单片机中的串口通信解析

       写单片机程序大多芯片都会用到串口进行抓取信息、调试代码。那如何编写串口代码呢,各种芯片串口都大同小异,一般会用到寄存器的串口中断使能位、设置波特率位、接受中断标志位、发送中断标志位、缓存寄存器(用于发送/接受)。我在最开始写串口代码一直认为接受中断标志位、发送中断标志位是当给缓存寄存器取数据/放数据时,会将接受/发送中断标志位自动置位,并进入中断函数。或许很多朋友都和我一样开始都这样认为,其实并不是这样,接受中断标志位、发送中断标志位是在接受/发送数据的最后一位(一般共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)       //中断函数 
{ 
   
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值