Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить

Проблема с прерыванием USART STM8L

Пн июн 03, 2013 18:15:17

Доброго времени суток!

Работаю с STM8L-Discovery (STM8L152C6) в IAR.
Настроил USART на передачу, теперь пытаюсь настроить USART на прием. Никак не могу попасть в прерывание(или попадаю и не могу выйти). Перечитал похожие проблемы: у кого-то библиотеки в IAR неправильные адреса прерываний выдают, у кого-то флаг не сбрасывается (так и не понял как сбросить флаг) - все равно не работает

Настроил порты USART на ввод и вывод, установил кварц и скорость USART. Задача слушать вход и после прихода символа выдавать что-то на выход (Hello)

Код:
#define STM8L15X_MD
#include "iostm8l152c6.h"
#include "stm8l15x.h"
#include "intrinsics.h"

// !!! Edit stm8l15x_conf.h to enable peripheral header
// !!! Test STM8L15X_MD in stm8l15x.h to the target STM8L device used
// Current selected:
// STM8L15x devices are STM8L151C4, STM8L151C6, STM8L152C4,
// STM8L152C6, STM8L151K4, STM8L151K6, STM8L152K4, STM8L152K6, STM8L151G4,
// STM8L151G6, STM8L152G4 and STM8L152G6


void main(){

// Настройка портов

PC_DDR_bit.DDR3 = 1; //P.3.3 - на выход
PC_CR1_bit.C13 = 1; // Push-pull
PC_CR2_bit.C23 = 0;

PC_DDR_bit.DDR2 = 0; //P.3.2 - на вход
PC_CR1_bit.C12 = 1; // Push-pull
PC_CR2_bit.C22 = 1; // с прерыванием

// Настройки кварца

CLK->ICKCR |= CLK_ICKCR_HSION;
CLK->ICKCR |= CLK_ICKCR_HSION; // внутренний
CLK->SWCR |= CLK_SWCR_SWEN;
CLK->SWR = 0x01;
CLK->CKDIVR = CLK_CKDIVR;

while(CLK_SCSR!=0x01); //ждем стабилизации


CLK->PCKENR1 |= CLK_PCKENR1_USART1;


USART1->BRR2 = 0x00; // Скорость 9600 при кварце 2 МГЦ
USART1->BRR1 = 0x0D;


USART1->CR1 = 0;
USART1->CR3 = 0;

USART1->CR4 = 0;
USART1->CR5 = 0;

USART1->CR2 = USART_CR2_REN; // Разрешение приема и передачи и разрешение прерывания
USART1->CR2 = USART_CR2_RIEN;
USART1->CR2 = USART_CR2_TEN;

__enable_interrupt();
while(1) // ждем символа на вход
{ }
}

#pragma vector=USART_R_OR_vector
__interrupt void USART_RXNE(void)
{
// Выводим Hello!

while (1)
{
USART1->DR = 'H';
while(!(USART1->SR & USART_SR_TC));
USART1->DR = 'e';
while(!(USART1->SR & USART_SR_TC));
USART1->DR = 'l';
while(!(USART1->SR & USART_SR_TC));
USART1->DR = 'l';
while(!(USART1->SR & USART_SR_TC));
USART1->DR = 'o';
while(!(USART1->SR & USART_SR_TC));
USART1->DR = '!';
while(!(USART1->SR & USART_SR_TC));
}
}



Может кто-нибудь знает где тут подводные камни?

Re: Проблема с прерыванием USART STM8L

Чт фев 02, 2017 12:01:16

Прерывание нужно делать на по входу С2, а по заполнению приемного регистра - UART1_CR2_RIEN. А так получается, что обработчик запускается по первому фронту первого бита в посылке и контроллер вместо приема байта и записи его в регистр, пытается обработать не нужное прерывание.

Re: Проблема с прерыванием USART STM8L

Чт янв 23, 2020 12:28:01

Добрый день, друзья! Тема конечно мертва, но наткнулся на точно такую же проблему. Передавать могу, но при попытке принимать в прерывании всё ломается. Сейчас обработчик такой:
Войти в прерывание, зажечь светодиод, считать принятый байт, запустить его же на передачу, погасить светодиод и выйти из прерывания. Флаг, судя по даташиту, должен сняться в момент считывания USART_DR. Нооооооооо ничего не происходит. МК вообще наглухо повисает после принятия байта, и до резета молчит. Есть версия, что ошибка в самих библиотеках/компиляторе -- и дело в векторе прерывания и возвращения из него. Нооооо... может всё-таки ошибка на моей стороне? Подскажет кто чего? :dont_know:

Код:
#pragma vector=USART_R_OR_vector
__interrupt void USART_RXNE(void)
{
PB_ODR_bit.ODR2 = 1;
USART1_DR = USART1_DR;
PB_ODR_bit.ODR2 = 0;
}
Ответить