реклама на сайте
подробности

 
 
> Прерывания UART на STM8S, Не втыкаю как с прерываниями работать
den1s
сообщение Oct 22 2012, 09:34
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 51
Регистрация: 17-03-11
Пользователь №: 63 677



здравствуйте, только начал осваивать 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();
}

извиняйте за ламерство, но как-то тяжко мне дается это дело)


--------------------
"Одной мотивации недостаточно: если у вас есть идиот и вы его мотивировали, то в результате вы получите мотивированного идиота." - Джим Рон
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
scifi
сообщение Oct 22 2012, 11:16
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Если что, вот мой драйвер 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;
}
Go to the top of the page
 
+Quote Post
cg_shura
сообщение Jun 9 2014, 09:39
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 33
Регистрация: 28-04-10
Пользователь №: 56 958



Цитата(scifi @ Oct 22 2012, 18:26) *
Если что, вот мой драйвер UART (IAR):
CODE
#include "uart.h"
#include "stm8regs.h"
...

Скиньте пожалуйста файл stm8regs.h, что-то приведенный код на базе STM8S_StdPeriph_Driver не работает, подозреваю, там в stm8s.h может быть ошибка в описаниях регистров.

Сообщение отредактировал cg_shura - Jun 9 2014, 09:40
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 30th July 2025 - 21:29
Рейтинг@Mail.ru


Страница сгенерированна за 0.01391 секунд с 7
ELECTRONIX ©2004-2016