Поиск сообщества
Показаны результаты для тегов 'Interrupt'.
Найдено: 3 результата
-
добрый день исходные: отлаживаю "библиотеку" на си - передача данных по 2м проводам (wiegand): - импульс D0 -> получили "0" - импульс D1 -> получили "1" будет использоваться неск. экземпляров RFID-датчиков, поэтому планирую сделать вообще без "механизмов блокировки". в прерывании только устанавливаются флаги, все остальное делается в основном цикле. в силу "обстоятельств" (унаследовано с прототипа) подключение пинов данных D0/D1 - на разных портах (по идее это не проблема, на ардуиновском "тестовом скетче" с таким-же расположением пинов - rfid-карта читается без проблем, но, походу, конечно протестирую еще и "все на одном порту") текущий код на си. читает карту, но с особенностями. к основному номеру карты (в старший разряд) добавляется еденица и последний (младший) разряд, соотв. обрезается. для отладки по шагам вместо "виганда" подключил две кнопки (c rc-цепочкой, сигналы нормальные, дребезг отсутствует, кнопок много, менялись/проверялись) выяснилось (в отладчике): - импульс на D0 - прерывание срабатывает 1 раз и далее все "печенькой" :о) - импульс на D1 - прерывание срабатывает 3 раза 1й раз - все по делу, "на падение сигнала", как и должно быть 2й раз - не по делу, "на подьем" (возвращение кнопки обратно), причем 2раза подряд и еще для "запуток" - при чтении (без отладчика, напрямую) только одна, самая первая, неправильная 1-ца добавляется в начало (в старший разряд) а далее серийник читается правильно. порты D0/D1 инициируются на вход, включается подтяжка, ни чего особенного.код, выкусы (упрощенка) кода: // // структура (выкус) // struct struct_Wiegand { TPinOut d0; // D0 пин TPinOut d1; // D1 пин uint8_t volatile data_flag[2]; // два флага на сработку D0/D1 ... }; typedef struct struct_Wiegand TWiegand; extern TWiegand* lst_rfid[RFID_NUM_DEV]; // список указателей на структуры // // в теле реализации // TWiegand w1={ {PIOA,19}, {PIOC,18}, {PIOA,20}, 0, {0,0}, 0, 0 }; TWiegand* lst_rfid[RFID_NUM_DEV] = { &w1 }; // // регистрация/добавление обработчиков прерываний // механизм/список такой-же как в ардуино // isr_enb_port (lst_rfid[0]->d0.pio, lst_rfid[0]->d0.pin, isr_rfid0_D0, FALLING); // D0 isr_enb_port (lst_rfid[0]->d1.pio, lst_rfid[0]->d1.pin, isr_rfid0_D1, FALLING); // D1 // // обработчики // void isr_rfid0_D0() { lst_rfid[0]->data_flag[0] ++; } void isr_rfid0_D1() { lst_rfid[0]->data_flag[1] ++; } других инициализаций прерываний нет (отрубал все что можно). если закомментировать строку вызова "добавления прерывания" для D1, то прерывание на D1 не срабатывает подобрал ссылки "околотемы" URL1 URL2 URL3 URL4 URL5 URL6 пока буду изучать ссылки, доки, даташит пинайте, кидайте помидоры, идеи, ссылки, все что угодно! можно просто побалагурить по теме! :о) спасибо.
-
Сделал два прерывания на кнопку и на таймер. Нажатие кнопки прекрасно обрабатывается. А вот с таймером проблемы. Решил потетстить свою настройку RCC, т.к. она не хочет работать корректно, ну или мне так кажется, но наткнулся еще на одну проблему. Код: void exti_init() { RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; SYSCFG->EXTICR[3] |= SYSCFG_EXTICR1_EXTI0_PA; EXTI->RTSR |= EXTI_RTSR_TR0; EXTI->PR = EXTI_PR_PR0; EXTI->IMR |= EXTI_IMR_MR0; NVIC_EnableIRQ( EXTI0_IRQn ); NVIC_SetPriority( EXTI0_IRQn, 14 ); // NVIC_EnableIRQ ( RCC_IRQn ); // NVIC_SetPriority( RCC_IRQn, 10 ); __enable_irq(); } void RCC_Init(void ) { SET_BIT( RCC->CR, RCC_CR_HSEON ); while ( READ_BIT( RCC->CR, RCC_CR_HSERDY == RESET ) ); FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_LATENCY_0WS; SET_BIT( RCC->PLLCFGR, RCC_PLLCFGR_PLLM_2 ); SET_BIT( RCC->PLLCFGR, RCC_PLLCFGR_PLLM_3 ); SET_BIT( RCC->PLLCFGR, RCC_PLLCFGR_PLLN_5 ); SET_BIT( RCC->PLLCFGR, RCC_PLLCFGR_PLLN_6 ); SET_BIT( RCC->PLLCFGR, ~RCC_PLLCFGR_PLLP_Pos ); SET_BIT( RCC->CFGR, RCC_CFGR_PPRE2_DIV1 ); SET_BIT( RCC->CFGR, RCC_CFGR_PPRE1_DIV2 ); SET_BIT( RCC->CFGR, RCC_CFGR_HPRE_DIV1 ); SET_BIT( RCC->CR, RCC_CR_PLLON ); while ( READ_BIT( RCC->CR, RCC_CR_PLLRDY == RESET ) ); SET_BIT( RCC->CFGR, RCC_CFGR_SW_PLL ); while ( READ_BIT( RCC->CR, RCC_CFGR_SWS_1 == RESET ) ); } GPIO_init(void ) { RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN; GPIOC->MODER |= GPIO_MODER_MODER13_0; GPIOA->MODER &= ~GPIO_MODER_MODER0_0; GPIOA->MODER &= ~GPIO_MODER_MODER0_1; SET_BIT( GPIOA->PUPDR, GPIO_PUPDR_PUPD0_0 ); } TIM2_init(void){ RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; TIM2->PSC = 8000-1; TIM2->ARR = 1000-1; TIM2->DIER |= TIM_DIER_UDE; TIM2->CR1 |= TIM_CR1_CEN; NVIC_EnableIRQ(TIM2_IRQn); NVIC_SetPriority(TIM2_IRQn, 13); } int main( void ) { // RCC_Init(); GPIO_init(); TIM2_init(); exti_init(); while ( 1 ) { } } void RCC_IRQHandler() { } void EXTI0_IRQHandler( void ) { if ( EXTI->PR & EXTI_PR_PR0 ) { EXTI->PR = EXTI_PR_PR0; GPIOC->ODR ^= GPIO_ODR_ODR_13; } } void TIM2_IRQHandler(void) { TIM2->SR = TIM_SR_UIF; GPIOC->ODR ^= GPIO_ODR_ODR_13; }
-
Здравствуйте. Захотел я посмотреть как на Arduino Uno (mega328P С кварцем на 16МГц) можно сделать простой генератор меандра, библиотечными digitalWrite() и delay() она начала привирать частоту гдето от 1-2кГц, решил написать на обычном Си. Взял таймер TIM1 с тактировкой от 16МГц с прерыванием по совпадению, и в прерывании обнулял счетчик и просто переключал ножку. interrupt [TIM1_COMPA] void timer1_compa_isr(void) { static unsigned char flag=0;//флаг лог. уровня пина TCNT1H=0x00;//обнуляем счетчик таймера TCNT1L=0x00; // Place your code here if (flag==0){ PORTB = 0x01;//лог 1 flag=1; } else { PORTB = 0x00;//лог 0 flag=0; } } Ожидал что работа с таймером и прерываниями отъест тактов 30-50, на отработку прерывания, заход и выход из него, один if и т.п. И будет у меня максимум килогерц 300 а дальше пойдет врать частоту. Но был удивлен тем что такая система начала привирать частоту уже на 10кГц, где давала 9.7кГц, а на 20кГц уже показывала 19кГц. (проверял точность осцилом). Вот и вопрос неужели таймер с прерыванием настолько медленные ? или я что-то делаю не так ? Полный код на Си если нужно прикреплен. boroda.c