这里以蓝桥杯嵌入式竞赛板 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 */
}