【STM32串口通信】HAL库串口中断通信
目的:
1)了解串口协议和RS-232标准,以及RS232电平与TTL电平的区别
2)STM32系统给上位机(win10)连续发送“hello windows!”。win10采用“串口助手”工具接收。
3)在完成以上任务基础,继续扩展功能:当上位机给stm32发送一个字符“#”后,stm32暂停发送“hello windows!”;发送一个字符“*”后,stm32继续发送;
一、串口通讯协议和RS-232
1、简介
串口通讯协议是一种设备间常用的串行通讯方式,用于输出调试信息。它以分层的方式来理解,最基本的是把它分为物理层和协议层。物理层规定通讯系统中具有机械、电子功能部分的特性,确保原始数据在物理媒体的传输。协议层主要规定通讯逻辑,统一收发双方的数据打包、解包标准。
RS-232是一种在串口通讯中常见的物理层标准。它主要规定了信号的用途、通讯接口以及信号的电平标准。两个通讯设备的“DB9接口”之间通过串口信号线建立起连接,串口信号线中使用“RS-232标准”传输数据信号。其中接线口以针式引出信号线的称为公头,以孔式引出信号线的称为母头。通讯时,串口线中传输的信号就是使用前面讲解的RS-232标准调制的。
2、RS232电平与TTL电平的区别
从表格中不难看出,两种标准划分的逻辑电压不同。在电子电路中常使用 TTL 的电平标准,理想状态下,使用 5V 表示二进制逻辑 1,使用 0V 表示逻辑 0;而为了增加串口通讯的远距离传输及抗干扰能力,它使用-15V表示逻辑 1,+15V 表示逻辑 0
二、简单的串口通信(基于hal库)
1、项目的创建
1、配置RCC
2、时钟配置
3、SYS配置
4、串口配置
USART的相关参数配置为默认值
5、串口引脚配置
6、中断配置
至此即可生成项目,由于之前有介绍,这里就不在赘述
链接: link
2、代码实现即效果演示
1、找到int main里面的while函数,在其中写入以下代码即可
HAL_UART_Transmit(&huart1,(uint8_t*)"hello windows /r/n ",14,0xFFFF);
HAL_Delay(100);
2、效果演示
在烧入成功后,打开串口助手
效果:
三、串口中断通信
项目的创建和上面一样即可
1、代码编写
1、定义全局变量
char c;
char message[]=" hello Windows \n\r";//输出信息
char tips[]=" CommandError \n\r";//提示1
char tips1[]="Start.....\n\r";//提示2
char tips2[]="Stop......\n\r";//提示3
int flag=0;
2、中断函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
//当输入的指令为0时,发送提示并改变flag
if(c=='#'){
flag=0;
HAL_UART_Transmit(&huart1, (uint8_t *)&tips2, strlen(tips2),0xFFFF);
}
//当输入的指令为1时,发送提示并改变flag
else if(c=='*'){
flag=1;
HAL_UART_Transmit(&huart1, (uint8_t *)&tips1, strlen(tips1),0xFFFF);
}
//当输入不存在指令时,发送提示并改变flag
else {
flag=0;
HAL_UART_Transmit(&huart1, (uint8_t *)&tips, strlen(tips),0xFFFF);
}
//重新设置中断
HAL_UART_Receive_IT(&huart1, (uint8_t *)&c, 1);
}
功能:串口中断接收,以中断方式接收指定长度数据。
大致过程是,设置数据存放位置,接收数据长度,然后使能串口接收中断。
接收到数据时,会触发串口中断。
再然后,串口中断函数处理,直到接收到指定长度数据
而后关闭中断,进入中断接收回调函数,不再触发接收中断。(只触发一次中断)
3、完整代码
#include "main.h"
#include "usart.h"
#include "gpio.h"
#include <string.h>
void SystemClock_Config(void);
char c;
char message[]=" hello Windows \n\r";//输出信息
char tips[]=" CommandError \n\r";//提示1
char tips1[]="Start.....\n\r";//提示2
char tips2[]="Stop......\n\r";//提示3
int flag=0;
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
//设置接受中断
HAL_UART_Receive_IT(&huart1, (uint8_t *)&c, 1);
//当flag为1时,每2秒发送一次信息
//当flag为0时,停止
while (1)
{
if(flag==1){
//发送信息
HAL_UART_Transmit(&huart1, (uint8_t *)&message, strlen(message),0xFFFF);
//延时
HAL_Delay(2000);
}
}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
//当输入的指令为0时,发送提示并改变flag
if(c=='#'){
flag=0;
HAL_UART_Transmit(&huart1, (uint8_t *)&tips2, strlen(tips2),0xFFFF);
}
//当输入的指令为1时,发送提示并改变flag
else if(c=='*'){
flag=1;
HAL_UART_Transmit(&huart1, (uint8_t *)&tips1, strlen(tips1),0xFFFF);
}
//当输入不存在指令时,发送提示并改变flag
else {
flag=0;
HAL_UART_Transmit(&huart1, (uint8_t *)&tips, strlen(tips),0xFFFF);
}
//重新设置中断
HAL_UART_Receive_IT(&huart1, (uint8_t *)&c, 1);
}
/* USER CODE END 4 */
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
2、实验效果
还是烧入之后打开串口助手
注意有时候需要清空接受区
四、总结
串口实现了计算机外设,是我们的调试助手
只需一根传输线就可以实现双向通信,甚至还可以利用电话线进行传输,数据一位位地顺序传送,其具有通信线路简单的特点,成本较低,特别试用于远距离传输。
在调试过程中,串口可以用来查看打印信息。
可以外接各种模块。