keil RTE HAL库 STM32CubeMX 串口收发

一、引言

在上一篇文章中,曾经聊过为啥要研究keil RTE,因外想用用keil内置的RTX操作系统。在研究keil RTE中,没有找到对应串口的例程,更奇怪的是,选择USART库的时候依赖库竟然有DMA,记得正点原子的STM32串口例程里面没有用到DMA。感谢社会,有万能的度娘,由HAL库找到CubeMX。下载,安装。

二、STM32CubeMX 创建串口项目

(1)选择和我手头板子一致的芯片STM32F407ZG ,双击进入下一步

(2)connectivity部分USART1, MODE选中Asynchronous,Configuration使能全局中断,其他选择默认设置

(3)System Core部分需要设置较多

   (3.1)sys保持默认数值

    

   (3.2)RCC 部分HSE 选择外部晶振

  

  (3.3)NVIC的NVIC ,选择中断群组2bit,串口为2,3,systick为3,3;代码生成只选择systick和usart1

  

   

(4)clock设置部分,

让系统主频为168M,外设时钟变成最大,没有警告(划线为需要修改的部分,主频要和你的硬件一致)。

(5)Project manage部分。

根据你的编译器选择和其他一些设置。完成后点左上角GENERATE CODE

三、代码分析和简单输出

(1)改错?

打开代码发现中断分组不对,改正(不能完全靠代码生成工具):

改正,保持和设置一致。

  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);

对HAL_InitTick函数,改正如下:

 HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 3U);

(2)简单串口输出(阻塞发送和接收)

在while(1)部分添加下属代码:

  while (1)
  {
    /* USER CODE END WHILE */
		HAL_Delay(5000);
		HAL_UART_Transmit(&huart1,"hello\r\n",sizeof("hello\r\n"),100);//阻塞发送
    /* USER CODE BEGIN 3 */
  }

系统输出如下:

从上面可以看出。该函数可以正常输出ASCII为0的字符。

该函数为阻塞发送函数,其中100为100ms。类似的阻塞接收并回传的函数如下:

if(HAL_UART_Receive(&huart1,buff,10,1000)==HAL_OK) //阻塞接收,10为接收的字符数量
		HAL_UART_Transmit(&huart1,buff,10,100);

其中buff为接收缓冲区。可定义如下:

(3)无阻塞发送和接收。

无阻塞发送函数(中断发送)比较简单,直接调用下属函数即可:

HAL_UART_Transmit_IT(huart,Txbuff,sizeof(Txbuff));

对于无阻塞接收(中断接收)比较麻烦。

首先需要重新实现接收回调函数HAL_UART_RxCpltCallback,简单的示例如下:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if(huart->Instance ==USART1)
    {
        flag=HAL_UART_Receive_IT(&huart1,Rxbuff,sizeof(Rxbuff));
    }
}

flag为标志位,可通过此标志位判断系统是否完成接收。需要注意的是,此函数内部不能放阻塞发送函数,否则会造成系统卡死。

(4)对比整点原子的例程

回想正点原子的串口例程,好像是中断接收,阻塞发送。但在CubeMx当中并没有看到这部分代码。研究起见。在串口中断处理函数中加入一个全局遍历,每进入1次加1。数据接收成功后输出此全局变量数值,并对接收字符串输出回显(输出均为非中断形式)。结果如下:

从上面可以看出,i的数值大的离谱。即发送,接收等几乎所有的串口事件都会触发串口中断。

资本家果然心怀不良,想让我换更快更贵的芯片。要不把CubeMX卸了???

猜你喜欢

转载自blog.csdn.net/zzlwl/article/details/115431728