学习理解STM32的串口通信,中断以及I2C的使用。
应用:使用中断和串口通通信获取按键值发送出来并显示到数码管上。使用I2C 将获取到的按键值保存到内存中。
串口通信
计算机的CPU与外部设备之间的信息交换,以及计算机与计算机之间的信息交换过程称为通信。
- 并行通信
数据字节的各位同时传送的通信方式。并行通信的优点是数据传送速度快,缺点是占用的传输线条数多,适用于近距离通信。 - 串行通信(Serial Communication):
数据字节的各位一位(bit)一位地依次传送的通信方式。串行通信的速度慢,但占用的传输线条数少,适用于远距离的数据传送。
这里我们讲串口通信
- 串口通讯协议分为物理层和协议层。
物理层规定通讯系统中具有机械、电子功能部分的特性,确保原始数据在物理媒体的传输。
协议层主要规定通讯逻辑,统一收发双方的数据打包、解包标准。
- STM32有3-5个的全双工的异步串行通信USART( 通用同步异步收发器USART)接口
USART的功能是通过操作相应寄存器实现的,数据寄存器,控制寄存器,控制寄存器等等。
有两个引脚TX:发送数据输出引脚。
RX:接收数据输入引脚。
常用库函数
//查询模式(blocking mode阻塞模式)调用这个函数并在等待时间内一直等待操作完成。
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
//中断模式(non- blocking mode)
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
//DMA模式
HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
//中断服务函数
void HAL_UART_IRQHandler(UART_HandleTypeDef *huart);
//中断回调函数
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);
void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart);
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart);
串口接收包括查询模式和中断模式
若单片机作为主机(主动发起通信任务)与其他从机双向通信:
根据任务,查询方式发送、查询方式接收或中断方式接收。
若单片机作为从机与其他主机机双向通信:
中断方式接收,查询方式发送(在接收中断程序中发送)。
STM32 CubeMx实现
- 查看原理图可知 A9 为数据发送引脚 A10为数据接收引脚 对应的UART1
- 使用CubeMx配置
引脚配置
PA9 配置 GPIO mode:Alternate Function push pull
PA10配置 GPIO mode:input mode
初始化UART1
配置模式:异步
配置参数:
波特率,115200bps
字长,8
奇偶校验,无
停止位,1
中断设置
USART global interrupt:使能
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WTGEidB1-1581689856542)(https://gitee.com/nie_hen/test/raw/master/小书匠/1567758987267.png)]
在System core 中NVIC下
设置中断优先级 主优先级1 次优先级0 (可不设)
生成工程
填写工程 名字 位置 ,使用IDE ,然后生成工程。
编写代码
查询发送 代码
在main.c 中主函数里 添加 发送代码
HAL_UART_Transmit(&huart1,connctt,15,500);
上面的receive_str 要在前面声明
uint8_t connctt[15]=“hello world”;
上面 发送函数里面参数,第一个为使用中断地址,第二个要发送的数组首地址,第三个发送字符串长度,第四个timeout (超过那个时间没法送成功,就会报错)
如果需要连续发送的到 while循环中,进行发送,加上延时,不然会一直连续发送。
查询接收代码
HAL_UART_Receive(&huart1,receive,15,500);
和查询发送一样 需要对receive进行声明,uint8_t receive[15];
参数也都一样
中断接收代码
/定义变量
uint8_t aRxBuffer;
//开启中断接收
HAL_UART_Receive_IT(&huart1,(uint8_t *)&aRxBuffer,1);
中断回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
HAL_UART_Transmit(&huart1,(uint8_t ))&aRxBuffer,1,0xffff); //为验证进入这个函数,把接收到的数据通过串口发送出去
HAL_UART_Receive_IT(&huart1,(uint8_t ))&aRxBuffer,1); //重新打开串口中断
}
注意中断接收每次接收必须要定长 如果接受到的数据是4个,而函数参数接受5个,那么中断接受不到结束的信号会一直等直到timeout。(查询方式的不需要)
编译
选择要使用的发送方式 和接收方式 写入代码 。
编译 传入hex文件
打开串口工具 (下面所使用到的安装包我都放到了个人网盘上,下载链接
打开串口后 从板子执行发送的字符串就会显示到上面,下面可以进行手动发送
(板子不在身边… 没法发测试图了… )
综合应用
综合应用放到另一篇文章上
使用串口通信将按键值发送出来 ,并使用I2C将按键值保存