1. 0x前缀表示16进制
后缀u代表无符号数
后缀l代表长型数
这三个标记都不区分大小写
于是整个0x1ul代表的含义是无符号长整数常量1,用16进制表示
2. 外部时钟不起振,切换成内部时钟有用:
硬件问题
怀疑是否负载电容过大了,因布线原因可能的杂散电容使得就有一定的负载电容。
3.MAX3232是电平转换芯片,MAX3232芯片的主要作用是实现TTL电平和RS-232电平之间的转换,提供强大的信号驱动能力和低功耗特性,适用于各种串行通信应用场景。
TTL(Transistor-Transistor Logic)电平信号通常使用的是逻辑电平,即高电平为5V,低电平为0V。
RS-232电平信号则使用负逻辑电平,即高电平为+5V至+15V,低电平为-5V至-15V。
TTL电平主要和用于短距离、高速度的数字逻辑通信应用
RS-232通信则广泛应用于长距离、低速率的工业控制和通信设备之间。
USART是单片机串口,使用RS-232电平,电脑COM口也是一种串口,使用RS-232电平。
但单片机内部是TTL电平,所以需要MAX3232进行电平转换。
而正常的单片机内部没有MAX3232,单片机串口和电脑通信就要使用 USB-TTL 接口。
4. extern 是告诉编译器 这个变量在我这,别人用的时候来我这找,只是声明,还需将这个变量定义在 .c 文件中。
当别的模块需要使用这个变量时:
- 包含定义了的头文件
- 使用extern int a;声明下,让编译器去别的地方找这个变量。
.c
int a;
.h
extern int a;
报多重定义的错就是这不注意。
5.环形缓冲区
好难!
6.串口发送
hex方式: 123456 -> 0x12 0x34 0x56
ascii方式:123456 -> 对应的ascii码值
//以 ASCII码 形式发送给 123456
HAL_UART_Transmit(&huart1,(uint8_t*)"123456\r\n",10,1000);
//以16进制 发送 12 AF 3D
uint8_t length;
uint8_t data[3] = {0x12,0xAF,0x3D};
length = sizeof(data) / sizeof(data[0]);
HAL_UART_Transmit(&huart1,data,length,1000);
//0C 22 38 因为你没有指定类型,默认是10进制,但是是 16进制发送
HAL_UART_Transmit(&huart1,(uint8_t[]){12,34,56},3,100);
//16进制发送 AF
HAL_UART_Transmit(&huart1,(uint8_t[]){0xAF},1,100);
//ASCII发送 AF
HAL_UART_Transmit(&huart1,(uint8_t*)"AF",2,100);
可以看到以什么形式发送关键并不在于 uint8_t ,这只是代表数据在内存中的存储形式 。关键在于数据的形式。
ASCII码发送使用 “”
16进制 发送使用 {0x__}16进制数组发送
接收到什么类型的数据取决于发送的数据是什么类型
7.MDK 可以不使用硬件进行仿真,关键在要使用内部时钟,不然会卡在晶振起振那。
参考:利用Keil进行STM32F103RB芯片软件仿真模拟方法 - 哔哩哔哩 (bilibili.com)
如果需要使用串口,也可以用虚拟串口助手选择两个串口对,然后在keil 调试命令界面输入:
MODE COM1 115200,0,8,1
ASSIGN COM1 <S1IN> S1OUT
就可以使用串口通信了。
8. 不勾选可以让编译速度加快,但是不能便捷的查看代码( go to definition)
9.HAL_UART_Receive_IT() 返回 HAL_BUSY 检查下是否对串口进行了初始化。
10.在proteus仿真中,使用VPDS虚拟串口,在proteus中选择了com1,那对应的就是com2接受数据。