国外扁平化风格网站,建立门户网站,网站带后台模板,郑州便民网#【软件STM32cubeIDE下H73xx配置串口uart1中断接收/DMA收发HAL库简单数据解析-基础样例】 1、前言2、实验器件3-1、普通收发中断接收实验第一步#xff1a;代码调试-基本配置#xff08;1#xff09;基本配置#xff08;3#xff09;时钟配置#xff08;4#xff09;保存… #【软件STM32cubeIDE下H73xx配置串口uart1中断接收/DMA收发HAL库简单数据解析-基础样例】 1、前言2、实验器件3-1、普通收发中断接收实验第一步代码调试-基本配置1基本配置3时钟配置4保存后就可以生成代码 第二步加入prinf打印1不重复造轮子打印相关连接2加入代码片段注意第四步要放到main里运行3代码测试 第三步加入接收代码1加入初始化配置2加入回调函数部分3加入到中断内 第四步实验验证 3-2、DMA收发实验第一步加入DMA初始化第二步加入DMA相关数组第三步加入回调函数第四步加入到中断函数内第四步简单数据解析功能1加入接收部分代码2加入处理部分代码3测试代码 4、代码连接5、注意细节1总是多个字符或者多个其它字符。2复制函数的使用。3逻辑调试与测试。4十进制的1与十六进制0x31。5不同串口工具有些信息不显示。6数据解析注意7初始化顺序不对不运行8回调函数写的有问题只返回一个字符9在网上找到样例进行测试没有成功 总结 1、前言
最近有段时间没有调试STM32了想着H743调试串口1也不能老师吃灰也遇到了问题即使最简单的功能一些细节也是非常重要的保持初学者之心是非常重要的同时也算做记录对于初学者会有帮助另外因为之前做过很多相关实验遇到问题基本轻车熟路了体现了记录的好处。
2、实验器件
软件环境STM32cubeIDE 1.8.0 硬件环境STM32H743xx正点原子阿波罗开发板 下载模块ST-link下载器 下载器 串口模块串口转换器 可用开发板上232模块代替
3-1、普通收发中断接收实验
第一步代码调试-基本配置
1基本配置
新建stm32项目先配置(下载口)和(时钟口)如下图
###q 2uart1以及DMA相关配置 uart1配置稍微复杂点但是配置串口多了熟悉了其实也就知道了分为几个步骤。 0先锁定自己需要引脚记得F4默认是FA9FA10但是H7不是我们想使用特定引脚的话需要选择引脚然后再选择uart1
1配置异步通信与开启中断使能这个时候uart1锁定的引脚就会变成绿色没选好之前是黄色的。 这里需要注意的是在自己实际操作生成代码时发现并没有生成中断函数所以最好在中断上再点下。
2配置DMA这部分直接添加就好都是默认的也不需要改什么。
3配置串口的波特率相关设置改成你需要的波特率一般也只改波特率其它不用动。 3时钟配置
也就是外部时钟配置之前F4用的是168MF1是72MH7一般是480M,配置如下。
4保存后就可以生成代码
建议先保存然后生成代码否则直接生成代码可能导致软件崩掉之前遇到过。 在这里插入图片描述
第二步加入prinf打印
1不重复造轮子打印相关连接
具体打印方式之前就写过所以不要重复造轮子之前看文章将代码复制过来。 文章连接# 关于软件stm32cubeIDE下配置printf重定向无法输出问题-解决方式之一
2加入代码片段注意第四步要放到main里运行
另外注意自己测试发现不能使用如下定义的方式。
//第三步定义输出函数printf
#define printf(...) HAL_UART_Transmit_DMA((UART_HandleTypeDef * )huart3, (uint8_t *)u_buf,\sprintf((char *)u_buf,__VA_ARGS__));需要使用以下方式并且需要加入换行符号 \n
printf(“\r\n star \r\n\r\n”); //起来之后输出一条语句 printf(“\r\n star \r\n\r\n”); //起来之后输出一条语句 printf(“\r\n star \r\n\r\n”); //起来之后输出一条语句 //第一步添加库
#include string.h
#include stdint.h
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes *//* USER CODE END Includes */
//第二步定义数组
uint8_t u_buf[64];/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
//第三步定义输出函数printf
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
//STM32cubeIDE下
PUTCHAR_PROTOTYPE
{HAL_UART_Transmit(huart1 , (uint8_t *)ch, 1,0x200);return ch;
}//keil下 //没在keil下尝试过 一直使用软件stm32cubeIDE没有取keil验证
//UART_HandleTypeDef huart1; //UART句柄
int fputc(int ch,FILE *f)
{HAL_UART_Transmit(huart1,(uint8_t*)ch,1,0xffff);return ch;
}/* USER CODE END PTD *///第四步打印输出printf(\r\n star \r\n\r\n); //起来之后输出一条语句HAL_Delay(1000);
3代码测试
随便输出些什么进行打印测试在网上找个串口上位机工具然后连接后串口转USB工具对应引脚就可以进行测了。 第四步代码放在主函数这里没有截图上位机串口数据打印可以放置的位置指示下下图已经做完实验的一个截图开始中断时还没有加入printf这点请熟知有疑问可以看代码或评论。
第三步加入接收代码
1加入初始化配置
具体代码见下边连接这里放置图片展示代码内容。
2加入回调函数部分
触发发送与接收都会回调函数我们这次就简单些收到什么就发送什么。 uint8_t aRxBuffer[1];
void UART_RxCpltCallback(UART_HandleTypeDef *huart)
{static uint32_t rxIndex 0;if(huart-Instance USART1){HAL_UART_Transmit(huart1, (uint8_t *)aRxBuffer, 1,0xFFFF);HAL_UART_Receive_IT(huart1, (uint8_t *)aRxBuffer, 1);}} 3加入到中断内
这点还是挺重要在中断函数内加入回调函数不加入相应功能无法实现。
第四步实验验证
1发送 2中断接收 3-2、DMA收发实验
因为上述步骤相关配置已经完成了我们不需要再重新配置直接使用即可。
第一步加入DMA初始化
__HAL_UART_ENABLE_IT(huart1, UART_IT_IDLE);//开启空闲中断/*.虽然我们使用的CubeMx来配置DMA* 但只是配置DMA模式为串口到内存* 所以还需要在程序中进一步指定* DMA具体搬运到内存的哪一个位置中* 我们建立一个数组用以存放DMA搬运的串口数据* 并使用HAL_UART_Receive_DMA()函数来配置*/HAL_UART_Receive_DMA(huart1, (uint8_t*)UART1_ReceBuf, UART1_Buf_LEN); 第二步加入DMA相关数组
/* USER CODE BEGIN PTD */
//第二步定义数组
uint8_t u_buf[64];
#define UART1_Buf_LEN 100uint8_t UART1_SendBuf[UART1_Buf_LEN];uint8_t UART1_ReceBuf[UART1_Buf_LEN];
/* USER CODE END PTD */
第三步加入回调函数
/* USER CODE BEGIN PFP */uint8_t aRxBuffer[1];
//void UART_RxCpltCallback(UART_HandleTypeDef *huart)
//{
// static uint32_t rxIndex 0;
//
// if(huart-Instance USART1)
// {
//
// HAL_UART_Transmit(huart1, (uint8_t *)aRxBuffer, 1,0xFFFF);
// HAL_UART_Receive_IT(huart1, (uint8_t *)aRxBuffer, 1);
//
// }
//
//
//
//}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)//发送完成回调函数
{}//采用DMA空闲串口中断模式 貌似不会回调到这里
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//接收完成回调函数
{}
/* USER CODE END 0 */uint8_t UART1_ReceBuf_deal_with_data[5];
void USAR_UART_IDLECallback(UART_HandleTypeDef *huart)
{//(1)HAL_UART_DMAStop(huart1); //停止本次DMA传输 需要使用DMA发送则需要关掉 如果使用的阻塞方式HAL_UART_Transmit发送请使用本行
HAL_UART_Transmit(huart1,(uint8_t*)UART1_ReceBuf,3,0x200);//阻塞方式发送 使用时需要关闭DMA模式 阻塞发送没有问题收啥 发啥
//数据头正确了再赋值
if(UART1_ReceBuf[0]0x31 UART1_ReceBuf[1]0x32)
{// 目标 源地址 数据量memcpy(UART1_ReceBuf_deal_with_data,UART1_ReceBuf,3);}memset(UART1_ReceBuf,0,UART1_Buf_LEN); //清零接收缓冲区// data_length 0;
HAL_UART_Receive_DMA(huart1, (uint8_t*)UART1_ReceBuf, UART1_Buf_LEN); //重启开始DMA传输 每次255字节数据}void USER_UART_IRQHandler(UART_HandleTypeDef *huart)
{if( huart-Instance USART1){if(RESET ! __HAL_UART_GET_FLAG(huart1, UART_FLAG_IDLE)) //判断是否是空闲中断{__HAL_UART_CLEAR_IDLEFLAG(huart1); //清楚空闲中断标志否则会一直不断进入中断USAR_UART_IDLECallback(huart); //调用中断处理函数}}
}/* USER CODE END PFP */第四步加入到中断函数内
void USART1_IRQHandler(void)
{/* USER CODE BEGIN USART1_IRQn 0 *//* USER CODE END USART1_IRQn 0 */HAL_UART_IRQHandler(huart1);/* USER CODE BEGIN USART1_IRQn 1 */USER_UART_IRQHandler(huart1);/* USER CODE END USART1_IRQn 1 */
} 第四步简单数据解析功能
1加入接收部分代码
我们收到什么数据就发出什么数据因为在回调函数里不能再用DMA发送了但可以堵塞发出。 2加入处理部分代码
我们将数据收到后如果数据对了我们只是将数据复制一份处理不在回调内做以免拖慢回调。
3测试代码
这里这里发放出成功接收并解析代码处理后发送出来就是如果接收到数据“123”那么返回数据“ABC”。
4、代码连接
1中断接收
代码链接https://download.csdn.net/download/qq_22146161/88500425
2DMA收发
代码链接https://download.csdn.net/download/qq_22146161/88500428
5、注意细节
1总是多个字符或者多个其它字符。
实际测试中发现总会多个0x0D数字不知道哪里来的多次检查后发现其实之前有发送因为进入空闲中断后停止了造成这种奇特现象。 原因点如下发现有奇怪数据时候一定看看有没其它地方输出。
2复制函数的使用。
调试解析时候我甚至将收到数据打印出来了但是就是无法触发发送才发现复制函数数组赋值那块弄错了还是需要注意的。
3逻辑调试与测试。
在我们不清楚的情况或者要测试逻辑时候可以让其将数据打印出来了帮助我们定位错的原因。如下图我们不知道收到什么是数据时候可以让其直接发回来帮助我们判断甚至复制完数据后成没成功也可以打印出来。 4十进制的1与十六进制0x31。
我这里代码有时候说“123”有时候又说0x31,0x32,0x33,其实这是他们进制表示不同一个是十进制一个是十六进制比如十进制的1等同于十六进制0x31跟ascii码对照表有关系。
5不同串口工具有些信息不显示。
不同上位机串口工具在使用的时候有差异的如果不切换到16进制进行显示我也不会发现十六进制的0x0D后来发现这个其实是换行符‘\n’。
6数据解析注意
开始自己看之前的文章的时候没主要就发了数据“12”发现不回检查后才知道数据为12的时候只复制不在while进行发送这点给忘了。 如下错误为只输入了“12”
7初始化顺序不对不运行
需要将DMA初始化放在uart前
8回调函数写的有问题只返回一个字符 9在网上找到样例进行测试没有成功 总结
再次调试相同东西再简单东西也有细节值得记录吧~~~。