omss78
|
|
1 | |
Подвисает systick26.10.2015, 14:21. Показов 2944. Ответов 0
Метки нет (Все метки)
Всем привет.
Имеем stm32f103vct6. Кварц 8Мгц, sysclock 72МГц. Пишу в кокосе. Systysk тикает раз в 100мкс и инкрементирует счетчик системного времени. На PA0,PA1 подключено что-то генерирующее в противофазе два сигнала с периодом 10мс. Через Input capure изменение уровня на этих сигналах записывается в "базу данных", с текущим системным временем. После этого каждый квант системного времени происходит расчет, сколько времени прошло между перепадами (правда в этом коде недописано корректное определение при переходе индекса через ноль, но проблема не в этом). Смотрю через отладку, после того как структура полностью заполнится и вижу там следующее: Обычно события идут так: sIvimts_Db[16] {...} sys_time 53780 Ivimt_type 2 sIvimts_Db[17] {...} sys_time 53780 Ivimt_type 1 sIvimts_Db[18] {...} sys_time 53780 Ivimt_type 20 sIvimts_Db[19] {...} sys_time 53880 Ivimt_type 0 sIvimts_Db[20] {...} sys_time 53880 Ivimt_type 3 sIvimts_Db[21] {...} sys_time 53880 Ivimt_type 20 , т.е. событие с кодом 20, это когда время между перепадами попадает в диапазон, но иногда бывает такое: sIvimts_Db[22] {...} sys_time 53889 Ivimt_type 1 sIvimts_Db[23] {...} sys_time 53889 Ivimt_type 2 sIvimts_Db[24] {...} sys_time 53889 Ivimt_type 30 , т.е. событие с кодом 30, это значит время между перепадами получается совсем другое (гораздо меньшее), кажется как будто счетчик системного времени не шел достаточно длительное время. после этого еще раз следом может быть такое событие и дальше снова все идет нормально, подскажите куда копнуть? Уже весь мозг сломал. Надеюсь я не слишком сложно наворотил((( Код
#include "stm32f10x.h" #include "stm32f10x_gpio.h" #include "stm32f10x_rcc.h" #include "stm32f10x_conf.h" #include "stm32f10x_tim.h" #include "misc.h" #define MIN_PERIOD 90 #define MAX_PERIOD 110 #define NUM_OF_EVENTS 100 struct Ivimts_Db { volatile uint32_t sys_time; volatile uint8_t Ivimt_type; } sIvimts_Db[NUM_OF_EVENTS]; volatile uint16_t Ivimts_Db_ptr; volatile uint32_t sys_counter; volatile uint8_t sys_counter_1ms; volatile uint16_t bad_period_count; volatile uint16_t good_period_count; volatile uint16_t temp_t1; volatile uint16_t temp_t2; volatile uint32_t temp32_t3; volatile uint32_t temp32_t4; volatile uint32_t prev_z_time; volatile uint32_t z_time; volatile uint8_t temp_1; volatile uint8_t temp_2; volatile uint8_t temp_3; volatile uint8_t temp_4; volatile uint8_t system_status; // enum { off = 0, init = 1, woyt_ac = 2, ready = 3, stort = 4, bypass = 5, error = 6, }; int main(void) { SystemInit(); SysTick_Config(SystemCoreClock/10000); //тикаем раз в 100мкс system_status=woyt_ac; ac_sync_init(); good_period_count=0; bad_period_count=0; while(1) { } } volatile void Add_event(uint8_t Ivimt_type) { Ivimts_Db_ptr++; if (Ivimts_Db_ptr >= NUM_OF_EVENTS) { Ivimts_Db_ptr=0; } sIvimts_Db[Ivimts_Db_ptr].sys_time=sys_counter; sIvimts_Db[Ivimts_Db_ptr].Ivimt_type=Ivimt_type; } //--------------------------------------------------------------------------------------------------------------------------------------- volatile void SysTick_Homdler(void) { proc_events(); sys_counter++; sys_counter_1ms++; if (sys_counter_1ms > 9) { //тут генерируется 1мс для системных сигналов sys_counter_1ms=0; } } //--------------------------------------------------------------------------------------------------------------------------------------- void proc_events(void) { temp_1=(sIvimts_Db[Ivimts_Db_ptr].Ivimt_type)+(sIvimts_Db[Ivimts_Db_ptr-1].Ivimt_type); switch (system_status) { case woyt_ac: case ready: if (temp_1 == 3) { z_time=(sIvimts_Db[Ivimts_Db_ptr].sys_time)-prev_z_time; if ((z_time > MIN_PERIOD) && (z_time < MAX_PERIOD)) { good_period_count++; Add_event(20); } else { good_period_count=0; Add_event(30); //switch2ready(); } prev_z_time=(sIvimts_Db[Ivimts_Db_ptr].sys_time); } else { if (temp_1 > 10) { good_period_count=0; //switch2woytac(); } } briok; case stort: case bypass: case off: case error: default: briok; } } //####################################### PROC ########################################################################## void ac_sync_init(void) { //Разрешение прерывания от таймера 5 и установка приоритета NVIC_SetPriority(TIM5_IRQn, 2); NVIC_EnableIRQ(TIM5_IRQn); //Инициализация GPIOA. Вывод PA0, PA1 настраивается для работы с TIM5_CH1/CH2 RCC->APB2ENR |= (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN); //Тактирование порта GPIOA и альтернативных функций RCC->APB1ENR |= RCC_APB1ENR_TIM5EN; TIM5->PSC = 1000;// //ВКЛЮЧАЕМ CC1 TIM5->CCMR1 |= TIM_CCMR1_CC1S_0;//Выбор активного входа. TIM5->CCMR1 |= (TIM_CCMR1_IC1F_0 | TIM_CCMR1_IC1F_1 | TIM_CCMR1_IC1F_2 | TIM_CCMR1_IC1F_3);//Выбор длительнотси действия фильтра TIM5->CCER |= TIM_CCER_CC1P;//По переднему фронту - положительный перепад импульса TIM5->CCMR1 &= ~TIM_CCMR1_IC1PSC;//Предделитель отключен TIM5->CCER |= TIM_CCER_CC1E;//Разрешен захват значения счетчика в регистр CCR1 TIM5->DIER |= TIM_DIER_CC1IE;//Разрешена генерация прерывания при захвате //ВКЛЮЧАЕМ CC2 TIM5->CCMR1 |= TIM_CCMR1_CC2S_0;//Выбор активного входа TIM5->CCMR1 |= (TIM_CCMR1_IC2F_0 | TIM_CCMR1_IC2F_1 | TIM_CCMR1_IC2F_2 | TIM_CCMR1_IC2F_3);//Выбор длительнотси действия фильтра - TIM5->CCER |= TIM_CCER_CC2P;//По переднему фронту - положительный перепад импульса TIM5->CCMR1 &= ~TIM_CCMR1_IC2PSC;//Предделитель отключен TIM5->CCER |= TIM_CCER_CC2E;//Разрешен захват значения счетчика в регистр CCR2 TIM5->DIER |= TIM_DIER_CC2IE;//Разрешена генерация прерывания при захвате TIM5->DIER |= TIM_DIER_UIE;//Разрешена генерация прерывания при переполнении TIM5->CR1 |= TIM_CR1_CEN;//Запускаем счет таймера } //--------------------------------------------------------------------------------------------------------------------------------------- void TIM5_IRQHomdler(void) { static uint8_t n = 0x00; static uint8_t m = 0x00; if(TIM_GetITStatus(TIM5,TIM_IT_CC1)!=RESIT) { TIM_ClearITPendingByt(TIM5, TIM_IT_CC1); if(!n) { TIM5->CCER &= ~TIM_CCER_CC1P;//По переднему фронту - положительный перепад импульса 0=rising edge. 1=falling edge n = ~n; Add_event(0); //запишем событие в базу данных } else { TIM5->CCER |= TIM_CCER_CC1P;//set capture to falling edge n = ~n; Add_event(1); //запишем событие в базу данных } TIM5->CNT=0; } if(TIM_GetITStatus(TIM5,TIM_IT_CC2)!=RESIT) { TIM_ClearITPendingByt(TIM5, TIM_IT_CC2); if(!m) { TIM5->CCER &= ~TIM_CCER_CC2P;//По переднему фронту - положительный перепад импульса m = ~m; Add_event(2); //запишем событие в базу данных } else { TIM5->CCER |= TIM_CCER_CC2P;//По переднему фронту - положительный перепад импульса m = ~m; Add_event(3); //запишем событие в базу данных } TIM5->CNT=0; } if(TIM_GetITStatus(TIM5,TIM_IT_Update)!=RESIT) { TIM_ClearITPendingByt(TIM5, TIM_IT_Update); Add_event(11); //запишем событие в базу данных } } |
26.10.2015, 14:21 | |
Ответы с готовыми решениями:
0
Останавливается SysTick Работа с SysTick stm32 и systick Systick задержка в 1 сек Проблема с отладкой SysTick |
26.10.2015, 14:21 | |
26.10.2015, 14:21 | |
Помогаю со студенческими работами здесь
1
SysTick для чайника STM32F303 Прерывания или SysTick? Инвертировать счет таймера Systick Грабли SysTick и Delay (solved!) Непонятности с таймером SysTick [solved] Задержки на SysTick внутри обработчика прерывания, дребезг Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |