51单片机串口通信以及printf调试
串行通信1.串口初始化串口工作方式波特率设置通过软件直接生成串口初始化代码2.输出到串口3.发送字符串到串口4.printf重定向到串口5.补充printf格式化输出串行通信
不知道你们写单片机程序的时候有没有烦恼,它没有想c语言的dos窗口,没有java的运行窗口,没有python的控制台,有时候想输出一条调试信息却无法做到,下面通过简单的方法,将调试信息通过51单片机的串口输出到串口。
1.串口初始化
只介绍本案例中需要使用的一些知识,串口初始化主要是选择串口工作方式和设置波特率。
串口工作方式
通过SCON寄存器中的SM0和SM1设置工作方式,REN为是否允许接收,一般设置这三个即可;
SM0 = 0;SM1 = 1; //设置工作方式2,波特率可调REN = 1; //允许接收/*或者直接对SCON整体赋值*/SCON = 0x50;
波特率设置
波特率是通过定时/计数器T1的溢出值设置的,先确定要使用的波特率,然后通过波特率求出T1的溢出值,计算出计数初值,并对T1进行初始化。
PCON = 0X00; //波特率不加倍TMOD = 0X20; //选择T1计数器工作方式2TH1 = 0XFD;TH1 = 0XFD; //设置波特率 TR1 = 1;//启动定时/计数器
通过软件直接生成串口初始化代码
可以直接使用stc的下载程序软件直接生成初始化代码
选择合适的参数,然后生成代码,例如:
波特率9600,晶振11.05926的初始化
void UartInit(void)//9600bps@11.0592MHz{PCON &= 0x7F;//波特率不倍速SCON = 0x50;//8位数据,可变波特率TMOD &= 0x0F;//清除定时器1模式位TMOD |= 0x20;//设定定时器1为8位自动重装方式TL1 = 0xFD;//设定定时初值TH1 = 0xFD;//设定定时器重装值ET1 = 0;//禁止定时器1中断TR1 = 1;//启动定时器1}
2.输出到串口
编写底层函数,输出字节信息到串口,串口通信只需要往SBUF发送缓冲寄存器中写入数据即可,然后通过查询或者中断方式对发送溢出标志位清零。
//发送一个字节数据void sendByte(unsigned char dat){SBUF = dat;//写入发送缓冲寄存器while(!TI); //等待发送完成,TI发送溢出标志位 置1TI = 0;//对溢出标志位清零}
3.发送字符串到串口
只需要将底层函数sendByte二次封装一下即可
void sendString(unsigned char *string){while(*string!='\0'){//指针的数据没到最后一位一直执行循环体sendByte(*string++); //发送指针指向的数据(字节byte)//指针自增,指向下一个数据 }}
4.printf重定向到串口
只需要重写他调用的一个底层函数即可
/***重写printf调用的putchar函数,重定向到串口输出**需要引入头文件<stdio.h>*****/char putchar(char c){//输出重定向到串口sendByte(c);return c; //返回给函数的调用者printf}
同时需要引入头文件 <stdio.h>
这样即可使用printf直接输出调试信息
5.补充printf格式化输出
和c语言中的格式输出稍微一些不同
例如打印 unsigned char 类型的数据需要使用 %bd
unsigned char dat1 = 48;printf("char-->%bd\r\n",dat1); //无符号字符型使用%bd显示十进制数
通过stc自带的串口助手就可以查看串口输出信息