串口通信(3)printf串口输出重定向的实现及一帧一串数据的发送

 本文为博主 日月同辉,与我共生,csdn原创首发。希望看完后能对你有所帮助,不足之处请指正!一起交流学习,共同进步!

> 个人主页:@日月同辉,与我共生的博客

> 欢迎你为独创博主日月同辉,与我共生点赞❤❤❤+关注👍+收藏🌹+评论☺。

系列专栏:CSDN-单片机串口通信学习系列🎁

> 我的格言是:“尽最大努力,做最好的自己!💪

转载请提前告知博主!!!

版权声明:本文为CSDN博主「日月同辉,与我共生」的原创文章,CSDN独一份。

目录

一、波特率设置及初值计算

1.1回顾-初值公式

1.2计算初值

1.3设置波特率

二、初始化

2.1回顾-查询法&中断法

2.2初始化函数

三、发送一帧数据

3.1原理

3.2发送一帧数据函数

3.3主程序及结果展示1

四、发送字符串

4.1原理

4.2发送字符串

4.3主程序及结果展示2

五、printf串口输出重定向

5.1printf函数

5.2printf串口输出重定向函数

5.3主程序及结果展示3

一、波特率设置及初值计算

1.1回顾-初值公式

fosc:晶振频率,通常取11.0592Mhz=110592hz。本次设计单片机晶振频率设置为11.0592Mhz。

SMOD:波特率加倍位。SMOD=0时,波特率不变;SMOD=1时,波特率加倍;

波特率:通常取9600bit/s,19200bit/s等。

初值就是定时初始值TH1和定时重载值TL1。

1.2计算初值

本文设计波特率为9600bit/s。波特率为9600bit/s,串口工作方式1,初值结果为253,十六进制为0xFD。

1.3设置波特率

虚拟终端、COMPIM、虚拟串口的波特率统一设置为9600bit/s。

二、初始化

2.1回顾-查询法&中断法

查询法:TI=0时,准备发送;TI=1时,发送完成。所以while(!TI);的作用就是等待发送完成,即发送完成前,TI=0,代码执行会一直执行该语句,发送完成后,TI自动置1,该语句不再执行,开始执行下一条语句。发送完成后,要将TI清0,以便下次能正确发送。

void main()
{
	UartInit();//调用串口初始化函数
	while(1)
	{
		SBUF = '0';//发送一帧数据
		while(!TI);//等待发送完成(TI会自动置1)
		TI=0;//将TI置0
		delay(1000);//延时1s
	}
}

中断法:要写中断服务函数,当发送完成后,因TI自动置1,所以触发中断服务函数,在中断服务函数中,将TI清0,以便下次能正确发送。串口通信中断入口编号为4。

//发送数据
void main()
{
	UartInit();//调用串口初始化函数
	while(1)
	{
		SBUF=0x00;
		delay(2000);//延时2s
	}
}
//初始化看第二章2.2


//中断服务函数
void ES_timer() interrupt 4 //当TI置1时,会进入中断服务函数
{
	if(TI)
	{
		TI=0;//TI软件置0
	}
}

2.2初始化函数

查询法初始化:初始化时,要设置寄存器SCON(工作方式、是否多机通信、数据位数),REN一般要接收(置1),初值就是定时初始值TH1/定时重载值TL1,工作方式为方式1(8位异步重载),波特率可变,因为是8位数据传输,所以定时器为定时器T1工作方式为方式2。中断法设置同上。

void UartInit()		//4800bps@11.0592MHz
{
	SCON = 0x50;		//8位数据,可变波特率
	TMOD &= 0x0F;		//设置定时器模式
	TMOD |= 0x20;		//设置定时器模式
	TL1 = 0xFA;			//设置定时初始值
	TH1 = 0xFA;			//设置定时重载值
	ET1 = 0;			//禁止定时器中断
	TR1 = 1;			//定时器1开始计时
}

中断法初始化:除了跟查询法一样的设置外,还要打开总中断EA=1,串口中断开关ES=1。

void UartInit(void)		//9600bps@11.0592MHz
{
	PCON &= 0x7F;		//波特率不倍速
	SCON = 0x50;		//8位数据,可变波特率
	TMOD &= 0x0F;		//设置定时器模式
	TMOD |= 0x20;		//设置定时器模式
	TL1 = 0xFD;			//设置定时初始值
	TH1 = 0xFD;			//设置定时重载值
	ET1 = 0;			//禁止定时器中断
	ES=1;
	EA=1;
	TR1 = 1;			//定时器1开始计时
}

三、发送一帧数据

3.1原理

原理跟查询法一样。第一步:发送数据dat。第二步:等待发送完成。第三步:TI清0。

3.2发送一帧数据函数

void sendByte(unsigned char dat) //发送一帧数据功能函数
{
	SBUF=dat;
	while(!TI);
	TI=0;
}

3.3主程序及结果展示1

void main()
{
	UartInit();//调用串口初始化函数
	while(1)
	{
		sendByte(0x88);
		delay(2000);
	}
}

结果:

四、发送字符串

4.1原理

(1)数组:k常数,定义数组int a[k],a[k]存储了k个元素,数据元素类型为int,a[0]=a0,a[k-1]=a k-1,最末尾有结束符‘\0’。当代码发送到字符等于‘\0’时,说明发送字符串已经完成

(2)指针:

指针变量:int *p=&a;p是指针变量,存储有a的地址,数据类型为int*。

*和&的区别:*是解引用符,&是地址符。p存储有a的地址,所以*p会根据a的地址找到a的值,即*p=a;

而数组本质上是一个指针常量,使用下标代表每个元素的值,可以用指针代替下标,由指针代表每个元素值。a[]为一个数组,int *p=a;语句*p=a,此时指针默认指向下标0,即*p的值为a[0],语句*p++;可以让指针由原来指向下标0变为指向下标1,即此时*p=a[1]。

4.2发送字符串

void sendString(unsigned char *dat)//发送字符串函数
{
	while(*dat != '\0')
	{
		sendByte(*dat++);
	}
}

4.3主程序及结果展示2

void main()
{
	UartInit();//调用串口初始化函数
	while(1)
	{
		
		sendString("hellow world\r\n");
		delay(2000);
	}
}

结果:

五、printf串口输出重定向

5.1printf函数

printf函数大家比较陌生,这个是#include <stdio.h>里面的库函数。下图是printf函数的格式:

可以看出,不同数据类型格式不同,printf函数发送的是字符串/十进制数,大家可以收藏起来以后说不定会用到!!!

5.2printf串口输出重定向函数

char putchar(char c)
{
	sendByte(c);
	return c;
}

5.3主程序及结果展示3

void main()
{
	unsigned char dat=88;
	
	char a = 1;
    int b  = 12365;
    long c = 0x7FFFFFFF;

    unsigned char x = 'A';
    unsigned int y  = 54321;
    unsigned long z = 0x4A6F6E00;

    float f = 10.0;
    float g = 22.95;

	UartInit();//调用串口初始化函数
	while(1)
	{
		printf("hellow world\r\n");
		printf("dat=%bu\r\n",dat);
		printf ("char %bd int %d long %ld\n",a,b,c);
        printf ("Uchar %bu Uint %u Ulong %lu\n",x,y,z);
        printf ("%f != %g\n", f, g);
		delay(2000);
	}
}

结果:

unsigned char dat=88;

printf("hellow world\r\n");//发送到格式hellow world
printf("dat=%bu\r\n",dat);//发送到格式dat=88

注:printf函数发送的是十进制数/字符串。

    char a = 1;
    int b  = 12365;
    long c = 0x7FFFFFFF;

    unsigned char x = 'A';
    unsigned int y  = 54321;
    unsigned long z = 0x4A6F6E00;

    float f = 10.0;
    float g = 22.95;

    printf ("char %bd int %d long %ld\n",a,b,c);

    //格式是char 1 int 12365 long 21474(把c转成了十进制)
    printf ("Uchar %bu Uint %u Ulong %lu\n",x,y,z);

    //格式是Uchar 65 Uint 54321 Ulong 1248816640
    printf ("%f != %g\n", f, g);//格式是10.000000!=22.95

下一文将着重一帧数据的接收 ,亲爱的读者敬请期待,下一文更精彩!!!

一日不读书,胸臆无佳想。我叫不白吃,喜欢我的,可以支持我,博主名叫@日月同辉,与我共生

https://blog.csdn.net/LIN___IT?spm=1000.2115.3001.5343icon-default.png?t=N7T8https://blog.csdn.net/LIN___IT?spm=1000.2115.3001.5343

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值