Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM8S-Discovery не получается зайти в обработчик прерывания
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Все остальные микроконтроллеры > STM8
smk
Как ни стараюсь, а в обработчик прерывания от таймера не попадаю. Подскажите в чем может быть проблема? Спасибо.
Код
#include <stm8s105c6.h> //Бибилиотека описаний периферии
//#include <intrins.h>
#include <intrist7.h>
#define enableInterrupts()  _rim_()  /* enable interrupts */
#define disableInterrupts() _sim_()  /* disable interrupts */

unsigned char a,b,c,Timer4;

void TIM4_UPD_OVF_IRQHandler(void) interrupt 23    //обработчик прерывания по таймеру 4
    {
        TIM4_SR &= ~(1<<0);     //Сбросим признак прерывания
        if(Timer4) Timer4--;      //Программный таймер        
    }

void Timer4_1ms_set (void) //инициализация таймера
    {
        TIM4_SR &= ~(1<<0);        //Сбросим признак прерывания
        TIM4_PSCR=0x07;           //Предделитель на 2^7=128   16000000/128 = 125000 Hz
        TIM4_ARR=125;             //Регистр автозагрузки таймера при переполнении 125000 / 250 = 500 Hz
        TIM4_IER |= (1<<0);       //Разрешаем генерацию прерывания при переполнеини
        CLK_PCKENR1 |= (1<<4); //Подключаем тактовый генератор к таймеру 4
        TIM4_CR1 |= (1<<0);       //Разрешаем счет
    }

_rim_(); //разрешить глобально прерывания


В отладчике видно, что флаг прерывания устанавливается, но обработчик не выполняется. В чем может быть причина? Спасибо.
Mareng
Цитата(smk @ Jan 4 2012, 03:55) *
Как ни стараюсь, а в обработчик прерывания от таймера не попадаю

Насколько я понял, кусок кода взят отсюда? http://eugenemcu.ru/publ/11-1-0-67
Если все так, как написано в вашем посте, то очевидно не хватает #pragma vector=TIM4_OVR_UIF_vector для захода в прерывание.
smk
Цитата(Mareng @ Jan 4 2012, 04:43) *
Насколько я понял, кусок кода взят отсюда? http://eugenemcu.ru/publ/11-1-0-67
Если все так, как написано в вашем посте, то очевидно не хватает #pragma vector=TIM4_OVR_UIF_vector для захода в прерывание.

Идея взята оттуда, но писана самостоятельно. Там под IAR, а у меня Raisonance.

Кстати, посмотрел пример от ST, там правда другие прерывания используются, так явных отличий в реализации не нашел. Что бы это значило?
Mareng
У вас в компиляторе указан какой-нить аналог иаровской #pragma vector?
Вектор прерывания указывает на вашу функцию-обработчик?
smk
Цитата(Mareng @ Jan 4 2012, 08:09) *
У вас в компиляторе указан какой-нить аналог иаровской #pragma vector?
Вектор прерывания указывает на вашу функцию-обработчик?

Код
void TIM4_UPD_OVF_IRQHandler(void) interrupt 23

Вот та цифра 23 ,судя по документации на компилятор, и указывает на вектор. Перед ней обязательно ключевое слово interrupt. Компилируется без ошибок и предупреждений, но не работает.

Нажмите для просмотра прикрепленного файла
Mareng
Цитата(smk @ Jan 4 2012, 13:13) *
Вот та цифра 23

просмотрел...
smk
В документе, что прикрутил к предыдущему посту на с.44 написано:
Цитата
4.5.1 Interrupts
An interrupt function must be declared with a specific syntax:
● void funcname(void) interrupt intnumber
● There must be no parameters and no return value.
● The keyword “interrupt” must follow the function header.
● After the “interrupt” keyword you can specify the interrupt number handled by the function.
● intnumber is the interrupt number taken by the function (from 0 to 13 on ST7, from 0 to 31 on
STM8).


Делаю вроде бы точно по науке.
smk
Вот это работает. В чем фокус?
Код
//
// main.c подходит для любого компилятора IAR, Cosmic, Raisonance
// с использованием определений из библиотеки STMicroelectronics
// для компиляции требуются файлы stm8s.h и stm8s_type.h из библиотеки.
// В файле stm8s.h найдите и закомментируйте #define USE_STDPERIPH_DRIVER
// ----------------------------------------------------------------------------
#include "stm8s.h"
#define LED_BIT 0           //на Discovery светодиод подключен на PD0, активный уровень - 0

int Timer1;

#ifdef _IAR_SYSTEMS_
#pragma vector=25 //особенность IAR - номер_вектора = номер_по_документации_ST + 2
__interrupt
#endif

void TIM4_IRQ_Handler(void)

#ifndef _COSMIC_
#ifdef _RAISONANCE_
interrupt 23      //для Raisonance номер вектора равен описанному в документации ST
#endif

// для Cosmic поместите код обработчика прерывания TIM4 в файл stm8s_it.c
{
  TIM4->SR1&=~TIM4_SR1_UIF;  //Сбросим признак прерывания
  if(Timer1) Timer1--;       //Программный таймер
}
#endif

void main( void )
{
  //Инициализируем CLK
  CLK->ECKR|=CLK_ECKR_HSEEN; //Разрешаем работу генератора с внешним кварцем (HSEEN)
  CLK->SWCR|=CLK_SWCR_SWEN;  //Разрешаем автопереключение источника Clock при неисправности генератора
  CLK->SWR=0xB4;             //Включаем clock от кварцевого генератора (HSE)
  CLK->CKDIVR=0;             //Делители частоты внутреннего и внешнего генератора на 1 - частота ядра максимальная

  //Инициализируем GPIO
  GPIOD->DDR|=1<<LED_BIT;    //PD0 - на вывод
  GPIOD->CR1&=~(1<<LED_BIT); //PD0 - открытый сток
  GPIOD->CR2&=~(1<<LED_BIT); //PD0 - ограничение скорости отключено

  //Инициализируем TIM4
  TIM4->SR1&=~TIM4_SR1_UIF;  //Сбросим признак прерывания
  TIM4->PSCR=0x07;           //Предделитель на 2^7=128   16000000/128 = 125000 Hz
  TIM4->ARR=250;             //Регистр автозагрузки таймера при переполнении 125000 / 250 = 500 Hz
  TIM4->IER|=TIM4_IER_UIE;   //Разрешаем генерацию прерывания при переполнеини
  TIM4->CR1|=TIM4_CR1_CEN;   //Разрешаем счет

  enableInterrupts();        //Разрешаем прерывания
  //Собственно мигание
  Timer1=250;                //500 / 250 = 2 Hz (500 мс)
  while(1)
  {
    if(!Timer1)              //Прошло 500 мс?
    {
      Timer1=250;            //500 / 250 = 2 Hz (500 мс)
      GPIOD->ODR^=(1<<LED_BIT); //Переключим светодиод
    }
  }
}

smk
Конечно удобнее если кто подскажет, то не так много времени уходит на поиски ошибок. Я так понял, что я по ошибке разрешил прерывания при переключении тактирования и после это самое переключение разрешал. Предполагаю, что в итоге контроллер уходил в прерывание, обработчик которого не описан и не определен никак. Вероятно там контроллер и оставался. Не знаю насколько это возможно, но другого объяснения не нахожу. Привожу архив с рабочим проектом, может кому поможет сэкономить время. И еще вопрос к знающим людям. У меня в проект пришлось скопировать stm8s105c6.h и stm8s105c_s.h. Я так понимаю, это из библиотеки компилятора. Почему он сам их не видит и как сделать чтобы видел? Спасибо.

Нажмите для просмотра прикрепленного файла
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.