完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
串口通信
注:时间戳和白字黑字两个比较鸡肋的功能是没有的 3、STM32串口通信 前言: STM32串口介绍 串行通信是单片机与外部设备或其他计算机交换信息的一个方式, 数据一位一位的按顺序传送, 其优点是只需要一条传输线, 协议简单, 但是缺点就是传送速度较慢。 串口是单片机上非常便捷的一个工具, 当写程序需要调试的时候, 它可以很方便的提供调试方法, 只要在一些关键代码执行的地方, 通过串口给串口调试助手发送相关信息, 就可以使我们很方便的查看代码在这个位置的执行情况。 下面看一下我所使用的单片机上串口的原理图接线 外部的发送端TXD就是单片机串口的接收端USART_RX, 外部接收端RXD就是单片机串口的发送端USART_TX USART就是Universal Synchronous/Asynchronous Receiver/Transmitter(通用同步/异步串行接收/发送器)的缩写 就是一个全双工的收发器CH340是串口芯片, 当单片机用一根USB串口线接到电脑的时候, TXD就是指电脑通过数据线给单片机发送数据,对应单片机要接收数据, 因此单片机对应引脚就是RX(接收) (电脑端发送) TXD -----> USART_RX(单片机接收)单片机上用跳线帽将PA10, PA9和USART1_RX, USART1_TX连接起来了, 所以我们只需对PA10, PA9配置即可 PA9就是USART1_TX, PA10就是USART1_RX 跳线帽将PA9和CH340的RXD, PA10和CH340的TXD连接起来了 下面开始Cube配置+IAR编程 3.1 操作简介 使用异步串口通信, 分别以轮询、中断、DMA方式使用串口发送数据进行与电脑的通信。 电脑端使用串口调试助手接收单片机发送的信息 3.2 轮询方式串口通信 单片机会不断查询串口对应引脚, 有通信需求就进行处理, 这样比较浪费CPU资源, 前面在中断里面也讲过, 中断可以很好地弥补这个。 这里先演示轮询方式 Step1 : Cube配置 新建一个工程, 同时也加入LED和按键等对应引脚的配置, 用以配合串口通信
关于异步传送(Asynchronous)和同步传送(Synchronous) 1、同步发送 : 发送方和接收方以同一个时钟源控制发送和接收。 就是当发送方发出数据后, 等待接收方发回响应后才发下一个数据包。 2、异步传送 : 数据在线路上是以一个字为单位传送, 各个字符之间可以是接连传送也可以是间断传送, 这完全由发送方根据需要来决定。 发送和接收双方分别用自己的饿时钟源来控制发送和接收。 也就是说发送方发出数据后, 不等待接收方回应, 随时可以发送下一组数据
第一节补充: 按键操作(CubeMX加HAL库学STM32系列)
但是, 单片机要使用这个就要把他打印的方向改一下, 不是打印在电脑的命令行中, 而是打印到串口里面,传输到串口调试助手. 因此我们需要重定向printf函数。 重定向后我们要将调试信息打印到USART1中, 需要对printf所依赖的打印函数fputc()重定向 在usart.c里面添加如下代码 #include #include "stdio.h" /****************************************************************** *@brief Retargets the C library printf function to the USART. *@param None *@retval None ******************************************************************/ #ifdef __GNUC__ #define PUTCHAR_PROTOTYPE int _io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif /* __GNUC__*/ PUTCHAR_PROTOTYPE { HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF); return ch; } 上面除了重定向的代码, 还包含了一个标准库头函数, 最好加上这个, 因为printf函数就是这个库里面的, 不加的话有时候会出错或者警告Tips : HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF); 是通过串口1传输一个字符, ch为字符的地址, 0XFFFF表示超时时间 下面是这个函数的定义 Go to definition进入 stm32f4xx_hal_uart.c可以看这个函数定义 关于串口通信的其他接口函数都可以在 stm32f4xx_hal_uart.h文件里面找到声明 在stm32f4xx_hal_uart.h里面的一些串口通信相关功能函数
// 在while(1)里面循环扫描, 判断读取的按键引脚状态 // 判断 WK_UP 按键是否按下 if (HAL_GPIO_ReadPin(WKUP_GPIO_Port, WKUP_Pin) == GPIO_PIN_SET) { HAL_Delay(10); // 延时10ms, 做一个软件的消抖, 防止因抖动而检测到按键按下 if (HAL_GPIO_ReadPin(WKUP_GPIO_Port, WKUP_Pin) == GPIO_PIN_SET) // 如果确实按下了 { while(HAL_GPIO_ReadPin(WKUP_GPIO_Port, WKUP_Pin) == GPIO_PIN_SET); // 松手检测, 即当这个按键松开后才进行下面的程序, 下同 printf("key WK_UP was pressed rn"); } } // 判断 KEY0 按键是否按下 if (HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin) == GPIO_PIN_RESET) { HAL_Delay(10); // 延时10ms, 软件消抖 if (HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin) == GPIO_PIN_RESET) { while(HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin) == GPIO_PIN_RESET); printf("key KEY0 was pressed rn"); } } /* USER CODE END 3 */
改错 在主函数里面包含一个标准库即可 #include "stdio.h" 注 : 养成习惯, 代码写在规范的位置 因为 printf是C语言标准库里面的函数, 所以我们要使用就最好加上这个, 当然不加也没事, 主要是加上比较完美 0 error(s) , 0 warning(s)(4) 实际效果展示 操作简介 : 通过中断方式传输指定长度的数据 Step1 : CubeMX配置 与3.1的轮询方式配置几乎都是一样的, 只需要在串口的配置里面勾选使能串口中断即可 先退出IAR或者Keil, 然后更改配置再重新Generate Code Step2 : IAR或Keil编程 (1) 在main函数外面先增加两个数组用作数据缓冲区 /* USER CODE BEGIN PV */ uint8_t TX_Buffer[] = "n********** 中断方式串口通信 *********n输入十个字符 (注:一个汉字为两个字符大小)n"; uint8_t Rx_Buffer[20]; //接收数据20个字符 /* USER CODE END PV */ (2) main函数里面 添加个人代码, 以及通过中断将 TX_Buffer[]里面的数据发送到串口调试助手 并在while(1) 里面不断等待接收数据 while(1) 外面的是我们通过单片机打印到串口的, while(1)里面接收中断发送的数据并显示 /* USER CODE BEGIN 2 */ printf("串口通信正常...nn"); printf("****** Kevin_8_Lee 2020-1-2 ********n"); printf(" ***** ***** *n"); printf(" ********* ********* *n"); printf(" ************* ************* *n"); printf(" ***************************** *n"); printf(" ***************************** *n"); printf(" ***************************** *n"); printf(" *************************** *n"); printf(" *********************** *n"); printf(" ******************* *n"); printf(" *************** *n"); printf(" *********** *n"); printf(" ******* *n"); printf(" *** *n"); printf(" * *n"); printf("*************************************n"); HAL_Delay(500); // 延时500ms, 等待下一步操作 /* 通过中断发送指定长度数据 */ HAL_UART_Transmit_IT(&huart1, (uint8_t *)TX_Buffer, sizeof(TX_Buffer)); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ HAL_UART_Receive_IT(&huart1, (uint8_t *)Rx_Buffer, 10); } /* USER CODE END 3 */ (3) 再回到main函数外面 在main函数外面添加中断回调函数 /* USER CODE BEGIN 4 */ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { /* Prevent unused argument(s) compilation warning */ UNUSED(huart); printf("n您发送的消息为: "); // 提示你所发送的信息 HAL_UART_Transmit(&huart1, (uint8_t *)Rx_Buffer, 10,0xFFFF); } /* USER CODE END 4 */ 中断回调函数把串口调试助手发送的数据再发送给串口调试助手, 然后显示出来 (4) 编译下载, 看一下实际效果 关于上述所用到的函数, 大家可以Go to definition去看一下这个函数的定义, 不懂得英文直接谷歌翻译, 问题不大 最后, 常见问题解决办法
|
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1777 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1621 浏览 1 评论
1080 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
728 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1678 浏览 2 评论
1937浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
731浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
570浏览 3评论
595浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
553浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 00:49 , Processed in 0.928614 second(s), Total 77, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号