串口数据发送与接收问题
配置好串口,无法打印问题
问题原因:没有勾选 “微库”
解决方法:勾选微库,重新编译,下载;
串口打印数据不正确
波特率错误:
检查单片机的时钟配置是否正确
外部晶振时钟大小;倍频后是否是72MHz;
使用寄存器时,波特率计算错误;
串口波特率计算问题
-
寄存器配置的时候,波特率的计算
计算公式与方法:
算法1:
根据公式,算出
USARTDIV
;取分频值的整数部分:
Mantissa
取分频值的小数部分:
Fraction
;向上取整;将两个数合并,放入寄存器中;
u16 Mantissa = 0;
u16 Fraction = 0;
float USARTDIV = 0;
USARTDIV = 72000000.0/16/brr;
Mantissa = (u16)USARTDIV;
Fraction = (u16)((USARTDIV - Mantissa)*16 + 0.5);
USART1->BRR = Mantissa<<4 | Fraction; //将值放入寄存器中
算法2:
小数的 二进制 存储形式:
如:19.625 19:10011 0.625 = 0.625 = 1*2-1 + 0*2-2 + 1*2-3 = 101
0.625 * 2 = 1.250 取整 1
0.250 * 2 = 0.5 取整0
0.5 * 2 = 1.0 取整1
0.0 * 2 = 0
所以说:9600
需要的 USARTDIV = 72000000 / (16 * BRR) = 468.75
对应的二进制存储形式:1 1101 0100.11
与 寄存器(
USART1->BRR
)的值 就差 左移4位;将
1 1101 0100.11 << 4
=0001 1101 0100 1100
(位数不够就补0)所以
USART1->BRR
= USARTDIV * 16 = 72000000 / (16 * BRR) *16 =72000000.0/BRR
USART1->BRR = 72000000.0/brr;
//是因为二进制的存储格式导致的;
串口使用printf
方法:编写 fputc 函数
- 包含头文件
#include ”stdio.h“
- 编写 fputc 函数
编写 fputc 函数
printf 是如何工作的
printf(“1234”);
输出到屏幕的时候,是调用 fputc 将字符一个 一个 输出到屏幕上; 就等于 fputc(‘1’); fputc(‘2’); fputc(‘3’); fputc(‘4’);
所以想要将数据 输出到 串口助手:只需要将 字符 利用 串口 发送出去;
根据函数声明格式,写出函数原型
函数编写,就是将数据 从串口发送出去;
fputc 需要有一个返回值,就返回 c;
printf函数的使用
printf 是格式化 控制输出到 设备上;
在这的 printf 是将 数据 输出到串口(助手)上;
串口助手数据的发送与接收
通过串口,每次发送和接收的数据都是8位;
如果发送16进制的数,要发送两个,一个16进制是4个位;
数据接收
数据接收 显示形式
数据的内容不变,只是数据的显示方式改变;
-
字符型显示
通过 串口 发送过来的 数据;都是二进制的0和1;
数据可以输是字符型数据,可以是整数;(数据本身是0和1)
在串口助手中 会将数据的形式 以字符型数据显示
如果说发送的数据是 整数65;串口助手以字符型的方式显示为 A
-
16进制显示
从串口发送过来的数据,将数据的显示方式改为16进制;
如果发送的是 字符 ‘A’,对应的整数是 ”65“;对应的16进制数为 ”41“(串口助手16进制显示)
数据发送
数据的发送形式:
-
字符型
1个字符型数据 是 8位,每次发送数据是一个字符一个字符发送的;
字符发送的时候,MCU接收到的数据是 对应字符的二进制数;
整数1 != 字符型数据 ‘1’,比较的时候,要格外注意数据的格式
-
16进制
发送16进制的数据 每次要发送 2个,如果发送的数据不够,MCU的接收中断不会触发;
如果发送的数据太多,MCU每次接收2个字节的数据,要保证数据能够不丢失;