写单片机程序大多芯片都会用到串口进行抓取信息、调试代码。那如何编写串口代码呢,各种芯片串口都大同小异,一般会用到寄存器的串口中断使能位、设置波特率位、接受中断标志位、发送中断标志位、缓存寄存器(用于发送/接受)。我在最开始写串口代码一直认为接受中断标志位、发送中断标志位是当给缓存寄存器取数据/放数据时,会将接受/发送中断标志位自动置位,并进入中断函数。或许很多朋友都和我一样开始都这样认为,其实并不是这样,接受中断标志位、发送中断标志位是在接受/发送数据的最后一位(一般共10位,起始位[1]、数据位[8]、停止位[1])后才置位,即接受/发送结束时,接受/发送中断标志位自动置位。程序中常常用while(!接受/发送中断标志位)来等待接受/发送,紧接着后面将接受/发送中断标志位清零。
如果开了串口中断,那么发送、接收数据的时候都会产生中断。一般而言,接收数据的时候才用中断,发送数据时候关掉中断直接发送。因为什么时候需要发送数据完全根据代码功能来判断,但是什么时候接收数据就不好说,如果不用中断来接收的话,只能用查询法不停循环来检测,很影响代码的实时性,尤其当要实现的功能比较多的时候,肯定得才用中断来接收串口数据,查询法是没法用的。
数据是怎么通过串口发送与接受呢
如果我们要向其他设备发送个小写字母‘a’。‘a’"这个字母对应的ASCII码是97,对应的八位二进制数则是 01100001。TX就将对应的二进制码发送出去。发送时用高电平来代表1,用低电平代表0. 那不发送数据的时候管脚就一直为高电平。
在每次发送一个字节的数据之前TX脚都会先输出一小段的低电平。来告诉对方,我要开始发送数据了,这一小段低电平便是启动位(起始位)。
如果我们发送多个字节,两个数据之间需要有个间隔,不然分不清哪个数据是哪个数据。所以每发送完一个字节的数据,TX脚就会输出一小段的高电平,这便是停止位。
下面是51单片机的串口实现代码,及其解析:
#include<reg51.h>
#include<stdio.h>
#define uchar unsigned char
#define uint unsigned int
void uart_init();
uint i = 0;
//UART发送串口数据
void UART_SendData(char dat)
{
ES=0; //关串口中断
SBUF=dat;
while(TI!=1); //等待发送成功
TI=0; //清除发送中断标志
ES=1; //开串口中断,如果不用串口接受一直关闭,初始化时就关闭;
}
//UART 发送字符串
void UART_SendString(char *s)
{
while(*s)
{
UART_SendData(*s++);//发送当前字符,一位一位的发送
}
}
//重写putchar函数
char putchar(char c)
{
UART_SendData(c);
return c;
}
void main()
{
uart_init();
while(1)
{
UART_SendString("I Love 51\r\n");
printf("i = %d\r\n",i++);
}
}
void uart_init()
{
TMOD=0x20; //定时器的工作方式2;
TH1=0xfd; //特率9600
TL1=0xfd;
TR1=1; //启动定时器1;
SM0=0; // 方式一:10位(8位数据位,1,一个起始位,1个停止位)
SM1=1;
REN=1; //先允许串口接收
EA=1; //全中断(总中断)
ES=1; // 串口中断
}
下面是PIC12LF1822的串口实现代码,及其解析:
#include <xc.h>
#include <stdio.h>
//UART 发送串口数据
void UART_SendData(char dat)
{
TXREG = dat; //Uart_Data
while(TXIF == 0); //??????
TXIF = 0;
}
//UART1 发送字符串
void UART_SendString(char *s)
{
while(*s)//检测字符串结束符
{
UART_SendData(*s++);//发送当前字符
}
}
void putch(unsigned char byte) //重定义
{
TXREG = byte; //Uart_Data
while(TXIF == 0); //等待发送
TXIF = 0;
}
void Init_Uart(void)
{
RXDTSEL = 0; //RA1->Rx
TXCKSEL = 0; //RA0->Tx
TXSTA = 0x2c; // Slave mode and Transmit enabled
RCSTA = 0x90; // Enables receiver
BAUDCON = 0x80; //Uart enabled
SPBRGH = 0;
SPBRGL = 0x19; //Baud Rate is 9600
RCIE = 1; //open Uart recive interput
TXIE = 0; //close Uart trismit interput
}
void main(void)
{
Init_Uart();
while(1)
{
UART_SendString("PIC12LF1822\r\n");
printf("hello PIC12LF1822\r\n");
}
return;
}
void interrupt ISR(void) //中断函数
{
}