我使用的是stm8s103k3,32脚单片机,这个使用手册上说了UART1,UART2,UART3。但是引脚的功能图上只有UART1,并且你打开 stm8s103k.h的头文件,里面也只有UART1寄存器的定义说明。所以我认为只有UART1。既然有这个功能,那就用吧,我以为直接可以连接到电脑的串口(COM1),就可以使用了,其实不可以。单片机即使写着提供UART通讯功能,也要连接MAX232转接芯片,我就在这里耽误了许多时间。
1、使用stm8s103上的串口和计算机com口通许的硬件连接:
2、软件设置
(1)发送数据配置
1)编程UART_CR1的M位来定义字长。
2)在UART_CR3中编程停止位的位数。
3)按下列顺序编写波特率寄存器选择要求的波特率。
a)UART_BRR2
b)UART_BRR1
4)设置UART_CR2中的TEN位来使能发送
5)把要发送的数据写进UART_DR寄存器
main.c程序如下:
#include "stm8s103k.h"
void UART1_Init(void)
{
UART1_CR2=0x00;//使发送禁用TEN=0;
UART1_CR1=0x00;//设置M字长,8位数据位
UART1_CR3=0x00;//1位停止位
UART1_BRR2=0x00;//00-0d:9600(fcpu=fmaster=2MHz)
UART1_BRR1=0x0d;//00-1a:4800; 01-34:2400
UART1_CR2=0x08;
}
main()
{
//fmaster=fcpu=2MHz
CLK_ECKR=0x00;
CLK_ICKR=0x01;
CLK_CMSR=0xe1;
CLK_SWR=0xe1;
CLK_CKDIVR=0x18;
UART1_Init();
while (1)
{
unsigned char i;
while(!(UART1_SR & 0x80));//发送寄存器数据是否转移完
UART1_CR2=0x00;//a处
UART1_DR=0xB6;//要发送的数据
UART1_CR2=0x08;//b处
while((UART1_SR & 0x40) ==0);//发送是否完成
}
}
上面的代码是我反复实验过的,如果不加a和b处代码,则接收的数据不稳定,比如发送5,接收到的数据的串口多次开闭,则接收的数据可能是0xB6,或0x67,或0x3B.
(2)接收数据
1)编程UART_CR1的M位来定义字长。
2)在UART_CR3中编程停止位的位数。
3)按下列顺序编写波特率寄存器选择要求的波特率。
a)UART_BRR2
b)UART_BRR1
4)设置UART_CR2中的REN位来使能接收
5)读UART_DR寄存器
a)查询:查询SR中标志位RXNE (读数据寄存器非空)
b)中断:需使能CR2中的RIEN(接收中断使能)
标志位查询方式:
初始化:
void UART1_Init(void)
{
UART1_CR1 = 0x00; //8bit
UART1_CR3 = 0x00;//1 stop bit
UART1_BRR2 = 0x01;
UART1_BRR1 = 0x1A;//4800 baud rate
UART1_CR2 = 0x04;//enable REN
}
Main()函数:
while (!(UART1_SR & 0x20));//Loop until the UART1 Receive Data Register is not empty
RxBuffer = UART1_DR; //Store the received byte in RxBuffer
中断方式:
初始化:
void UART1_Init(void)
{
UART1_CR1 = 0x00; //8bit
UART1_CR3 = 0x00;//1 stop bit
UART1_BRR2 = 0x01;
UART1_BRR1 = 0x1A;//4800 baud rate
UART1_CR2 = 0x24;//enable REN and RIEN
}
UART1接收中断函数:
@far @interrupt void UART1_RX_IRQHandler (void)
{
RxBuffer = UART1_DR; //Store the received byte in RxBuffer
return;
}
UART1接收中断向量(设置中断向量,即将中断服务程序的入口填写到中断向量表中)
struct interrupt_vector const _vectab[] =
{
……
{0x82, UART1_RX_IRQHandler},
……
}
(3)特别注意波特率的计算设置方式
波特率通过配置16位除法器UART_DIV来设置