04.08.2016, 21:24
|
|
Прописка
Регистрация: 29.03.2007
Сообщений: 185
Сказал спасибо: 11
Сказали Спасибо 1 раз в 1 сообщении
|
Внешние прерывания stm32f100ret6b
Помогите плз, уже мозги кипят. Надо зажигать светодиод PD2, когда на любой из пинов PB 11, 12, 13, 14 подают 1. Для проверки я подал на все 4 пина 1. Потом нажимаю кнопки, но прерывание не срабатывает. Отладчик показывает, что в регистре EXTI-›PR , биты 11, 12, 13, 14 - устанавливаются. Но судя по тому что диод не загорается, а биты в PR не сбрасываются, то просто не входит в вектор.
Код:
|
void EXTI3_IRQHandler(void)
{
GPIOD-›ODR ^= 0x4;
EXTI-›PR |= EXTI_PR_PR11;
}
void EXTI4_IRQHandler(void)
{
GPIOD-›ODR ^= 0x4;
EXTI-›PR |= EXTI_PR_PR11 | EXTI_PR_PR12 | EXTI_PR_PR13 | EXTI_PR_PR14;
}
int main(void){
RCC-›APB2ENR |= RCC_APB2ENR_IOPDEN; //PORT D CMD
GPIOD-›CRL &= ~GPIO_CRL_CNF2_0;
GPIOD-›CRL |= GPIO_CRL_MODE2_1;
RCC-›APB2ENR |= RCC_APB2ENR_IOPBEN | RCC_APB2ENR_AFIOEN;
GPIOB-›CRH &= ~(GPIO_CRH_CNF11_0 | GPIO_CRH_CNF12_0 | GPIO_CRH_CNF13_0 | GPIO_CRH_CNF14_0);//Scan Pins: PB11, PB12, PB13, PB14.
GPIOB-›CRH |= GPIO_CRH_CNF11_1 | GPIO_CRH_CNF12_1 | GPIO_CRH_CNF13_1 | GPIO_CRH_CNF14_1; //Input Push-down.
GPIOB-›CRL &= ~(GPIO_CRL_CNF5_0 | GPIO_CRL_CNF6_0 | GPIO_CRL_CNF7_0); //Generate Pins: PB5, PB6, PB7, PB8.
GPIOB-›CRH &= ~GPIO_CRH_CNF8_0;
GPIOB-›CRL |= GPIO_CRL_MODE5_1 | GPIO_CRL_MODE6_1 | GPIO_CRL_MODE7_1; //Output Push-pull.
GPIOB-›CRH |= GPIO_CRH_MODE8_1;
GPIOB-›BSRR |= 0x1E0;
//-------Setup EXTI-------------------------------
AFIO-›EXTICR[2] |= AFIO_EXTICR3_EXTI11_PB;
AFIO-›EXTICR[3] |= AFIO_EXTICR4_EXTI12_PB | AFIO_EXTICR4_EXTI13_PB | AFIO_EXTICR4_EXTI14_PB | AFIO_EXTICR4_EXTI15_PB;
EXTI-›RTSR |= EXTI_RTSR_TR11 | EXTI_RTSR_TR12 | EXTI_RTSR_TR13 | EXTI_RTSR_TR14;
EXTI-›IMR |= EXTI_IMR_MR11 | EXTI_IMR_MR12 | EXTI_IMR_MR13 | EXTI_IMR_MR14;
NVIC_EnableIRQ(EXTI3_IRQn);
NVIC_EnableIRQ(EXTI4_IRQn);
__enable_irq();
//------------------------------------------------
while(1){
__NOP();
}
} |
|
|
|
|
07.08.2016, 19:24
|
|
Почётный гражданин KAZUS.RU
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,508
Сказал спасибо: 401
Сказали Спасибо 2,218 раз(а) в 1,316 сообщении(ях)
|
Re: Внешние прерывания stm32f100ret6b
Ну вот, на этот раз уже лучше - вместо циферок понятные буковки.
А по поводу прерываний - давай внимательно посмотрим даташит.
Отдельные вектора прерываний доступны только для пяти первых линий от 0 до 4. А нужные в проге выведены в общий вектор EXTI15_10_IRQHandler. Соответственно, и разрешить вектор нужно именно этот - NVIC_EnableIRQ(EXTI15_10_IRQn).
Вот это то и надо записать. А чтобы определить, от какой линии прерывание настало, надо там в обработчике проверить биты EXTI_PR_PR(10...15)
Последний раз редактировалось NewWriter; 07.08.2016 в 19:43.
|
|
|
Сказали "Спасибо" NewWriter
|
|
|
08.08.2016, 13:23
|
|
Прописка
Регистрация: 29.03.2007
Сообщений: 185
Сказал спасибо: 11
Сказали Спасибо 1 раз в 1 сообщении
|
Re: Внешние прерывания stm32f100ret6b
Я уже понял это вчера. Сделал вот так:
Код:
|
void EXTI15_10_IRQHandler(void)
{
GPIOD-›ODR ^= 0x4;
EXTI-›PR |= EXTI_PR_PR11 | EXTI_PR_PR12 | EXTI_PR_PR13 | EXTI_PR_PR14;
}
int main(void){
//-------Setup clock 24 mHz from Ext Quartz 8 mHz------------------------------------------------
RCC-›CR &= ~RCC_CR_HSION; //HSI Disable (0 bit)
RCC-›CR |= RCC_CR_HSEON; //HSE Enable (16 bit)
while((RCC-›CR & RCC_CR_HSERDY) == 0){} //wait till HSE is ready
RCC-›CFGR = 0; //clear CFGR bits
RCC-›CFGR |= RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL_2; //PLL source = PREDIV1; HSE / 2 = 4 MHz; 4 * 6 = 24 MHz
//RCC-›CFGR &= ~RCC_CFGR_SW;
RCC-›CR |= RCC_CR_PLLON; //enable PLL (24 bit)
while((RCC-›CR & RCC_CR_PLLRDY) == 0) {} //wait till PLL is ready (25 bit)
RCC-›CFGR &= ~RCC_CFGR_SW; //clear SW bits (0 bit, 1 bit)
RCC-›CFGR |= RCC_CFGR_SW_1; //select PLL as system clock (1 bit)
while((RCC-›CFGR & RCC_CFGR_SWS) != 0x8) {} //wait till PLL is used (2, 3 bits)
//------------------------------------------------------------------------------------------------
RCC-›APB2ENR |= RCC_APB2ENR_IOPDEN; //PORT D CMD
GPIOD-›CRL &= ~GPIO_CRL_CNF2_0;
GPIOD-›CRL |= GPIO_CRL_MODE2_1;
RCC-›APB2ENR |= RCC_APB2ENR_IOPBEN | RCC_APB2ENR_AFIOEN; //CMD PORT B. cmd alt func
GPIOB-›CRH &= ~(GPIO_CRH_CNF11_0 | GPIO_CRH_CNF12_0 | GPIO_CRH_CNF13_0 | GPIO_CRH_CNF14_0); //Scan Pins: PB11, PB12, PB13, PB14.
GPIOB-›CRH |= GPIO_CRH_CNF11_1 | GPIO_CRH_CNF12_1 | GPIO_CRH_CNF13_1 | GPIO_CRH_CNF14_1; //Input Push-down.
GPIOB-›CRL &= ~(GPIO_CRL_CNF5_0 | GPIO_CRL_CNF6_0 | GPIO_CRL_CNF7_0); //Generate Pins: PB5, PB6, PB7, PB8.
GPIOB-›CRH &= ~GPIO_CRH_CNF8_0;
GPIOB-›CRL |= GPIO_CRL_MODE5_1 | GPIO_CRL_MODE6_1 | GPIO_CRL_MODE7_1; //Output Push-pull.
GPIOB-›CRH |= GPIO_CRH_MODE8_1;
GPIOB-›BSRR |= 0x1E0;
AFIO-›EXTICR[2] = AFIO_EXTICR3_EXTI11_PB;
AFIO-›EXTICR[3] = AFIO_EXTICR4_EXTI12_PB | AFIO_EXTICR4_EXTI13_PB | AFIO_EXTICR4_EXTI14_PB;
EXTI-›RTSR |= EXTI_RTSR_TR11 | EXTI_RTSR_TR12 | EXTI_RTSR_TR13 | EXTI_RTSR_TR14;
EXTI-›IMR |= EXTI_IMR_MR11 | EXTI_IMR_MR12 | EXTI_IMR_MR13 | EXTI_IMR_MR14;
NVIC_EnableIRQ(EXTI15_10_IRQn);
__enable_irq();
while(1){
__NOP();
}
} |
Я в обработчике не проверяю откуда конкретно влетело, что бы проверить вообще обработчик работает или нет. Так вот не поверишь, даже при таком раскладе не работает
|
|
|
|
08.08.2016, 17:55
|
|
Почётный гражданин KAZUS.RU
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,508
Сказал спасибо: 401
Сказали Спасибо 2,218 раз(а) в 1,316 сообщении(ях)
|
Re: Внешние прерывания stm32f100ret6b
Не работает? Да ну. Убери всё лишнее, оставь только одну-две линии и попробуй с них получить прерывание. Получится однозначно. Однако, из-за дребезга контактов прерывание может сработать несколько раз подряд за очень короткое время, поэтому лучше поставить брекпоинт в обработчике прерывания или выполнять в пошаговой отладке.
Вот такой код работает точно:
PHP код:
|
void EXTI15_10_IRQHandler(void)
{
if ((EXTI-›PR & EXTI_PR_PR11) !=0)
{
GPIOD-›BSRR = GPIO_Pin_2;
EXTI-›PR = EXTI_PR_PR11;
}
if ((EXTI-›PR & EXTI_PR_PR12) !=0)
{
GPIOD-›BRR = GPIO_Pin_2;
EXTI-›PR = EXTI_PR_PR12;
}
}
|
В майне настройка:
PHP код:
|
RCC-›APB2ENR |= RCC_APB2ENR_IOPDEN; //PORT D CMD
GPIOD-›CRL &= ~GPIO_CRL_CNF2_0;
GPIOD-›CRL |= GPIO_CRL_MODE2_1;
RCC-›APB2ENR |= RCC_APB2ENR_IOPBEN | RCC_APBENR_AFIOEN;
GPIOB-›CRH &= ~(GPIO_CRH_CNF11_0 | GPIO_CRH_CNF12_0);
GPIOB-›CRH |= GPIO_CRH_CNF11_1 | GPIO_CRH_CNF12_1;
// GPIOB-›BSRR = 0x1E0;
//-------Setup EXTI-------------------------------
AFIO-›EXTICR[2] = AFIO_EXTICR3_EXTI11_PB;
AFIO-›EXTICR[3] = AFIO_EXTICR4_EXTI12_PB;
EXTI-›RTSR |= EXTI_RTSR_TR11 | EXTI_RTSR_TR12;
EXTI-›IMR |= EXTI_IMR_MR11 | EXTI_IMR_MR12;
NVIC_EnableIRQ(EXTI15_10_IRQn);
|
Поскольку у прерывания EXTI15_10_IRQn номер 40, то в отладке в регистрах посмотреть все, что связано с номером 40. При наступлении прерывания установится 1 бита ACTIVE40 в регистре NVIC-›NVIC_IABR1.
И еще - а случаем не отладка ли в RAM без записи во флеш используется? Потому как при отладке в RAM нужно переместить таблицу векторов прерываний тоже в RAM, раскомментировав для этого строчку #define VECT_TAB_SRAM в файле system_stm32f10x.c. Без этого прерывания правильно работать не будут.
|
|
|
Сказали "Спасибо" NewWriter
|
|
|
08.08.2016, 20:42
|
|
Прописка
Регистрация: 29.03.2007
Сообщений: 185
Сказал спасибо: 11
Сказали Спасибо 1 раз в 1 сообщении
|
Re: Внешние прерывания stm32f100ret6b
И предложенный вами код тоже не работает. А проблема оказалось вот в чём. На другом форуме показали баг ARM, о котором все молчат. А именно, в обработчике первым делом надо сбрасывать PR, а потом всё остальное.
я поменял строки местами
Код:
|
void EXTI15_10_IRQHandler(void)
{
EXTI-›PR |= EXTI_PR_PR11 | EXTI_PR_PR12 | EXTI_PR_PR13 | EXTI_PR_PR14;
GPIOD-›ODR ^= 0x4;
} |
ии оно заработало!!!!!!!. А если назад поменять - опять не работает. Вот такая хрень, товарищи
|
|
|
|
08.08.2016, 21:21
|
|
Почётный гражданин KAZUS.RU
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,508
Сказал спасибо: 401
Сказали Спасибо 2,218 раз(а) в 1,316 сообщении(ях)
|
Re: Внешние прерывания stm32f100ret6b
Ну лично у меня работает, никаких багов, это бред. Пусть там не пи... трындят про баги, если не разбираются! Серьезно, черт возьми! Если не верите, могу да хоть даже видео выложить, что с приведенным мною кодом работает именно в той последовательности, как я написал.
Ну и... хм.. уже ж писалось про то, что пихать в майн блок с настройкой системной частоты Setup clock 24 mHz from Ext Quartz 8 mHz - да нахрен не нужно, если в папку проекта закинут файл с системной конфигурацией. А он опять с упорством в майн повторно пихает.. Че, тоже на каком-то форуме "посоветовали"? Да бред это, люди просто не разбираются.
чтобы убедиться, нужно просто поставить брекпоинт в system_stm32f10x.c напротив функции void SystemInit (void) и убедиться, что все эти действия, продублированные в майне, они и без того выполняются при старте.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 06:20.
|
|