16.10.2013, 21:46
|
|
Прописка
Регистрация: 31.08.2008
Сообщений: 117
Сказал спасибо: 4
Сказали Спасибо 3 раз(а) в 3 сообщении(ях)
|
Re: Измерение длительности импульса STM32
Сообщение от nahimovv
|
Менять полярность по входу, сбрасывать TMRxCNT нет смысла.
Посмотрите в даташите, там всё расписано. Ещё есть AN4013 "STM32F1xx, STM32F2xx, STM32F4xx, STM32L1xx, STM32F30/31/37/38x timer overview".
Нет, 41,6666666 нСек.
|
Снизойдите до меня укажите как это сделать в коде. По предварительному чтению счётчик таймера при положительном фронте импульса устанавливается в ноль.
|
|
|
|
17.10.2013, 11:58
|
|
Заблокирован
Регистрация: 25.04.2013
Сообщений: 1,431
Сказал спасибо: 0
Сказали Спасибо 385 раз(а) в 254 сообщении(ях)
|
Re: Измерение длительности импульса STM32
Если честно, непонятна постановка вопроса. Зачем сбрасывать счётчик? По переднему фронту и так происходит сброс счётчика, по заднему фронту состояние счётчика заносится в TIMx_CCR2, что и является длительностью импульса.
|
|
|
|
17.10.2013, 14:33
|
|
Прописка
Регистрация: 31.08.2008
Сообщений: 117
Сказал спасибо: 4
Сказали Спасибо 3 раз(а) в 3 сообщении(ях)
|
Re: Измерение длительности импульса STM32
Сообщение от nahimovv
|
Если честно, непонятна постановка вопроса. Зачем сбрасывать счётчик? По переднему фронту и так происходит сброс счётчика, по заднему фронту состояние счётчика заносится в TIMx_CCR2, что и является длительностью импульса.
|
Спасибо. Я уже это понял.
Но у меня получается, что
DutyCycle = TIM_GetCapture1(TIM3);
т. е. я считываю длительность из TIM3_CCR1?
В то время как
Frequency = SystemCoreClock /TIM_GetCapture2(TIM3);
Последний раз редактировалось anton_1000; 17.10.2013 в 14:55.
|
|
|
|
17.10.2013, 15:14
|
|
Заблокирован
Регистрация: 25.04.2013
Сообщений: 1,431
Сказал спасибо: 0
Сказали Спасибо 385 раз(а) в 254 сообщении(ях)
|
Re: Измерение длительности импульса STM32
В вашем случае - да.
Цитата:
|
/* TIM3 configuration: PWM Input mode ------------------------
The external signal is connected to TIM3 CH2 pin (PA.01),
The Rising edge is used as active edge,
The TIM3 CCR2 is used to compute the frequency value
The TIM3 CCR1 is used to compute the duty cycle value
------------------------------------------------------------ */
|
Если измерение частоты не нужно, то убрать разрешение прерывания по 2-му каналу, разрешить прерывание по 1-му, переписать прерывание под 1-ый канал.
Тогда по фронту импульса произойдёт сброс счётчика, а по спаду захват в 1-ый канал и прерывание. Т.е. если произошло прерывание, значит можно забирать данные длительности импульса из 1-го канала TIM3.
Последний раз редактировалось nahimovv; 17.10.2013 в 15:19.
|
|
|
Сказали "Спасибо" nahimovv
|
|
|
17.10.2013, 15:30
|
|
Прописка
Регистрация: 31.08.2008
Сообщений: 117
Сказал спасибо: 4
Сказали Спасибо 3 раз(а) в 3 сообщении(ях)
|
Re: Измерение длительности импульса STM32
Да действительно частота мне не нужна, а нужна только длительность
Разве у меня прерывание возникает два раза? А как настроить таймер на одно прерывание по захвату длительности импульса?
|
|
|
|
18.10.2013, 09:38
|
|
Прописка
Регистрация: 31.08.2008
Сообщений: 117
Сказал спасибо: 4
Сказали Спасибо 3 раз(а) в 3 сообщении(ях)
|
Re: Измерение длительности импульса STM32
Насколько я понимаю, прерывание возникает один раз
Код:
|
/* Enable the CC2 Interrupt Request */
TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE); |
|
|
|
|
18.10.2013, 09:56
|
|
Гуру портала
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 10,835
Сказал спасибо: 919
Сказали Спасибо 4,308 раз(а) в 2,573 сообщении(ях)
|
Re: Измерение длительности импульса STM32
Для приема и декодирования такого сигнала (смотри вложение) у меня код получился очень простой:
Код:
|
vu8 BitCounter = 0;
vu8 Buffer[0xFF];
u8 Data[20];
vu8 DataReadyFlag = 0;
const u8 TriggerValue = 20;
int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_AP B2Periph_GPIOC|RCC_APB2Periph_USART1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
PIN_OUT_PP(BLUE_LED);
PIN_OUT_PP(GREEN_LED);
PIN_IN(SYG);
delay_ms(100);
EXTI_Configuration();
NVIC_Configuration();
TIM2_Configuration();
UART_Configuration();
uart_print_string(USART1, "IR Receiver ready!", 1);
while (1)
{
while (DataReadyFlag==0);
PIN_ON(BLUE_LED);
ConvertData();
PrintResultBits(0);
PrintResult(0);
DataReadyFlag = 0;
BitCounter = 0;
PIN_OFF(BLUE_LED);
}
} |
Далее инитиализация переферии:
Код:
|
void NVIC_Configuration (void)
{
NVIC_EnableIRQ(EXTI1_IRQn);
NVIC_EnableIRQ(TIM2_IRQn);
}
void TIM2_Configuration (void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_TimeBaseInitStruct.TIM_Prescaler = 1000;
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStruct.TIM_Period = 0xFF;
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM2, DISABLE);
TIM_SetCounter(TIM2, 0);
}
void UART_Configuration (void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1,ENABLE);
/*
* USART1_TX -› PA9 , USART1_RX -› PA10
*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_Cmd(USART1, ENABLE);
} |
Далее обработчик прерывания по перепаду уровня на входе:
Код:
|
void EXTI1_IRQHandler (void)
{
PIN_INV(BLUE_LED);
PIN_OFF(GREEN_LED);
if (PIN_SYG(SYG)!=0)
{
TIM_SetCounter(TIM2, 0);
TIM_Cmd(TIM2, ENABLE);
}
else
{
TIM_Cmd(TIM2, DISABLE);
Buffer[BitCounter++] = TIM_GetCounter(TIM2);
}
EXTI_ClearITPendingBit(EXTI_Line1);
} |
И обработчик переполнения таймера для определения конца посылки:
Код:
|
void TIM2_IRQHandler (void)
{
PIN_ON(GREEN_LED);
TIM_Cmd(TIM2, DISABLE);
TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update);
if (BitCounter) DataReadyFlag = 1;
} |
Дальше конвертируем биты в байты по пороговому значению:
Код:
|
void ConvertData (void)
{
u8 cnt, bitcnt = 7, bytecnt = 0;
for (cnt=0;cnt!=sizeof(Data);cnt++) Data[cnt] = 0;
for (cnt=2;cnt!=BitCounter;cnt++)
{
if (Buffer[cnt]›TriggerValue)
{
Buffer[cnt]=1;
Data[bytecnt]|=(1‹‹bitcnt);
}
else Buffer[cnt]=0;
bitcnt--;
if (bitcnt==0)
{
bitcnt=7;
bytecnt++;
}
}
} |
И выводим результат:
Код:
|
void PrintResult (u8 MoreInfo)
{
u8 cnt = 0;
u8 bytecnt = BitCounter/8;
if (MoreInfo)
{
uart_print_string(USART1, "Received ", 0);
uart_print_value(USART1, bytecnt);
uart_print_string(USART1, " bytes.", 1);
}
while (bytecnt--)
{
uart_print_hex_value(USART1, Data[cnt++]);
uart_print_string(USART1, " ", 0);
}
uart_print_string(USART1, " ", 1);
if (MoreInfo) uart_print_string(USART1, "Done!", 1);
} |
Получается, что длительность 9-10 тактов таймера соответствует нулю, а 29-31 единичке.
|
|
|
|
18.10.2013, 10:03
|
|
Прописка
Регистрация: 31.08.2008
Сообщений: 117
Сказал спасибо: 4
Сказали Спасибо 3 раз(а) в 3 сообщении(ях)
|
Re: Измерение длительности импульса STM32
Спасибо за альтернативный вариант. Я пытаюсь измерить длительность импульса от ульразвукового датчика расстояния. Какой вариант предпочтительней или они равноценны?
|
|
|
|
18.10.2013, 10:07
|
|
Гуру портала
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 10,835
Сказал спасибо: 919
Сказали Спасибо 4,308 раз(а) в 2,573 сообщении(ях)
|
Re: Измерение длительности импульса STM32
anton_1000, на сколько я помню свои эксперименты с этим датчиком, разницы не будет. Таймер считает таковые импульсы процессора, пока эхо не вернется. Количество импульсов пропорционально расстоянию. Значит, метод будет работать и тут. По перепаду измерять значение таймера, по срабатыванию таймера запускать новое измерение или сообщать, что сигнал ушел в "никуда".
|
|
|
|
21.10.2013, 22:42
|
|
Прописка
Регистрация: 31.08.2008
Сообщений: 117
Сказал спасибо: 4
Сказали Спасибо 3 раз(а) в 3 сообщении(ях)
|
Re: Измерение длительности импульса STM32
Помогите, пожайлуста, настроить DMA для чтения значения TIM2_CCR2? т.е. значение длительности импульса.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 09:03.
|
|