c - stm8 uart tx中断问题
问题描述
我正在通过中断将 STM8S103F3 编程到 UART 上的 TX。我知道在“发送数据寄存器空中断”之后写入 DR 将启动另一个 TX,所以我的 ISR 中有这个。但它只有在我的主循环旋转等待中断时才有效。如果它在 nop 上旋转,则仅发送第一个字符 - 就好像在 ISR 中写入 DR 不会产生后续中断一样。
使用 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();
}
}
解决方案
请参阅第 12.9.1 章的 stm8 参考手册(我使用 CD00218714),您将看到 CPU 条件代码寄存器的默认值(复位后)为 0x28 - 这意味着在启动后您的 mcu 将在中断级别 3 和所有软件下工作中断被禁用,只有 RESET 和 TRAP 可以工作。
根据程序手册(我使用 CD00161709)指令 WFI 将中断级别更改为 0 级,并且您的 USART 软件中断变得可用。
您需要asm("rim");
在初始化代码之后(在 line 之后CLK_CKDIVR = 0;
)插入 - 这将使您的代码可用于asm("nop");
基于主循环的代码。
推荐阅读
- swift - Firebase createdAt - 时间戳与日期
- api - 远离相机检测的 Tenorflow 小物体
- typescript - 续集计数返回值不可分配给类型“数字”
- angular - AngularJs 无法读取未定义的属性“订阅”
- google-cloud-build - CloudBuild 作业未并行执行
- javascript - 关于偶数和奇数问题(使用递归)
- html - 即使我已经在 css 中设置了背景颜色、大小等,我的按钮也没有格式化
- python - 如何将系列附加到数据框列表中包含的数据框?
- spring - Spring Scheduler 在 DST 期间未运行
- asp.net-core-3.0 - 为什么我在注册 IHostedService 时没有实例化我的 HomeController