• STM32使用STM32CubeMX生成文件,并实现串口打印功能。


    使用STM32CubeMX生成项目

    首先我们点击CubeMX,进入芯片选择页面,这里根据自己的开发板的芯片型号,自行选择。

    这里选择自己的芯片双击即可

    这里我们首先配置系统时钟RCC时钟是单片机运行的基础,时钟信号推动单片机内各个部分执行相应的指令。时钟系统就是CPU的脉搏,决定cpu速率,像人的心跳一样 只有有了心跳,人才能做其他的事情,而单片机有了时钟,才能够运行执行指令,才能够做其他的处理 (点灯,串口,ADC),时钟的重要性不言而喻。

    晶振选择为3种:
    Disable 这个是不用外部晶振
    Crystal/Ceramic Resontor 这个是用无源外部晶振
    BYPASS Clock Source 这个是有源外部晶振

    这里我高速时钟和低速时钟都配置成无源外部晶振,读者可以自行根据项目配置。

    这里SYS,Debug配置成Serial Wire,时钟源选择定时器4(我这是为后续移植FreeRTOS准备,所以没有选择第一个系统的)

    因为这是一个简单的串口数据显示项目,所以我没有配置其他的,单独配置一个串口1,串口中断不开,因为后续BSP移植里面会有串口中断的配置。

    然后配置时钟,只需配置HCLK,配置成72MHz即可。

     这里将自己的项目名,项目存放路径,自己选择好,然后在Toolchain/IDE选择MDK-ARM。

    这里勾选将.h和.c分开查看的按键。

    然后点击右上角生成代码,我们用CubeMX生成的项目最开始就生成了。

    修改生成的工程项目

    然后打开工程。

    这便是我们生成的项目,但是还有很多冗杂的东西,我们首先把gpio.c、usart.c这两个.c文件删除。

    我们在项目的目录下新建一个文件夹,改名为BSP。

    再将我们写好的串口配置函数直接调用。

    需要的可以自行在资源里面下载

    我们点击一个长得像品字的按钮,然后添加组BSP,再加进去bsp_usart.c文件。(这里.h文件都是看不见的,但是是存在的),然后点击ok。

    再点击魔法棒,按图中点击,更新路径

    找到路径中的BSP并加入进去。

    然后打开main.c文件,我们进行适当修改。

    我们删除usart.h,gpio.h这两个头文件,并引入bsp_usart.h这个头文件,然后删除 MX_GPIO_Init();
      MX_USART1_UART_Init(); 这两个hal库配置的串口。

    可以看见现在是0 ERROR,0 Warning。我们再来配置串口,我们在bsp_usart.c文件中可以看见,我们配置串口1是

    1. void USART1_Init(unsigned int BPS, void Tx_Over(void), void (*RxFunction)(unsigned char RX_Data))
    2. {
    3. GPIO_InitTypeDef GPIO_InitStruct = {0};
    4. //´®¿Ú1³õʼ»¯
    5. __HAL_RCC_USART1_CLK_ENABLE();
    6. __HAL_RCC_GPIOA_CLK_ENABLE();
    7. Usart_ISR.U1TXOver = Tx_Over; //·¢ËÍÍê³É»Øµ÷
    8. Usart_ISR.U1RXOperation = RxFunction; //½ÓÊÕÊý¾Ýº¯Êý
    9. GPIO_InitStruct.Pin = GPIO_PIN_9;
    10. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    11. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    12. HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    13. GPIO_InitStruct.Pin = GPIO_PIN_10;
    14. GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    15. GPIO_InitStruct.Pull = GPIO_NOPULL;
    16. HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    17. huart1.Instance = USART1;
    18. huart1.Init.BaudRate = BPS;
    19. huart1.Init.WordLength = UART_WORDLENGTH_8B;
    20. huart1.Init.StopBits = UART_STOPBITS_1;
    21. huart1.Init.Parity = UART_PARITY_NONE;
    22. huart1.Init.Mode = UART_MODE_TX_RX;
    23. huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    24. huart1.Init.OverSampling = UART_OVERSAMPLING_16;
    25. if (HAL_UART_Init(&huart1) != HAL_OK)
    26. {
    27. Error_Handler();
    28. }
    29. __HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE); //ʹÄܽÓÊÕÖжÏ
    30. //USART3 NVIC ÅäÖÃ
    31. HAL_NVIC_SetPriority(USART1_IRQn, 0, 1);
    32. HAL_NVIC_EnableIRQ(USART1_IRQn);
    33. }

    这是串口一的初始化

    但这样就好了吗,其实还没有,我们在stm32中使用printf这个函数,我们都需要对fputc这个函数进行重定义。

    1. int fputc( int ch, FILE *f )
    2. {
    3. USART_TypeDef* USARTx = USART1;
    4. while((USARTx->SR & (1<<7))==0);
    5. USARTx->DR=ch;
    6. return ch;
    7. }

    这是重定义的函数,原理是我们查看stm32f103系列的芯片手册时,可以看见数据是存入stm32的DR寄存器的,当bit=7时,我们的数据便全部发送出去了,然后我们SR寄存器是状态寄存器,我们可以判断是否有数据存入。

    我们要点击魔法棒,勾选使用MicroLIB,然后自己用的什么下载工具自行配置,不然我们的printf打印的内容还是无法在串口助手上查看。

    像这样,我们便可以下载到开发板上进行调试了,但注意不能在keil5里面在线模拟调试,因为hal库使用模拟调试会出现什么都打印不了的情况。

    下载到开发板,我们打开串口助手,就能看见我们打印的数据在串口助手上一秒一次的发送。

    到此本文结束。

  • 相关阅读:
    LeetCode-895. 最大频率栈以及HashMap的存值取值操作
    就业季学好3d建模,找对才是赚到
    STM8应用笔记3.GPIO输出 (1)
    客流人数管理新趋势:景区客流采集分析系统的功能特点
    目标检测——Faster RCNN
    Flink-CDC-快速入手(MySQL为例)
    MySQL 正则判断匹配
    纯粹的四位奇数
    快速幂实战
    iframe嵌入页面跨域通信
  • 原文地址:https://blog.csdn.net/ljt2333/article/details/133043048