Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Прерывания UART на STM8S
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Все остальные микроконтроллеры > STM8
den1s
здравствуйте, только начал осваивать STM8, да еще взялся использовать их родную библиотеку. Но пока как-то понимание приходит неспеша. Вопрос собственно в организации прерываний - нужно на прерываниях замутить прием/передачу по UART2 через буфер (очередь).

функция отправки символа проверяет свободен ли передатчик и пустой ли сейчас буфер (очередь) и если это так то отправляет байт, иначе кладет его в буфер (очередь)
Код
__monitor void UART_PutChar(uint8_t sym)
{
  if((UART2_GetFlagStatus(UART2_FLAG_TXE) == SET) && (txCount == 0))
    UART2_SendData8(sym);
  else
  {
    if (txCount < SIZE_BUF)
    {
      uartTxBuf[txBufTail] = sym;
      txCount++;
      txBufTail++;
      txBufTail = txBufTail % SIZE_BUF;
    }
  }
}

обработчик прерывания проверяет есть ли символы в буфере (очереде) и если они есть отправляет очередной символ
Код
INTERRUPT_HANDLER(UART2_TX_IRQHandler, 20)
{
   if (txCount > 0)
   {
     UART2_SendData8(uartTxBuf[txBufHead]);
     txCount--;
     txBufHead++;
     if (txBufHead == SIZE_BUF)
       txBufHead = 0;
   }
}

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

Инициализацию делаю так:
Код
void UART_init(void)
{
  UART2_DeInit();
  UART2_Init((uint32_t)UART_SPEED, UART2_WORDLENGTH_8D, UART2_STOPBITS_1, UART2_PARITY_NO,
              UART2_SYNCMODE_CLOCK_DISABLE, UART2_MODE_TXRX_ENABLE);
  UART2_ITConfig(UART2_IT_TC, ENABLE);
  UART2_ITConfig(UART2_IT_RXNE_OR, ENABLE);
  UART2_Cmd(ENABLE);
  enableInterrupts();
}

извиняйте за ламерство, но как-то тяжко мне дается это дело)
scifi
Если что, вот мой драйвер UART (IAR):
CODE
#include "uart.h"
#include "stm8regs.h"
#include "assert_static.h"

#define RXBUFSIZE 8
#define TXBUFSIZE 32
/*
* The baud rate is set low so that received bytes are not lost during
* EEPROM programming (3.33 ms max). 2400 bps means 1 byte per 4.17 ms.
*/
#define BAUDRATE 2400

#define IS_POWER_OF_2(x) (!(((x) - 1) & (x)))
#define DIV2BRR1(d) (((d) >> 4) & 0xFF)
#define DIV2BRR2(d) ((((d) >> 8) & 0xF0) | ((d) & 0xF))

static uint8_t volatile rxbuf[RXBUFSIZE];
static uint8_t txbuf[TXBUFSIZE];
static uint8_t volatile rxhead, txtail;
static uint8_t rxtail, txhead;

uint8_t
uart_rxcount(void)
{
return rxhead - rxtail;
}

uint8_t
uart_txcount(void)
{
return txhead - txtail;
}

uint8_t
uart_getbyte(void)
{
uint8_t ret;
while (rxhead == rxtail)
{
/* wait for new RX data */
}
ret = rxbuf[rxtail & (RXBUFSIZE - 1)];
rxtail++;
return ret;
}

void
uart_putbyte(uint8_t byte)
{
if ((txhead - txtail) == TXBUFSIZE)
{
(void)byte; /* TX buffer full, drop the byte */
}
else
{
txbuf[txhead & (TXBUFSIZE - 1)] = byte;
txhead++;
UART1_CR2 |= 0x80; /* enable TX interrupt */
}
}

#pragma vector = 20
__interrupt static void
uart_rxhandler(void)
{
uint8_t head;
head = rxhead;
(void)UART1_SR; /* clear the OR flag if set */
if ((head - rxtail) < RXBUFSIZE)
{
rxbuf[head & (RXBUFSIZE - 1)] = UART1_DR;
rxhead = head + 1;
}
else
{
(void)UART1_DR; /* RX buffer full, drop the byte */
}
}

#pragma vector = 19
__interrupt static void
uart_txhandler(void)
{
uint8_t tail;
tail = txtail;
UART1_DR = txbuf[tail & (TXBUFSIZE - 1)];
tail++;
txtail = tail;
if (txhead == tail)
{
UART1_CR2 &= 0x7F; /* disable TX interrupt */
}
}

void
uart_init(void)
{
assert_static(IS_POWER_OF_2(RXBUFSIZE));
assert_static(IS_POWER_OF_2(TXBUFSIZE));
UART1_BRR2 = DIV2BRR2((SYSCLOCK + BAUDRATE / 2) / BAUDRATE);
UART1_BRR1 = DIV2BRR1((SYSCLOCK + BAUDRATE / 2) / BAUDRATE);
/* Lower TX interrupt level to 1 */
ITC_SPR5 &= 0xF7;
/* Enable receiver interrupt. Enable transmitter, receiver. */
UART1_CR2 = 0x2C;
}
den1s
Цитата(scifi @ Oct 22 2012, 15:16) *
Если что, вот мой драйвер UART (IAR):

Вот спасибо, понял я чего мне не хватало. Строчки типа Вашей:
Код
if (txhead == tail)
{
   UART1_CR2 &= 0x7F; /* disable TX interrupt */
}
cg_shura
Цитата(scifi @ Oct 22 2012, 18:26) *
Если что, вот мой драйвер UART (IAR):
CODE
#include "uart.h"
#include "stm8regs.h"
...

Скиньте пожалуйста файл stm8regs.h, что-то приведенный код на базе STM8S_StdPeriph_Driver не работает, подозреваю, там в stm8s.h может быть ошибка в описаниях регистров.
scifi
Цитата(cg_shura @ Jun 9 2014, 13:39) *
Скиньте пожалуйста файл stm8regs.h, что-то приведенный код на базе STM8S_StdPeriph_Driver не работает, подозреваю, там в stm8s.h может быть ошибка в описаниях регистров.

Не поможет. Я его ручками ваяю, совместимости с кем-то ещё не ищу. К тому же у разных STM8 одни и те же регистры по разным адресам могут быть размещены.
CODE
/**
* @file stm8regs.h
* @brief Register definitions for the STM8 microcontroller family
*/

#ifndef STM8REGS_H
#define STM8REGS_H

#include <stdint.h>

#define STM8_REG8(addr) (*(uint8_t volatile*)(addr))
#define STM8_REG16(addr) (*(uint16_t volatile*)(addr))

#define GPIO_BASE 0x5000
#define PA_ODR STM8_REG8(GPIO_BASE + 0)
#define PA_IDR STM8_REG8(GPIO_BASE + 1)
#define PA_DDR STM8_REG8(GPIO_BASE + 2)
#define PA_CR1 STM8_REG8(GPIO_BASE + 3)
#define PA_CR2 STM8_REG8(GPIO_BASE + 4)
#define PB_ODR STM8_REG8(GPIO_BASE + 5)
#define PB_IDR STM8_REG8(GPIO_BASE + 6)
#define PB_DDR STM8_REG8(GPIO_BASE + 7)
#define PB_CR1 STM8_REG8(GPIO_BASE + 8)
#define PB_CR2 STM8_REG8(GPIO_BASE + 9)
#define PC_ODR STM8_REG8(GPIO_BASE + 0xA)
#define PC_DDR STM8_REG8(GPIO_BASE + 0xC)
#define PC_CR1 STM8_REG8(GPIO_BASE + 0xD)
#define PD_ODR STM8_REG8(GPIO_BASE + 0xF)
#define PD_IDR STM8_REG8(GPIO_BASE + 0x10)
#define PD_DDR STM8_REG8(GPIO_BASE + 0x11)
#define PD_CR1 STM8_REG8(GPIO_BASE + 0x12)
#define PE_ODR STM8_REG8(GPIO_BASE + 0x14)
#define PE_DDR STM8_REG8(GPIO_BASE + 0x16)
#define PE_CR1 STM8_REG8(GPIO_BASE + 0x17)
#define PF_ODR STM8_REG8(GPIO_BASE + 0x19)
#define PF_DDR STM8_REG8(GPIO_BASE + 0x1B)
#define PF_CR1 STM8_REG8(GPIO_BASE + 0x1C)

#define FLASH_BASE 0x505A
#define FLASH_CR1 STM8_REG8(FLASH_BASE + 0)
#define FLASH_CR2 STM8_REG8(FLASH_BASE + 1)
#define FLASH_NCR2 STM8_REG8(FLASH_BASE + 2)
#define FLASH_IAPSR STM8_REG8(FLASH_BASE + 5)
#define FLASH_PUKR STM8_REG8(FLASH_BASE + 8)
#define FLASH_DUKR STM8_REG8(FLASH_BASE + 0xA)

#define EXTI_BASE 0x50A0
#define EXTI_CR1 STM8_REG8(EXTI_BASE + 0)

#define CLK_BASE 0x50C0
#define CLK_CKDIVR STM8_REG8(CLK_BASE + 6)
#define CLK_PCKEN1 STM8_REG8(CLK_BASE + 7)
#define CLK_CCOR STM8_REG8(CLK_BASE + 9)
#define CLK_PCKEN2 STM8_REG8(CLK_BASE + 0xA)

#define IWDG_BASE 0x50E0
#define IWDG_KR STM8_REG8(IWDG_BASE + 0)
#define IWDG_PR STM8_REG8(IWDG_BASE + 1)
#define IWDG_RLR STM8_REG8(IWDG_BASE + 2)

#define BEEP_BASE 0x50F3
#define BEEP_CSR STM8_REG8(BEEP_BASE + 0)

#define I2C_BASE 0x5210
#define I2C_CR1 STM8_REG8(I2C_BASE + 0)
#define I2C_CR2 STM8_REG8(I2C_BASE + 1)
#define I2C_FREQR STM8_REG8(I2C_BASE + 2)
#define I2C_OARL STM8_REG8(I2C_BASE + 3)
#define I2C_OARH STM8_REG8(I2C_BASE + 4)
#define I2C_DR STM8_REG8(I2C_BASE + 6)
#define I2C_SR1 STM8_REG8(I2C_BASE + 7)
#define I2C_SR2 STM8_REG8(I2C_BASE + 8)
#define I2C_SR3 STM8_REG8(I2C_BASE + 9)
#define I2C_ITR STM8_REG8(I2C_BASE + 0xA)
#define I2C_CCRL STM8_REG8(I2C_BASE + 0xB)
#define I2C_CCRH STM8_REG8(I2C_BASE + 0xC)
#define I2C_TRISER STM8_REG8(I2C_BASE + 0xD)

#define UART1_BASE 0x5230
#define UART1_SR STM8_REG8(UART1_BASE + 0)
#define UART1_DR STM8_REG8(UART1_BASE + 1)
#define UART1_BRR1 STM8_REG8(UART1_BASE + 2)
#define UART1_BRR2 STM8_REG8(UART1_BASE + 3)
#define UART1_CR2 STM8_REG8(UART1_BASE + 5)

#define UART2_BASE 0x5240
#define UART2_SR STM8_REG8(UART2_BASE + 0)
#define UART2_DR STM8_REG8(UART2_BASE + 1)
#define UART2_BRR1 STM8_REG8(UART2_BASE + 2)
#define UART2_BRR2 STM8_REG8(UART2_BASE + 3)
#define UART2_CR2 STM8_REG8(UART2_BASE + 5)
#define UART2_CR3 STM8_REG8(UART2_BASE + 6)
#define UART2_CR4 STM8_REG8(UART2_BASE + 7)
#define UART2_CR6 STM8_REG8(UART2_BASE + 9)

#define TIM1_BASE 0x5250
#define TIM1_CR1 STM8_REG8(TIM1_BASE + 0)
#define TIM1_CR2 STM8_REG8(TIM1_BASE + 1)
#define TIM1_SMCR STM8_REG8(TIM1_BASE + 2)
#define TIM1_ETR STM8_REG8(TIM1_BASE + 3)
#define TIM1_IER STM8_REG8(TIM1_BASE + 4)
#define TIM1_SR1 STM8_REG8(TIM1_BASE + 5)
#define TIM1_SR2 STM8_REG8(TIM1_BASE + 6)
#define TIM1_EGR STM8_REG8(TIM1_BASE + 7)
#define TIM1_CCMR1 STM8_REG8(TIM1_BASE + 8)
#define TIM1_CCMR2 STM8_REG8(TIM1_BASE + 9)
#define TIM1_CCMR3 STM8_REG8(TIM1_BASE + 0xA)
#define TIM1_CCMR4 STM8_REG8(TIM1_BASE + 0xB)
#define TIM1_CCER1 STM8_REG8(TIM1_BASE + 0xC)
#define TIM1_CCER2 STM8_REG8(TIM1_BASE + 0xD)
#define TIM1_CNTRH STM8_REG8(TIM1_BASE + 0xE)
#define TIM1_CNTRL STM8_REG8(TIM1_BASE + 0xF)
#define TIM1_PSCRH STM8_REG8(TIM1_BASE + 0x10)
#define TIM1_PSCRL STM8_REG8(TIM1_BASE + 0x11)
#define TIM1_ARRH STM8_REG8(TIM1_BASE + 0x12)
#define TIM1_ARRL STM8_REG8(TIM1_BASE + 0x13)
#define TIM1_RCR STM8_REG8(TIM1_BASE + 0x14)
#define TIM1_CCR1H STM8_REG8(TIM1_BASE + 0x15)
#define TIM1_CCR1L STM8_REG8(TIM1_BASE + 0x16)
#define TIM1_CCR2H STM8_REG8(TIM1_BASE + 0x17)
#define TIM1_CCR2L STM8_REG8(TIM1_BASE + 0x18)
#define TIM1_CCR3H STM8_REG8(TIM1_BASE + 0x19)
#define TIM1_CCR3L STM8_REG8(TIM1_BASE + 0x1A)
#define TIM1_CCR4H STM8_REG8(TIM1_BASE + 0x1B)
#define TIM1_CCR4L STM8_REG8(TIM1_BASE + 0x1C)
#define TIM1_BKR STM8_REG8(TIM1_BASE + 0x1D)
#define TIM1_DTR STM8_REG8(TIM1_BASE + 0x1E)
#define TIM1_OISR STM8_REG8(TIM1_BASE + 0x1F)

#define TIM2_BASE 0x5300
#define TIM2_CR1 STM8_REG8(TIM2_BASE + 0)
#define TIM2_IER STM8_REG8(TIM2_BASE + 1)
#define TIM2_SR1 STM8_REG8(TIM2_BASE + 2)
#define TIM2_SR2 STM8_REG8(TIM2_BASE + 3)
#define TIM2_EGR STM8_REG8(TIM2_BASE + 4)
#define TIM2_CCMR1 STM8_REG8(TIM2_BASE + 5)
#define TIM2_CCMR2 STM8_REG8(TIM2_BASE + 6)
#define TIM2_CCMR3 STM8_REG8(TIM2_BASE + 7)
#define TIM2_CCER1 STM8_REG8(TIM2_BASE + 8)
#define TIM2_CCER2 STM8_REG8(TIM2_BASE + 9)
#define TIM2_CNTRH STM8_REG8(TIM2_BASE + 0xA)
#define TIM2_CNTRL STM8_REG8(TIM2_BASE + 0xB)
#define TIM2_PSCR STM8_REG8(TIM2_BASE + 0xC)
#define TIM2_ARRH STM8_REG8(TIM2_BASE + 0xD)
#define TIM2_ARRL STM8_REG8(TIM2_BASE + 0xE)
#define TIM2_CCR1H STM8_REG8(TIM2_BASE + 0xF)
#define TIM2_CCR1L STM8_REG8(TIM2_BASE + 0x10)
#define TIM2_CCR2H STM8_REG8(TIM2_BASE + 0x11)
#define TIM2_CCR2L STM8_REG8(TIM2_BASE + 0x12)
#define TIM2_CCR3H STM8_REG8(TIM2_BASE + 0x13)
#define TIM2_CCR3L STM8_REG8(TIM2_BASE + 0x14)

#define TIM3_BASE 0x5320
#define TIM3_CR1 STM8_REG8(TIM3_BASE + 0)
#define TIM3_IER STM8_REG8(TIM3_BASE + 1)
#define TIM3_SR1 STM8_REG8(TIM3_BASE + 2)
#define TIM3_SR2 STM8_REG8(TIM3_BASE + 3)
#define TIM3_EGR STM8_REG8(TIM3_BASE + 4)
#define TIM3_CCMR1 STM8_REG8(TIM3_BASE + 5)
#define TIM3_CCMR2 STM8_REG8(TIM3_BASE + 6)
#define TIM3_CCER1 STM8_REG8(TIM3_BASE + 7)
#define TIM3_CNTRH STM8_REG8(TIM3_BASE + 8)
#define TIM3_CNTRL STM8_REG8(TIM3_BASE + 9)
#define TIM3_PSCR STM8_REG8(TIM3_BASE + 0xA)
#define TIM3_ARRH STM8_REG8(TIM3_BASE + 0xB)
#define TIM3_ARRL STM8_REG8(TIM3_BASE + 0xC)
#define TIM3_CCR1H STM8_REG8(TIM3_BASE + 0xD)
#define TIM3_CCR1L STM8_REG8(TIM3_BASE + 0xE)
#define TIM3_CCR2H STM8_REG8(TIM3_BASE + 0xF)
#define TIM3_CCR2L STM8_REG8(TIM3_BASE + 0x10)
#define TIM3_CCR2 STM8_REG16(TIM3_BASE + 0xF)

#define TIM4_BASE 0x5340
#define TIM4_CR1 STM8_REG8(TIM4_BASE + 0)
#define TIM4_IER STM8_REG8(TIM4_BASE + 1)
#define TIM4_SR STM8_REG8(TIM4_BASE + 2)
#define TIM4_CNTR STM8_REG8(TIM4_BASE + 4)
#define TIM4_PSCR STM8_REG8(TIM4_BASE + 5)
#define TIM4_ARR STM8_REG8(TIM4_BASE + 6)

#define ADC_BASE 0x53E0
#define ADC_DBRH(n) STM8_REG8(ADC_BASE + 2 * n)
#define ADC_DBRL(n) STM8_REG8(ADC_BASE + 2 * n + 1)
#define ADC_DBR(n) STM8_REG16(ADC_BASE + 2 * n)
#define ADC_CSR STM8_REG8(ADC_BASE + 0x20)
#define ADC_CR1 STM8_REG8(ADC_BASE + 0x21)
#define ADC_CR2 STM8_REG8(ADC_BASE + 0x22)
#define ADC_CR3 STM8_REG8(ADC_BASE + 0x23)
#define ADC_DRH STM8_REG8(ADC_BASE + 0x24)
#define ADC_DRL STM8_REG8(ADC_BASE + 0x25)
#define ADC_DR STM8_REG16(ADC_BASE + 0x24)

#define ITC_BASE 0x7F70
#define ITC_SPR5 STM8_REG8(ITC_BASE + 4)
#define ITC_SPR6 STM8_REG8(ITC_BASE + 5)

#define SYSCLOCK 16000000

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