STM32串口发送不定长数据【利用定时器 简单易懂】

本文介绍了如何在STM32G431RBT6嵌入式系统中设置串口波特率、定时器分频,计算数据发送时间,并利用中断处理串口接收数据,以实现简单的字符识别功能。
摘要由CSDN通过智能技术生成

这里以蓝桥杯嵌入式竞赛板 STM32G431RBT6作为演示【主频为80MHz】

首先设置串口USART1波特率为9600

随后随便设置一个定时器的分频系数PSC为8000-1

在默认为8位数据位,1位停止位,无奇偶校验的前提下,我们做一个简单的计算:

1bit起始位+8bit数据位+1bit停止位=10bit

波特率为9600bit/s 即1s传输9600bit 即1bit=(1/9600)s

则 10bit的发送时长 = 10 * (1/9600) ≈ 1.04ms

由于分频系数为8000-1

可以得出每(PSC/主频)= 1CNT

即 1CNT = (8000/80000000)= 0.1ms

则 15CNT = 1.5ms 【略大于上面的1.04ms】

核心逻辑:

从上面计算可知,串口每发送一个数据需要大概1.04ms左右【再怎么离谱也不会偏差到1.5ms去】

因此我们只需要判断如果CNT的值大于15了,即计时已经超过了1.5ms,则可以理解为数据已经传输完毕,我们再做收尾工作即可。

核心代码:

中断回调函数:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance==USART1)
	{
		TIM4->CNT=0;
		rec_flag = 1;
		RxBuff[Count] = Receice_Data[0];
		Count++;
		
		HAL_UART_Receive_IT(huart,Receice_Data,1);
	}
}

自定义的处理串口接收数据函数:

void Uart_Receive(void)
{
	if(rec_flag==1)
	{
		if(TIM4->CNT>15)
		{
			if(RxBuff[0]=='l'&&RxBuff[1]=='a'&&RxBuff[2]=='n')
			{
				sprintf(str,"lan\r\n");
				HAL_UART_Transmit(&huart1,str,strlen(str),50);
			}else if(RxBuff[0]=='q'&&RxBuff[1]=='i'&&RxBuff[2]=='a'&&RxBuff[3]=='o')
			{
				sprintf(str,"qiao\r\n");
				HAL_UART_Transmit(&huart1,str,strlen(str),50);				
			}
			Count=0;
            for(int i=0;i<Count;i++)
                RxBuff[i]=0;
			rec_flag=0;
		}
	}
}

主函数main():

uint8_t RxBuff[30];
uint8_t Receice_Data[10];
uint16_t Count=0;
uint16_t rec_flag=0;	//判断是否正在接收数据

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();
  MX_TIM4_Init();
  /* USER CODE BEGIN 2 */
  HAL_TIM_Base_Start(&htim4);    //开启定时器4 需要自己定义
  
  HAL_UART_Receive_IT(&huart1,Receice_Data,1);    //开启串口接收中断 需要自己定义
  
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {	  
	  Uart_Receive();

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值