简体   繁体   English

stm8 uart tx中断问题

[英]stm8 uart tx interrupt issue

I am programming a STM8S103F3 to TX on UART via interrupt.我正在通过中断将 STM8S103F3 编程到 UART 上的 TX。 I understand a write to DR after "Transmit data register empty interrupt" will start another TX, so I have this in my ISR.我知道在“发送数据寄存器空中断”之后写入 DR 将启动另一个 TX,所以我的 ISR 中有这个。 But it only works if my main loop spins on wait for interrupt.但它只有在我的主循环旋转等待中断时才有效。 If it spins on nop only the first char is TXed - as though the write to DR within the ISR does not generate a subsequent interrupt.如果它在 nop 上旋转,则仅发送第一个字符 - 就好像在 ISR 中写入 DR 不会产生后续中断一样。

Using SDCC compiler.使用 SDCC 编译器。

sdcc -mstm8 -o build\uart.hex uart.c

#include <stdint.h>
#include <stdlib.h>
#include "stm8.h"

#define DEBUG_BUF_SIZE 10
char debugBuf[DEBUG_BUF_SIZE];
volatile unsigned char *debugPtr;

// UART Tx interrupt
void TX_complete(void) __interrupt(UART_TX_COMPLETE) {
    if(*debugPtr != 0) {
        UART1_DR = *debugPtr++;
    } 
}

void log(char *msg)
{
    unsigned char i = 0;

    UART1_CR2 &= ~UART_CR2_TIEN;
    for(; msg[i] != 0 && i<DEBUG_BUF_SIZE-1; i++) {
        debugBuf[i] = msg[i];
    }
    debugBuf[i] = 0;
    debugPtr = debugBuf;
    UART1_CR2 |= UART_CR2_TIEN;

    // Write to DR will start tx
    UART1_DR = *debugPtr++;
}


int main(void)
{
    // UART 115K2 baud, interrupt driven tx
    // UART1_CR1, UART_CR3 reset values are 8N1
    UART1_BRR2 = 0x0B;
    UART1_BRR1 = 0x08;
    UART1_CR2 |= UART_CR2_TEN | UART_CR2_TIEN;

    /* Set clock to full speed (16 Mhz) */
    CLK_CKDIVR = 0;

    log("Run\r\n");

    while(1) {
        // Only the first char is txed if nop is used
        nop();
        // But all chars txed if wfi is used
        // wfi();
    }
}

See your reference manual for stm8 (I use CD00218714) at chapter 12.9.1 you will see default value (after reset) of CPU condition code register it's 0x28 - this mean that just after start your mcu will work at interrupt level 3 and all software interrupt are disabled, only RESET and TRAP will workable.请参阅第 12.9.1 章的 stm8 参考手册(我使用 CD00218714),您将看到 CPU 条件代码寄存器的默认值(复位后)为 0x28 - 这意味着在启动后您的 mcu 将在中断级别 3 和所有软件下工作中断被禁用,只有 RESET 和 TRAP 可以工作。

According to program manual (I use CD00161709) instruction WFI change interrupt level to level 0 and your software interrupt of USART become workable.根据程序手册(我使用 CD00161709)指令 WFI 将中断级别更改为 0 级,并且您的 USART 软件中断变得可用。

You need to insert asm("rim");您需要插入asm("rim"); just after initialization code (after line CLK_CKDIVR = 0; ) - this will make your code workable with asm("nop");就在初始化代码之后(在CLK_CKDIVR = 0;行之后) - 这将使您的代码可用于asm("nop"); based main loop.基于主循环。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM