串口通讯也是单片机应用中经常要用到,今天的实验就是利用STM8的UART资源,来进行串口通讯的实验。 实验程序的功能是以中断方式接收串口数据,然后将接收到的数据以查询方式发送到串口。程序代码如下,首先要对STM8的UART进行初始化,初始化 时要注意的是波特率寄存器的设置,当求出一个波特率的分频系数(一个16位的数)后,要将高4位和低4位写到BRR2中,而将中间的8位写到BRR1中, 并且必须是先写BRR2,再写BRR1。 同样也是利用ST的开发工具,生成一个C语言的框架,然后修改其中的main.c,同时由于需要用到中断服务,因此还要修改stm8_interrupt_vector.c。 修改后,编译连接,然后下载到开发板上,再做一根与PC机相连的线,把开发板的串口与PC机的串口连接起来,注意,2、3脚要交叉。 在PC机上运行超级终端,设置波特率为9600,然后每按下一个按键,屏幕上就显示对应的字符。 修改后的main.c和stm8_interrupt_vector.c如下: // 程序描述:初始化UART,以中断方式接收字符,以查询方式发送 // UART通讯参数:9600bps,8位数据,1位停止位,无校验 #include "STM8S207C_S.h" // 函数功能:初始化UART // 输入参数:无 // 输出参数:无 // 返 回 值:无 // 备 注:无 void UART3_Init(void) { LINUART_CR2 = 0; // 禁止UART发送和接收 LINUART_CR1 = 0; // b5 = 0,允许UART // b2 = 0,禁止校验 LINUART_CR3 = 0; // b5,b4 = 00,1个停止位 // 设置波特率,必须注意以下几点: // (1) 必须先写BRR2 // (2) BRR1存放的是分频系数的第11位到第4位, // (3) BRR2存放的是分频系数的第15位到第12位,和第3位到第0位 // 例如对于波特率位9600时,分频系数=2000000/9600=208 // 对应的十六进制数为00D0,BBR1=0D,BBR2=00 LINUART_BRR2 = 0; LINUART_BRR1 = 0x0d; // 实际的波特率分频系数为00D0(208) // 对应的波特率为2000000/208=9600 LINUART_CR2 = 0x2C; // b3 = 1,允许发送 // b2 = 1,允许接收 // b5 = 1,允许产生接收中断 } // 函数功能:从UART3发送一个字符 // 输入参数:ch -- 要发送的字符 // 输出参数:无 // 返 回 值:无 // 备 注:无 void UART3_SendChar(unsigned char ch) { while((LINUART_SR & 0x80) == 0x00); // 若发送寄存器不空,则等待 LINUART_DR = ch; // 将要发送的字符送到数据寄存器 } main() { // 首先初始化UART3 UART3_Init(); _asm("rim"); // 允许CPU全局中断 while(1) // 进入无限循环 { } } // 函数功能:UART3的接收中断服务程序 // 输入参数:无 // 输出参数:无 // 返 回 值:无 @far @interrupt void UART3_Recv_IRQHandler (void) { unsigned char ch; ch = LINUART_DR; // 读入接收到的字符 UART3_SendChar(ch); // 将字符发送出去 } /* BASIC INTERRUPT VECTOR TABLE FOR STM8 devices * Copyright (c) 2007 STMicroelectronics */ typedef void @far (*interrupt_handler_t)(void); struct interrupt_vector { unsigned char interrupt_instruction; interrupt_handler_t interrupt_handler; }; @far @interrupt void NonHandledInterrupt (void) { /* in order to detect unexpected events during development, it is recommended to set a breakpoint on the following instruction */ return; } extern void _stext(); /* startup routine */ extern @far @interrupt void UART3_Recv_IRQHandler(); struct interrupt_vector const _vectab[] = { {0x82, (interrupt_handler_t)_stext}, /* reset */ {0x82, NonHandledInterrupt}, /* trap */ {0x82, NonHandledInterrupt}, /* irq0 */ {0x82, NonHandledInterrupt}, /* irq1 */ {0x82, NonHandledInterrupt}, /* irq2 */ {0x82, NonHandledInterrupt}, /* irq3 */ {0x82, NonHandledInterrupt}, /* irq4 */ {0x82, NonHandledInterrupt}, /* irq5 */ {0x82, NonHandledInterrupt}, /* irq6 */ {0x82, NonHandledInterrupt}, /* irq7 */ {0x82, NonHandledInterrupt}, /* irq8 */ {0x82, NonHandledInterrupt}, /* irq9 */ {0x82, NonHandledInterrupt}, /* irq10 */ {0x82, NonHandledInterrupt}, /* irq11 */ {0x82, NonHandledInterrupt}, /* irq12 */ {0x82, NonHandledInterrupt}, /* irq13 */ {0x82, NonHandledInterrupt}, /* irq14 */ {0x82, NonHandledInterrupt}, /* irq15 */ {0x82, NonHandledInterrupt}, /* irq16 */ {0x82, NonHandledInterrupt}, /* irq17 */ {0x82, NonHandledInterrupt}, /* irq18 */ {0x82, NonHandledInterrupt}, /* irq19 */ {0x82, NonHandledInterrupt}, /* irq20 */ {0x82, UART3_Recv_IRQHandler}, /* irq21 */ {0x82, NonHandledInterrupt}, /* irq22 */ {0x82, NonHandledInterrupt}, /* irq23 */ {0x82, NonHandledInterrupt}, /* irq24 */ {0x82, NonHandledInterrupt}, /* irq25 */ {0x82, NonHandledInterrupt}, /* irq26 */ {0x82, NonHandledInterrupt}, /* irq27 */ {0x82, NonHandledInterrupt}, /* irq28 */ {0x82, NonHandledInterrupt}, /* irq29 */ }; |
从零开始操作STM8寄存器(风驰iCreate奉献)
【中文资料】初学STM8库函数的中文帮助软件
绝对经典的中文STM8学习手册,淘宝上学习板资料,友情大放送!
【原创教程】风驰iCreate独家开源STM8 27个例程和10多万字的pdf教程
STM8的LCD1602 4线驱动,为什么不工作
【精华资料】由零开始开发STM8
STM8S 的触摸库是如何在主程序中查询键的呢、
【精华资料】STM8的C语言编程1-14讲完整版
【精品教程】STM8系列单片机入门教程系列
STM8 第一次进中断不准【悬赏问答】
RE:【ST公益分享】STM8 -- UART