51单片机 - 串口UART_发送

0> 引言


在这里插入图片描述


1


1> 通讯协议

🔗 UART 概述

一帧数据:
1

位段内容
空闲位TX保持高电平
起始位TX由高变低,保持=1bit位宽
数据为5~8位ASCII的编码数据
校验位校验方式:奇校验 / 偶校验
停止位TX由低变高,保持>=0.5bit位宽

1.1> 示波器测试

1

波特率9600;


2> 硬件组成

2.1> 串口工作模式1 (8N1)

8N1: 8位数据位, 无校验位,1位停止位;

1

发送框图:
1

发送时序:

1

1> 定时器1作,脉冲发生器;
2> 并转串 移位寄存器,作数据通路;
3> TX/RX ConTROL单元,作控制单元;

注意: UART模块内部通过SMOD 和 [/16分频] 对定时器的溢出率进行分频


2.2> 并转串-移位寄存器(74HC165)

通过74HC165芯片,了解 移位寄存器,工作本质

1
1

一个CLK移动移位;


3> 波特率发生器

通过定时器1的溢出,产生CLK方波;
STC89C516RD+ 有3个定时器, 通常,Tim1 用作串口波特率发生器, Tim2用于整个系统定时, Timer0用于其他;

3.1> 定时器1 配置

/**
 * @brief UART initialization
 * @note 8N1, 115200
 */ 
void UART_Init(void)
{
	ES = 0;					// 禁止串口中断;
	ET1 = 0;				// 禁止定时器1中断 
	RI = 0;					// 清零接收中断请求标志
	
	/* UART Config */
	SCON = 0x50;    		// 串口工作模式:8位数据位, 0101  0000
	PCON |=  0x80;			// 串口波特率加倍;1000 0000

	/* Tim1 Config */
    TMOD &= 0x0F;
    TMOD |= 0x20;			// 定时器1工作模式2:8位自动重装载
    TH1 = 0x100 - (SYS_CLK / 12 * 2 / 32 / 115200);   
    TL1 = TH1;				// 定时器1初始值
	
    TR1 = 1;				// 启动定时器1
}

3.2> 8位自动重装载

在这里插入图片描述

对SYSclk 分频后, 进行+1 计数器;
当加满溢出时, 硬件自动将TH1值装入TL1;

定时器溢出率 = SYSclk / 12 / (2 ^ 8 - N);


3.3> 初始值计算

相关概念:

定时器的溢出率 : 1S内定时器加满次数,
波特率: 1S内传输二进制bit位数;

1

11

公式总结:
串口方式1, 定时器模式8位自动重装载:

波特率 = 定时器溢出率 * ( 2 ^ SMOD / 32 ) ;

定时器溢出率 = SYSclk / 12 / (2 ^ 8 - N);
波特率 = SYSclk / 12 / (256 - N) * ( 2 ^ SMOD / 32 )

256 - N = SYSclk / 12 * (2 ^ SMOD / 32) / 波特率
N = 256 - SYSclk / 12 * (2 ^ SMOD / 32) / 波特率

以外部晶振22.1184MHz, 12T模式, 加倍计算, 产生115200波特率的N值;

N = 256 - (22118400 / 12 * 2 / 32 / 115200);  
  = 256 - 1
  = 255  //0xFF
  

11

与串口波特率计算工具的结果一样;


4> 程序设计


4.1> 发送1字节数据

轮询方式,注意先发送数据,再判断TI;

/**
 * @brief UART put one Byte
 * @c put data
 */ 
void UART_Putchar(uchar8_t c)
{
    
	
    SBUF = c;
    while(!TI) {
		/* Nothing */ ;
	}
	
    TI = 0;
	
}

4.2> 发送字符串

void bsp_uart_putstring(unsigned char *str)
{
	while (*str) {
		if (*str == '\n') {
			bsp_uart_putbyte('\r');	
		}

		bsp_uart_putbyte(*str++);
	}
}

Windows系统对于文本都是以‘\r’回车结束,再’\n’换行,所以要插入一个‘\r’;


4.3> printf重定向

用字节写的发送一个字符函数,编写库函数的putchar, 因为库函数printf调用putchar输出;

#include <stdio.h>

char putchar(char c)
{
	ES = 0;

	if (c == '\n') {
		SBUF = '\r';
		while ( !TI ) { /*  waiting */;	} 
		TI = 0;	
	}

	SBUF = c;
	while ( !TI ) { /*  waiting */;	} 
	TI = 0;
	ES = 1;	

	return 1; 
}

查看库函数
1

格式化输出方式,注意char 用 %bd;

2.2

使用printf测试数据类型,所占内存大小

1

好嘛,有了printf, 51上就可以练习C语言了;



5> 🔗视频链接

B站:视频链接

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值