3.4生成工程
4.代码编写
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include<stdio.h>
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart1;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
int UartDrvWrite(unsigned char *buf,unsigned short length)
{
if(NULL == buf) return -1;
if(0 == length) return -1;
if(HAL_OK != HAL_UART_Transmit(&huart1,buf,1,HAL_MAX_DELAY))
return -1;
return length;
}
int UartDrvRead(unsigned char *buf,unsigned short length)
{
if(NULL == buf) return -1;
if(0 == length) return -1;
if(HAL_OK != HAL_UART_Receive(&huart1,buf,1,HAL_MAX_DELAY))
return -1;
return length;
}
struct __FILE{
int handle;
};
FILE __stdout;
int fputc(int ch,FILE *f)
{
(void)f;
UartDrvWrite((unsigned char*)&ch,1);
return ch;
}
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
char a = 'a';
printf("%c",a);
if(1 == UartDrvRead((unsigned char*)&a,1))
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_RESET);
HAL_Delay(1000);
}
printf("%c",a);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
5.结果展示
在显示结果时,不是很方便一起录视频,所以只截图一个MobaXterm的界面。相关的软件操作放在文章最后面进行讲解。
6.代码分析
在学习串口时,我们有一点要进行注意,一定要分清楚,串口的发送方和接收方是谁,我们程序中的发送方其实是stm32单片机,接收方是电脑,不要错认为电脑是发送方,如果在一开始都分不清楚这一点,就很难搞明白串口的工作方式和方向,从而进入学习的误区。
6.1初始思路
初始思路很残暴,就是直接采用HAL_UART_Transmit和HAL_UART_Receive进行字母a的收和任意字符的收,程序一开始,就将a进行发出,然后程序一直卡在HAL_UART_Receive,等待收字符,进行led点亮,然后在对收到的字符进行回显。我们在进行仿真和正常的逻辑思维双重推理下,发现程序其实很残暴,因为当我们一直收不到字符时,程序就一直卡着不动,进行等待,现实中不会这样进行设计程序,这里只是为了学习而进行学习。
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
char a = 'a';
if(HAL_OK != HAL_UART_Transmit(&huart1,(uint8_t *)&a,1,10))
{
Error_Handler();
}
if(HAL_OK == HAL_UART_Receive(&huart1,(uint8_t *)&a,1,HAL_MAX_DELAY))
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_RESET);
HAL_Delay(1000);
}
if(HAL_OK != HAL_UART_Transmit(&huart1,(uint8_t *)&a,1,HAL_MAX_DELAY))
{
Error_Handler();
}
while (1)
{
}
}
6.2进一步
接着我们会想着自己封装一个发送和接收函数,这样让程序更加清晰明了。
#include "main.h"
UART_HandleTypeDef huart1;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
int UartDrvWrite(unsigned char *buf,unsigned short length)
{
if(NULL == buf) return -1;
if(0 == length) return -1;
if(HAL_OK != HAL_UART_Transmit(&huart1,buf,1,HAL_MAX_DELAY))
return -1;
return length;
}
int UartDrvRead(unsigned char *buf,unsigned short length)
{
if(NULL == buf) return -1;
if(0 == length) return -1;
if(HAL_OK != HAL_UART_Receive(&huart1,buf,1,HAL_MAX_DELAY))
return -1;
return length;
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
char a = 'a';
if(1 != UartDrvWrite((unsigned char*)&a,1))
{
Error_Handler();
}
if(1 == UartDrvRead((unsigned char*)&a,1))
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_RESET);
HAL_Delay(1000);
}
if(1 != UartDrvWrite((unsigned char*)&a,1))
{
Error_Handler();
}
while (1)
{
}
}
6.3最终代码
最后再加入重定向,形成最终代码。加入重定向以后,printf函数就是相当于发送函数,也就是写函数,这里也是要搞明白这个相关逻辑。
#include "main.h"
#include<stdio.h>
UART_HandleTypeDef huart1;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
int UartDrvWrite(unsigned char *buf,unsigned short length)
{
if(NULL == buf) return -1;
if(0 == length) return -1;
if(HAL_OK != HAL_UART_Transmit(&huart1,buf,1,HAL_MAX_DELAY))
return -1;
return length;
}
int UartDrvRead(unsigned char *buf,unsigned short length)
{
if(NULL == buf) return -1;
if(0 == length) return -1;
if(HAL_OK != HAL_UART_Receive(&huart1,buf,1,HAL_MAX_DELAY))
return -1;
return length;
}
struct __FILE{
int handle;
};
FILE __stdout;
int fputc(int ch,FILE *f)
{
(void)f;
UartDrvWrite((unsigned char*)&ch,1);
return ch;
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
char a = 'a';
printf("%c",a);
if(1 == UartDrvRead((unsigned char*)&a,1))
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_RESET);
HAL_Delay(1000);
}
printf("%c",a);
while (1)
{
}
}
7.函数分析
7.1HAL_UART_Receive
判断是否忙–>锁住–>标记接收忙–>获取tick计数–>赋值RxXferCount有多少数据要接收–>每次从DR内获取一个Byte存在pData指向的空间
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
uint16_t *tmp;
## 最后
**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**
**深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。**
**因此收集整理了一份《2024年嵌入式&物联网开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
![img](https://img-blog.csdnimg.cn/img_convert/18dd9bd91ce0ee1b32cd1eeeb8293c49.png)
![img](https://img-blog.csdnimg.cn/img_convert/181e69e1c888f11fe4154cf637b6c5da.jpeg)
![img](https://img-blog.csdnimg.cn/img_convert/229d365feb08ec57745baaa63031141e.png)
![img](https://img-blog.csdnimg.cn/img_convert/0b57edf5036c523491ac0702369429b0.png)
![img](https://img-blog.csdnimg.cn/img_convert/26e5bf4027347aee7eae74fdb466f7a7.png)
![img](https://img-blog.csdnimg.cn/img_convert/6d08959a9411de1e711041c0a8972735.png)
![](https://img-blog.csdnimg.cn/img_convert/fe29856b63f85080fdc9c0aaae3b9fdc.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!**
[**如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618654289)
**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**!!
5901530)]
[外链图片转存中...(img-3ohIR3ig-1715575901531)]
[外链图片转存中...(img-Kz6UQngW-1715575901532)]
[外链图片转存中...(img-BRtBTXFX-1715575901533)]
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!**
[**如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618654289)
**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**!!