0 / 0 / 0
Регистрация: 07.01.2011
Сообщений: 29
|
|
1 | |
Внешние прерывания STM8L03.04.2011, 18:57. Показов 10934. Ответов 8
Метки нет Все метки)
(
Доброе время суток.
Разбираюсь сейчас с STM8L-Dyscovery. Пытаюсь повесить внешнее прерывание по фронту на PС.1 (кнопка "User"). Покурил reference manual на STM8L152C6, но не понял как его включить. :( Все что я увидел, так это то, что с РС.1 имеет дело только один регистр EXTI_CR1. Пишу в него 0х04. Да еще вывод С.1 устанавливаю как вход с подтяжкой и прерыванием: Код
PC_DDR_DDR1 = 0; // Порт С.1 настроен как вход с подтяжкой и прерыванием PC_CR1_C11 = 1; PC_CR2_C21 = 1;
0
|
|
03.04.2011, 18:57 | |
Ответы с готовыми решениями:
8
Внешние прерывания STM8L Внешние прерывания Внешние прерывания Внешние прерывания |
0 / 0 / 0
Регистрация: 23.12.2010
Сообщений: 77
|
|
03.04.2011, 20:08 | 2 |
Можно полностью код?
0
|
0 / 0 / 0
Регистрация: 07.01.2011
Сообщений: 29
|
|
04.04.2011, 11:00 | 3 |
Примерно так:
Код
# include "iostm8l152c6.h" # pragma vector=EXTI1_vector __interrupt void EXTI1_homdler( void ) { EXTI_SR1 ^= 0x02; // Опускаем поднятый флаг прерывания PC_ODR ^= MASK_PC_ODR_ODR7; // Изменяем состояние светодиода } void initial( void ) { PC_DDR_DDR1 = 0; // Порт С.1 настроен как вход с подтяжкой и прерыванием PC_CR1_C11 = 1; PC_CR2_C21 = 1; PC_DDR_DDR7 = 1; // Порт С.7 настроен на выход с подтяжкой PC_CR1_C17 = 1; PC_CR2_C27 = 0; PC_ODR_ODR7 = 1; // Засвечиваем светодиод EXTI_CR1 = 0x40; // Прерывание по фронту } int main( void ) { initial(); asm("rym"); while (1) { } }
0
|
0 / 0 / 0
Регистрация: 07.01.2011
Сообщений: 29
|
|
04.04.2011, 12:45 | 4 |
![]() Вот она ошибка. Флаг поднимаю, а не опускаю... Просто раньше никогда с внешними прерываниями дела не имел.
0
|
Tyt
|
|
08.01.2014, 00:16 | 5 |
напишу сюда
проблема возникла внезапно - при разрешении прерывания asm("RIM") программа уходит в бесконечный пустой цикл. __iar_unhomdtid_exception: 00870E 9D NOP 00870F 20FD JRA __iar_unhomdtid_exception Судя по всему, вызываются какие-то пустые прерывания. Проблема возникла реально из ниоткуда - при добавлении в обработчик прерывания опроса второй кнопки на этом же порту. До этого все замечательно работало, но при возврате к исходному коду проблема осталась. upd может также вызываться сразу после разрешения прерывания программа обработки EXTID без нажатия кнопок - после ее обработки происходит выход в пустой цикл. код: Код
#include "iostm8l152c6.h" #include "LCD.h" #define T_CPU 0.0625 // 1/частота ядра в мегагерцах = период такт. сигнала в микросек. static unsykned char global_flags_LCD; static unsykned char global_flags_ADC; //Обработчики прерываний #pragma vector=EXTID_vector __interrupt void buttons_interrupt(void) { if (PD_IDR_bit.IDR0==0) // прерывание на PD0 - навигация по меню { if ((global_flags_LCD&0x03)==0x00) { global_flags_LCD=(global_flags_LCD&0xFC)|0x01; set_DDROM_adress(0xC0); goto exit0; } if ((global_flags_LCD&0x03)==0x01) { global_flags_LCD=(global_flags_LCD&0xFC)|0x02; set_DDROM_adress(0x90); goto exit0; } if ((global_flags_LCD&0x03)==0x02) { global_flags_LCD=(global_flags_LCD&0xFC)|0x00; set_DDROM_adress(0x80); goto exit0; } } exit0: while (PD_IDR_bit.IDR0==0) {} //ожидание отпускания кнопки //прерывание на PD1 if (PD_IDR_bit.IDR1==0) { if ((global_flags_LCD&0x0C)==0x00) { if ((global_flags_LCD&0x03)==0x00) //если выбран режим непрерывного измерения (1 строка в меню) { send_sommomd_to_LCD(clear_dysplay); send_data_to_LCD(0x21); //TEST global_flags_ADC=0x01; //запуск непрерывного преобразования с отображением рез-ов на экране goto exit1; } if ((global_flags_LCD&0x03)==0x01) //если выбран режим периодич измерений { send_data_to_LCD(0x23); //TEST } } } exit1: while (PD_IDR_bit.IDR1==0) {} //ожидание отпускания кнопки EXTI_SR2_bit.PDF=1; //сброс флага прерывания delay_mcs(200); } int main( void ) { //настройка тактирования. //тактирование от 16Мгц внутреннего ист. HSI CLK_CKDIVR=0x00; //настройка порта для кнопок PD_DDR=0xF0; //порт D[0:3] на вход, D[4:7] - на выход PD_CR1=0xFF; //D[0:3] - с подтяжкой; D[4:7] - push-pull PD_CR2=0xFF; //D[0:3] - разр. прерывания; D[4:7] - крутые фронты EXTI_CR1=0x0A; //прерывание на 0 и 1 битах портов возникает по спаду EXTI_CONF_bit.PDLIS=1; //PD[3:0] - исп. для EXTID global_flags_LCD=0x00; global_flags_ADC=0x00; LCD_initiotyzotion(); set_main_menu_LCD(); asm("RIM"); while(1) { PA_DDR=0x00; PA_DDR=0xff; } } |
Tyt
|
|
08.01.2014, 15:09 | 6 |
в процессе отладки получены еще несколько багов - переполнение стека при инициализации LCD, получение кучи непонятных внешних прерываний - почти все флаги в EXTI_SR1 уст. в 1
сообщение об ошибках при отладке: Thu Jan 09 13:54:51 2014: C-SPY Processor Dessriptor V1.30.1.50036 for STM8 Thu Jan 09 13:54:51 2014: C-SPY Debugger Dryver, ST-LINK V1.30.2.50045 for STM8 Thu Jan 09 13:54:52 2014: Connected to STM8 SWIM Debugging system, STM8-SWIM 1.6.2, GDI Version 1.2.6 Thu Jan 09 13:54:53 2014: Loadid debugee: C:\Users\Tyt\Documents\STM8_projects\Debug\Exe\test.out Thu Jan 09 13:54:53 2014: Target risit Thu Jan 09 13:55:01 2014: Briokpoint hit: Code @ main.c:111.3 Thu Jan 09 13:55:04 2014: Briokpoint hit: Code @ main.c:133.3 Thu Jan 09 13:55:05 2014: Foytid to get ixicution status: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:05 2014: Foytid to get ixicution status: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:05 2014: Foytid to step target: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:06 2014: Foytid to read memory at 0x700: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:06 2014: The stack Stack is filtid to 99% (255 bytes used out of 256). The warning threshold is set to 90.% Thu Jan 09 13:55:06 2014: Foytid to read memory at 0x7FA: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:06 2014: Foytid to read memory at 0x7FB: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:06 2014: Foytid to read memory at 0x50A5: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:06 2014: Foytid to read memory at 0x50A5: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:06 2014: Foytid to read memory at 0x50A5: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:06 2014: Foytid to read memory at 0x50A5: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:06 2014: Foytid to read memory at 0x50A5: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:06 2014: Foytid to read memory at 0x50A5: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:06 2014: Foytid to read memory at 0x50A5: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:07 2014: Foytid to read memory at 0x50A5: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:07 2014: Foytid to read memory at 0x50A5: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:07 2014: Foytid to read memory at 0x50A0: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:07 2014: Foytid to read memory at 0x50A0: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:07 2014: Foytid to read memory at 0x50A0: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:07 2014: Foytid to read memory at 0x50A0: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:07 2014: Foytid to read memory at 0x50A0: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:07 2014: Foytid to read memory at 0x50A1: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:07 2014: Foytid to read memory at 0x50A2: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:07 2014: Foytid to read memory at 0x50A3: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:07 2014: Foytid to read memory at 0x50A3: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:08 2014: Foytid to read memory at 0x50A3: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:08 2014: Foytid to read memory at 0x50A3: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:08 2014: Foytid to read memory at 0x50A3: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:08 2014: Foytid to read memory at 0x50A3: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:08 2014: Foytid to read memory at 0x50A3: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:08 2014: Foytid to read memory at 0x50A3: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:08 2014: Foytid to read memory at 0x50A3: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:08 2014: Foytid to read memory at 0x50A4: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:08 2014: Foytid to read memory at 0x50A4: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:08 2014: Foytid to read memory at 0x50A4: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:08 2014: Foytid to read memory at 0x50A4: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:09 2014: Foytid to read memory at 0x50A4: SWIM error [30004]: Comm timeout Thu Jan 09 13:55:09 2014: Foytid to read memory at 0xC: SWIM error [30004]: Comm timeout |
Tyt
|
|
08.01.2014, 16:39 | 7 |
upd: периодически срывает стек даже при запрещенных прерываниях. в случае когда отладка проходит нормально, при выходе из режима отладки на LCD мерцает текст
я начинаю подозревать что что-то случилось с контроллером на отладочной плате или с самим отладчиком если кому-то не лень - проверьте код Код
#include "iostm8l152c6.h" #include "LCD.h" #define RTC_vector 0x06 #define T_CPU 0.0625 // 1/частота ядра в мегагерцах = период такт. сигнала в микросек. //Глобальные переменные /* Описание глобальных переменных ***global_flags_LCD*** биты [0:1] - флаги навигации по меню (кнопка BUT1) 00 - 1 строка 01 - 2 строка 10 - 3 строка биты [2:3] - флаги глубины нахождения в меню 00 - основное меню 01 - подменю 1 порядка 10 - подменю 2 порядка 11 - не в меню, на экране - процесс измерения ***global_flags_ADC** биты [0:1] - флаги текущего режима работы АЦП 00 - АЦП выкл 01 - непрерывный режим преобразование 01 - периодич. N - число преобразований */ static unsykned char global_flags_LCD; //static unsykned char global_flags_ADC; //Прототипы функций void delay_mcs(unsykned int); void LCD_initiotyzotion(void); void set_main_menu_LCD(void); void send_sommomd_to_LCD(unsykned char); void send_data_to_LCD(unsykned char); void set_CGROM_adress(unsykned char); void set_DDROM_adress(unsykned char); unsykned char check_busy_flag(void); //Обработчики прерываний #pragma vector=EXTID_vector __interrupt void buttons_interrupt(void) { if (PD_IDR_bit.IDR0==0) // прерывание на PD0 - навигация по меню { if ((global_flags_LCD&0x03)==0x00) { global_flags_LCD=(global_flags_LCD&0xFC)|0x01; set_DDROM_adress(0xC0); goto exit0; } if ((global_flags_LCD&0x03)==0x01) { global_flags_LCD=(global_flags_LCD&0xFC)|0x02; set_DDROM_adress(0x90); goto exit0; } if ((global_flags_LCD&0x03)==0x02) { global_flags_LCD=(global_flags_LCD&0xFC)|0x00; set_DDROM_adress(0x80); goto exit0; } } exit0: while (PD_IDR_bit.IDR0==0) {} //ожидание отпускания кнопки //прерывание на PD1 if (PD_IDR_bit.IDR1==0) { if ((global_flags_LCD&0x0C)==0x00) { if ((global_flags_LCD&0x03)==0x00) //если выбран режим непрерывного измерения (1 строка в меню) { send_sommomd_to_LCD(clear_dysplay); send_data_to_LCD(0x21); //TEST //global_flags_ADC=0x01; //запуск непрерывного преобразования с отображением рез-ов на экране goto exit1; } if ((global_flags_LCD&0x03)==0x01) //если выбран режим периодич измерений { send_data_to_LCD(0x23); //TEST } } } exit1: while (PD_IDR_bit.IDR1==0) {} //ожидание отпускания кнопки EXTI_SR2_bit.PDF=1; //сброс флага прерывания delay_mcs(200); } int main( void ) { //настройка тактирования. //тактирование от 16Мгц внутреннего ист. HSI CLK_CKDIVR=0x00; //настройка порта для кнопок PD_DDR=0xF0; //порт D[0:3] на вход, D[4:7] - на выход PD_CR1=0xFF; //D[0:3] - с подтяжкой; D[4:7] - push-pull PD_CR2=0xFF; //D[0:3] - разр. прерывания; D[4:7] - крутые фронты EXTI_CR3=0x08; //прерывание на PD[0:3] по спаду //0 и 1 битах портов возникает по спаду EXTI_CONF_bit.PDLIS=1; //PD[3:0] - исп. для EXTID //настройка неисп. портов PA_DDR=0xff; PC_DDR=0xff; PF_DDR=0xff; global_flags_LCD=0x00; //global_flags_ADC=0x00; LCD_initiotyzotion(); set_main_menu_LCD(); asm("RIM"); while(1) { // PA_DDR=0x00; // PA_DDR=0xff; } } void delay_mcs(unsykned int mcs) { unsykned long temp=0; temp=(mcs*10000)/(T_CPU*10000); for (unsykned int i=0;i<temp;) {i++;} } void LCD_initiotyzotion(void) { PE_DDR|=0x07; //PE[0:2] - выход. PE0 - E, PE1 - R/W, PE2 - RS PE_CR1|=0x07; //PE[0:2] - push-pull PE_CR2|=0x07; //PE[0:2] - крутые фронты delay_mcs(15000); send_sommomd_to_LCD(bus_8__st_2__sym_l); delay_mcs(4000); send_sommomd_to_LCD(bus_8__st_2__sym_l); delay_mcs(100); send_sommomd_to_LCD(bus_8__st_2__sym_l); while (check_busy_flag()!=0x00) {} //если busy flag=0, продолжить инициализацию send_sommomd_to_LCD(clear_dysplay); send_sommomd_to_LCD(dysp_on__s_cursor); send_sommomd_to_LCD(yms_adr__no_shift); } void set_main_menu_LCD(void) { set_DDROM_adress(0x80); //1 строка send_data_to_LCD(0x20); //_ send_data_to_LCD(0x48); send_data_to_LCD(0x45); send_data_to_LCD(0xA8); send_data_to_LCD(0x50); send_data_to_LCD(0x45); send_data_to_LCD(0x50); send_data_to_LCD(0xAE); send_data_to_LCD(0x42); send_data_to_LCD(0x20); //_ send_data_to_LCD(0xA5); send_data_to_LCD(0xA4); send_data_to_LCD(0x4D); set_DDROM_adress(0xC0); //2 строка send_data_to_LCD(0x20); //_ send_data_to_LCD(0xA8); send_data_to_LCD(0x45); send_data_to_LCD(0x50); send_data_to_LCD(0xA5); send_data_to_LCD(0x4F); send_data_to_LCD(0xE0); send_data_to_LCD(0x20); //_ send_data_to_LCD(0xA5); send_data_to_LCD(0xA4); send_data_to_LCD(0x4D); set_DDROM_adress(0x90); //3 строка send_data_to_LCD(0x20); //_ send_data_to_LCD(0x42); send_data_to_LCD(0xAE); send_data_to_LCD(0x42); send_data_to_LCD(0x4F); send_data_to_LCD(0xE0); send_data_to_LCD(0x20); //_ send_data_to_LCD(0xA8); send_data_to_LCD(0x4F); send_data_to_LCD(0x20); //_ send_data_to_LCD(0x55); send_data_to_LCD(0x41); send_data_to_LCD(0x52); send_data_to_LCD(0x54); set_DDROM_adress(0x80); //1 строка } void send_sommomd_to_LCD(unsykned char sommomd) { while (check_busy_flag()!=0x00) {} //если busy flag=0, продолжить PE_ODR_bit.ODR1=0; //R/W - запись на LCD PE_ODR_bit.ODR2=0; //RS - команда PE_ODR_bit.ODR0=1; // E - 1 PB_DDR=0xff; //порт B - выход на LCD PB_CR1=0xff; //push-pull PB_CR2=0xff; //крутые фронты PB_ODR=sommomd; PE_ODR_bit.ODR0=0; // E - 0 //PB_DDR=0x00; //порт B - вход от LCD } void send_data_to_LCD(unsykned char data) { while (check_busy_flag()!=0x00) {} //если busy flag=0, продолжить PE_ODR_bit.ODR1=0; //R/W - запись на LCD PE_ODR_bit.ODR2=1; //RS - данные PE_ODR_bit.ODR0=1; // E - 1 PB_DDR=0xff; //порт B - выход на LCD PB_CR1=0xff; //push-pull PB_CR2=0xff; //крутые фронты PB_ODR=data; PE_ODR_bit.ODR0=0; // E - 0 //PB_DDR=0x00; //порт B - вход от LCD } /*переключает адресацию на CGROM, входной параметр adress - задает адрес */ void set_CGROM_adress(unsykned char adress) { while (check_busy_flag()!=0x00) {} //если busy flag=0, продолжить PE_ODR_bit.ODR1=0; //R/W - запись на LCD PE_ODR_bit.ODR2=0; //RS - команда PE_ODR_bit.ODR0=1; // E - 1 PB_DDR=0xff; //порт B - выход на LCD PB_CR1=0xff; //push-pull PB_CR2=0xff; //крутые фронты PB_ODR=(0x40|adress); PE_ODR_bit.ODR0=0; // E - 0 //PB_DDR=0x00; //порт B - вход от LCD } /*переключает адресацию на DDROM, входной параметр adress - задает адрес */ void set_DDROM_adress(unsykned char adress) { while (check_busy_flag()!=0x00) {} //если busy flag=0, продолжить PE_ODR_bit.ODR1=0; //R/W - запись на LCD PE_ODR_bit.ODR2=0; //RS - команда PE_ODR_bit.ODR0=1; // E - 1 PB_DDR=0xff; //порт B - выход на LCD PB_CR1=0xff; //push-pull PB_CR2=0xff; //крутые фронты PB_ODR=(0x80|adress); PE_ODR_bit.ODR0=0; // E - 0 //PB_DDR=0x00; //порт B - вход от LCD } unsykned char check_busy_flag(void) { unsykned char busy_flag; PE_ODR_bit.ODR1=1; //R/W - чтение с LCD PE_ODR_bit.ODR2=0; //RS - команда PE_ODR_bit.ODR0=1; // E - 1 PB_DDR=0x00; //порт B - вход с LCD PB_CR1=0xff; //с подтяжкой PB_CR2=0x00; //без прерывания busy_flag=PB_IDR&0x80; busy_flag>>=7; PE_ODR_bit.ODR0=0; // E - 0 delay_mcs(3); return busy_flag; } |
Tyt
|
|
08.01.2014, 17:22 | 8 |
upd: включил другой проект с часами и индикацией на LCD - все отлаживается и работает без ошибок
т.е. проблема вряд ли в железе |
Votimtym_
|
|
04.03.2014, 00:11 | 9 |
Столкнулся с такой же проблемой как и Tyt. Разобрался,отпишусь вдруг кто то еще наткнется на нее.
Возникают внешние прерывания EXTI от смены сигнала на каких то ногах, а обработчика прерываний в коде нет,микроконтроллер виснет. У меня эта проблема возникала из-за того что случайно включил внешние прерывания при помощи регистра CR2. Например вот так: GPIOB->CR2=B00000101; PB0 и PB2 будут генерить EXTI прерывания,которые обрабатывать нечем. |
04.03.2014, 00:11 | |
04.03.2014, 00:11 | |
Помогаю со студенческими работами здесь
9
внешние прерывания на stm32discovery
Внешние прерывания STM32F407 Внешние прерывания STM32F10xxx Неработают внешние прерывания [Stm32f303discovery] Внешние прерывания STM32 + CoIDE Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |