proton8489

Внешние прерывания STM32F10xxx

4 сообщения в этой теме

proton8489    0

Господа, имею следующий код (а он имеет меня), который вообще никак не заметен микроконтроллером (stm32f103rb, stm32f103c8). Подавая сигналы "0" или "1" на входы прерывания не выполняются. Пробовал вызывать внутреннее прерывание, но попытки были бессмысленны. Что здесь не так?


void NVIC_InputInit(void)
{ 
  RCC->APB2ENR |= RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPCEN; 	// Тактирование альтернативных функций и порта
  PIO_INIT_PIN(GPIOC,6,Input_Floating);     // PС6,7 на вход
  PIO_INIT_PIN(GPIOC,7,Input_Floating); 
  PIO_INIT_PIN(GPIOC,10,Output2_Push_Pull);  // PС10,11 на выход
  PIO_INIT_PIN(GPIOC,11,Output2_Push_Pull);
 
  AFIO->EXTICR[1] |= AFIO_EXTICR2_EXTI6_PC | AFIO_EXTICR2_EXTI7_PC;  // Настройка порта и выбор пинов для прерывания 
  EXTI->IMR |= EXTI_IMR_MR6 | EXTI_IMR_MR7;    // Разрешаем генерацию прерывания в периферии          
  EXTI->RTSR |= EXTI_RTSR_TR6 | EXTI_RTSR_TR7;  // Настроим прерывание на детектирование обоих фронтов            
  EXTI->FTSR |= EXTI_FTSR_TR6 | EXTI_FTSR_TR7;  // у двух входов   
  //EXTI->EMR |= EXTI_EMR_MR6; //Разрешение возобновления при внешних событиях

  // Разрешаем прерывания  
  //uint32_t prioritygroup = NVIC_GetPriorityGrouping();
  //uint32_t priority = NVIC_EncodePriority(prioritygroup, 1, 0 );
  //NVIC_SetPriority(EXTI9_5_IRQn, priority);
  NVIC_EnableIRQ(EXTI9_5_IRQn);  
  // Разрешаем глобальные прерывания  
  __enable_irq(); 

  //EXTI->SWIER |= EXTI_IMR_MR7; // Внутреннее прерывание
}

void EXTI9_5_IRQHandler(void) 
{
  if (EXTI->PR & (1<<6)) //проверяем прерывание от EXTI6
  { 
     EXTI->PR |= (1<<6);
    //EXTI->PR |= EXTI_PR_PR6; //сброс флага прерывания 
     
    PIO_RESET(GPIOC,11);   
  } 
  // if ((EXTI->PR & EXTI_PR_PR7) == EXTI_PR_PR7) 
  if (EXTI->PR & (1<<7)) //проверяем прерывание от EXTI6
  { 
    EXTI->PR |= (1<<7);
    //EXTI->PR |= EXTI_PR_PR7; //сброс флага прерывания 
    
    PIO_RESET(GPIOC,10); 
  }
}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Быстрый заказ печатных плат

Полный цикл производства PCB по низким ценам!

  • x
    мм
Заказать Получить купон на $5.00
proton8489    0

Ну неужели никто не знает и не подскажет? Проблема точно не аппаратная, контакт есть, а реакции на него нет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
snn_krs    4

STM32F103C8, Keil 5 ниже код работает нормально. Проверьте в отладчике устанавливаются AFIO->EXTICR[1]. или нет.

 

void NVIC_InputInit(void)
{ 
  RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; 	// 
  AFIO->EXTICR[1] |= AFIO_EXTICR2_EXTI6_PB | AFIO_EXTICR2_EXTI7_PB;  //
  EXTI->IMR |= EXTI_IMR_MR6 | EXTI_IMR_MR7;    //
  EXTI->RTSR |= EXTI_RTSR_TR6 | EXTI_RTSR_TR7;  //
  EXTI->FTSR |= EXTI_FTSR_TR6 | EXTI_FTSR_TR7;  //
  NVIC_EnableIRQ(EXTI9_5_IRQn);  
  __enable_irq(); 
}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
proton8489    0

У меня точно такой же код и в отладчике всё было с регистрами нормально, кроме захода в само прерывание. Но проблема решена. Оказывается надо было подключить к проекту файл стартапа (список векторов прерываний), который сам ни через что не цепляется.
 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ваша публикация должна быть проверена модератором

Гость
Вы не авторизованы. Если у вас есть аккаунт, пожалуйста, войдите.
Ответить в тему...

×   Вставлено в виде отформатированного текста.   Восстановить форматирование

  Разрешено не более 75 смайлов.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставить изображения напрямую. Загрузите или вставьте изображения по ссылке.

Загрузка...

  • Похожие публикации

    • Автор: melkiy93
      Доброго!
      Контроллер stm32f103c8t6. Пишу настройку таймера и его прерываний, но программа зависает через несколько тиков после выхода из самой функции настройки.
      По коду: в главной функции пишу сразу настройку таймера и далее бесконечный цикл, до которого дело не доходит.
      На рисунках скрины отладки в момент зависания.
      void TIM_ini(void) { TIM_TimeBaseInitTypeDef UserTimStruct; NVIC_InitTypeDef UserNVIC_Structure; TIM_DeInit(TIM3); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); UserTimStruct.TIM_ClockDivision = TIM_CKD_DIV4; UserTimStruct.TIM_CounterMode = TIM_CounterMode_Up; UserTimStruct.TIM_Period = 200; UserTimStruct.TIM_Prescaler = 700-1; TIM_TimeBaseInit(TIM3, &UserTimStruct); TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); TIM_Cmd(TIM3, ENABLE); UserNVIC_Structure.NVIC_IRQChannel = TIM3_IRQn; UserNVIC_Structure.NVIC_IRQChannelCmd = ENABLE; UserNVIC_Structure.NVIC_IRQChannelPreemptionPriority = 1; UserNVIC_Structure.NVIC_IRQChannelSubPriority = 1; NVIC_Init(&UserNVIC_Structure); } ,

    • Автор: trengtor
      Я верно понимаю, что вектор для прерывания по достижению счетчиком PWM значения TOP совпадает с вектором для переполнения этого же счетчика?
    • Автор: Дмитрий Т87
      Здравствуйте. Прошу помощи в теме статитическая индикация 6 разрядного 7ми сегментного индикатора по 2м проводам Data и Clock.
      Есть такой код для 3х разрядного индикатора в CVavr Си
      Хочу закидывать данные в каждый разряд отдельно, и выводить эти функции в прерываниях avr микроконтроллера.

      // cd4094 control example by kalobyte.com 2009 #include <avr/io.h> #define F_CPU 1000000UL #include <util/delay.h> #define REG_PORT PORTB #define REG_DDR DDRB #define REG_PIN_DATA 3 #define REG_PIN_CLK 4 //--- #define REG_DATA_ON REG_PORT|=1<<REG_PIN_DATA; #define REG_DATA_OFF REG_PORT&=~(1<<REG_PIN_DATA); #define REG_CLK {REG_PORT|=1<<REG_PIN_CLK;REG_PORT&=~(1<<REG_PIN_CLK);} unsigned char digs[10]={0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F}; // katode // unsigned char digs[10]={0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90}; //anode void cd4094_init(void){ char i=0; while(i!=24){ REG_CLK i++; } } void cd4094(int dig){ char i,tmp,j; //dig = 123; int div[4]; div[1] = digs[dig%10]; dig = dig/10; div[2] = digs[dig%10]; div[3] = digs[dig/10]; for(j=3;j>0;j--){ tmp = div[j]; for(i=8;i>0;i--){ if(tmp & 0x80){ REG_DATA_ON } else {REG_DATA_OFF} tmp <<=1; REG_CLK } } } int main(void){ int i=1; REG_DDR = (1<<REG_PIN_DATA)|(1<<REG_PIN_CLK); REG_PORT = (0<<REG_PIN_DATA)|(0<<REG_PIN_CLK); cd4094_init(); //cd4094(2); while(i<999){ _delay_ms(1000); cd4094(i); i++; } return 0; }
      Вот такая схема

    • Автор: 123654789
      Пишу прошивку для управления всяким с пульта от телека, столкнулся с непонятным мне поведением программы (об этом ниже).
      Прошивка:

      #define F_CPU 4800000L // 4.8 Мгц #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #define INVERT_PIN(x) PORTB ^= x /* PB2 (7) - реле (ВЫХОД). PB1 (PCINT1) (6) - ИК-приёмник (ВХОД). PB0 (PCINT0) (5) - сенсорная панель (ВХОД). PB3 (2) - светодиод (ВЫХОД). PB4 (PCINT4) (3) - кнопка (ВХОД). */ volatile char is_sensor_active = 0; volatile unsigned int rc_code = 0; volatile unsigned int etalon_rc_code = 0; // http://www.atmel.com/webdoc/AVRLibcReferenceManual/group__util__delay_1gad22e7a36b80e2f917324dc43a425e9d3.html // 262.14 / 4.8 = 54.61 мс - это максимальная задержка для данной частоты, до которой можно использовать _delay_ms. void delay_ms(unsigned int period) { while(--period) { _delay_ms(1); } } ISR(PCINT0_vect) { is_sensor_active = 1; } int main() { DDRB = 0b00001100; // Срабатывание прерывания при смене логического уровня на ножках. MCUCR = 0b00000001; // Прерывание генерятся при изменении уровня на ножках. GIMSK = 0b00100000; // Выбор генерящих прерывание пинов. PCMSK = 0b00000010; sei(); while(1) { if( is_sensor_active ) { cli(); rc_code = 0; for( int i = 0; i < sizeof(rc_code) * 8; ++i) { rc_code = (rc_code << 1) + ((PINB & 0b00000010) >> 1); _delay_ms(16); } if( etalon_rc_code == 0) etalon_rc_code = rc_code; if( etalon_rc_code == rc_code) { INVERT_PIN(0b00000100); } else { for( int i = 0; i < 10; ++i) { INVERT_PIN(0b00001000); _delay_ms(30); } } is_sensor_active = 0; delay_ms(240); sei(); } } return 0; }
      Как я ожидаю она должна работать: как только на ножке 6 сменится логический уровень, с ножки же 6 будет считано четырехбайтовое беззнаковое целое, принято за эталон команды и на ножке 7 установится лог. 1. При повторном зажигании прерывания снова будет считана команда, сравнена с эталонной и, если совпадает, инвертируется ножка 7. В противном случае помигать ножкой 2.
      Как оно на самом деле работает: вне зависимости от была ли команда верной или нет, контроллер дергает ножкой 2. Отсюда я делаю вывод, прерывание почему-то зажигается дважды. Но ведь не должно же! Вопрос: что же я упустил, приводящее к такому поведению? При обработке команды я прерывания запрещаю же, потом обратно включаю.
    • Гость AlexKooper
      Автор: Гость AlexKooper
      Добрый день. Имеется ардуина, которая на int0 по прерываниям меряет частоту (скорость с приборной доски авто). Хочу включать в теле программы прерывание int0 только в нужные моменты, но не запрещать вообще все прерывания, а только INT0 включать-выключать. Как это сделать?
      Второй вопрос.
      Захотелось добавить управление с ИК-пульта (там тоже по прерываниям работает, но все ньюансы скрыты внутри библиотеки), при этом наблюдается какой-то конфликт c функциями Tone или Delay - звуковые сигналы вместо гудков превращаются в щелчки. Пока функция вывода звуковых сигналов не вызывалась - всё работает. Как пошли - ИК-команды не ловятся.
      Как найти, почему ИК-команды перестают ловится после вызова такой процедуры?
      void rukabeep()
      {
      tone (17,3000);
      delay(200);
      noTone(17);
      }
      P.S. работа с ИК пультом устроена так:
      библиотека IRremote_a10.zip
      void setup()
      {
      //start IR reciver
      irrecv.enableIRIn();
      }
      в лупе функция
      if (irrecv.decode(&results))
      {
      lcd.print(results.value);
      irrecv.resume(); // Receive the next value
      }