Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Обработчик внешнего прерывания для STM8S в IAR
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
Kir85
Здравствуйте.

Имеется отладочная плата STM8S-DISCOVERY
http://www.st.com/jp/evalboard/product/247087.jsp

Код пишу в IAR... Для прерывания по переполнению TIM1 все прозрачно. Смотрим подключаемый файл iostm8s105c6.h, находим строчку
Код
#define TIM1_OVR_TIF_vector                  0x0D

Далее в main.cpp пишем обработчик...
Код
#pragma vector=TIM1_OVR_UIF_vector // прерывание каждые 20мкс
__interrupt void Tim1_over(void){
  TIM1_SR1_bit.UIF = 0;    // Сброс флага прерывания, обязательно делать вручную!!!  
  counter++;
  if(counter == 25000){ // это 0,5 сек
    c_c = c_c+1;
    counter=0;  
    if(c_c == 2){ // Это 1 сек  
      c_c=0;  
      PD_ODR_bit.ODR0 = ~PD_ODR_bit.ODR0;
    }
  }
}

Теперь стал дальше изучать... Появилось два вопроса..
1. Что значит значение 0x0D в подключаемом файле iostm8s105c6.h???
2. Как узнать это значение для внешнего прерывания, т.к. в файле iostm8s105c6.h я его не нашел... Т.е. как написать обработчик для внешнего прерывания..
Весь код main.cpp ниже
CODE
#include "iostm8s105c6.h"

char flag = 1;
int counter = 0;
char c_c = 0;
bool c=false;

#pragma vector=TIM1_OVR_UIF_vector // прерывание каждые 20мкс
__interrupt void Tim1_over(void)
{
// Обработчик прерывания таймера здесь!
TIM1_SR1_bit.UIF = 0; // Сброс флага прерывания, обязательно делать вручную!!!
counter++;
if(counter == 25000){ // это 0,5 сек
c_c = c_c+1;
counter=0;
if(c_c == 2){ // Это 1 сек
c_c=0;
PD_ODR_bit.ODR0 = ~PD_ODR_bit.ODR0;
}
}
}


void init(void){
//Инициализируем CLK
CLK_ECKR_bit.HSEEN=1; //Разрешаем работу генератора с внешним кварцем (HSEEN)
CLK_SWCR_bit.SWEN=1; //Разрешаем переключение генераторов;
CLK_SWR=0xB4; //Выбираем clock от кварцевого генератора (HSE)
CLK_CKDIVR=0; //Делители частоты внутреннего и внешнего генератора на 1 - частота ядра максимальная
while(CLK_CMSR!=0xB4); //Ждем стабилизации частоты
CLK_CSSR_bit.CSSEN=1; //Разрешаем автопереключение источника Clock на внутренний при неисправности генератора

//Инициализируем GPIO
//на Discovery светодиод подключен на PD0, активный уровень - 0
PD_DDR_bit.DDR0=1; // PD0 - на выход, TIM3_CH2
PD_CR1_bit.C10=1; // In output mode (DDR = 1): 0: Pseudo open drain 1: Push-pull, slope control for the output depends on the
// corresponding CR2 bit
PD_CR2_bit.C20=1; // In output mode (DDR = 1): 0: Output speed up to 2 MHz 1: Output speed up to 10 MHz
PD_ODR_bit.ODR0=0; // Writing to the ODR register when in output mode applies a digital value to the I/O through the latch.

PD_DDR_bit.DDR2 = 0; // PD1 - на вход
PD_CR1_bit.C12=0; // In input mode (DDR = 0): 0: Floating input 1: Input with pull-up
PD_CR2_bit.C22=1; // In input mode (DDR = 0): 0: External interrupt disabled 1: External interrupt enabled
//PD_ODR_bit.ODR0=0; // In input mode, writing in the ODR register, latche s the value in the register but does not change the pin state.

CPU_CCR_bit.I0 = 1;
CPU_CCR_bit.I1 = 1;
EXTI_CR1_PDIS = 3; // 00: Falling edge and low level 01: Rising edge only 10: Falling edge only 11: Rising and falling edge

//Инициализируем TIM1, прерывание каждые 20мкс
TIM1_PSCRH = 0x00; // The counter clock frequency fCK_CNT is equal to fCK_PSC / (PSCR[15:0]+1)
TIM1_PSCRL = 0x00; // При 16 МГц один такт 62,5нс. Для 20 мкс нужно 320 тактов.
TIM1_ARRH=0x01;
TIM1_ARRL=0x40; // Досчитать 320.
TIM1_IER_bit.UIE = 1;
TIM1_CR1_bit.CEN = 1;
}

void main( void )
{
init();
asm("rim");
while(1){
asm("nop");
asm("nop");
asm("nop");
asm("nop");
}
}
Lagman
Вот тут http://www.st.com/internet/com/TECHNICAL_R.../CD00200092.pdf на 47 странице все написано.
Хм, правда там не понятно откуда считать вектора, но если исходить из того что у меня работало, то надо считать от первой записи (счет вести от 0 sm.gif ).
Kir85
Спасибо! Заработало!!!
Обработчик выглядит след. образом
Код
#pragma vector=0x08 // внешие прерывания PORTD
__interrupt void PORD_edge(void){
  asm("nop");
  asm("nop");
  asm("nop");
  asm("nop");
}


0x08 = 0x06+const, где const = 0x02, а 0x06 берется отсюда
Нажмите для просмотра прикрепленного файла
Откуда берется 0x02 хз, но работает ))
Glupen'
А простоучитываются первые два прерывания — RESET и TRAP. А в таблице они идут без номеров. А у IAR они пронумерованы, вот двойку и прибавляют.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.