|
本帖最后由 caicaptain2 于 2019-8-15 09:34 编辑
近期开始尝试HAL库,串口收发很常用,给大家分享。
主要特点:mcu是F401,使用串口2,dma发送,中断单字节接收,tim4作为modbus的数据帧判断。不用在it函数种做任何变动。
初始化部分: tim4使用update event中断,IO口/串口设置/定时器设置简略不细说。
变量:usart2_buffe[256]串口接收缓冲;usart2_single 串口接收单字节缓冲;usart2_buffer_index缓冲区数据序号指示
main函数中,加入这个:
__HAL_TIM_ENABLE_IT(&htim4,TIM_IT_UPDATE);//打开tim4的update中断。tim4的总中断在初始化时已经打开。
HAL_UART_Receive_IT(&huart2,&usart2_single,1)//打开串口接收中断。
串口DMA发送用这个:
while(huart2.gState == HAL_UART_STATE_READY)
{
HAL_GPIO_WritePin(ModbusControl_GPIO_Port,ModbusControl_Pin,GPIO_PIN_SET);//设置modbus为发送模式。半双工用这个,全双工忽略。
HAL_UART_Transmit_DMA(&huart2,发送缓冲区指针,数据长度);//使能串口发送DMA
}
回调函数部分:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) //串口接收中断回调函数
{
if (huart->Instance ==USART2 ) {
usart2_buffe[usart2_buffer_index]=usart2_single;
HAL_UART_Receive_IT(huart,&usart2_single,1); //使能串口2的接受中断,每次接收一个就中断,且进入complete回调函数
if(usart2_buffer_index==0) {
__HAL_TIM_SET_COUNTER(&htim4, 0);//此处应该计数器清零先
HAL_TIM_Base_Start(&htim4);//HAL函数方式
//__HAL_TIM_ENABLE(&htim4); 寄存器方式
}
//此处TIM4->CNT可以赋值为2ms,来满足modbus 字节之间小于1.5t延时标准。
__HAL_TIM_SET_COUNTER(&htim4, 0);
ModbusOvertime=0; //
usart2_buffer_index++; //数据超长
if(usart2_buffer_index>(USARTBUFFERSIZE-1))
{
usart2_buffer_index=0; //1-3
}
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//TIM11是FreeRTOS的时钟,为系统自动加上的。
{
/* USER CODE BEGIN Callback 0 */
if (htim->Instance == TIM4) {//TIM4的超时,判断出一帧数据结束,然后停止定时器。
__HAL_TIM_SET_COUNTER(&htim4, 0);
ModbusOvertime=1;//超时后,才可以判断一帧结束,解码。
HAL_TIM_Base_Stop(&htim4);
//__HAL_TIM_DISABLE(&htim4); //寄存器操作方式
}
/* USER CODE END Callback 0 */
if (htim->Instance == TIM11) {
HAL_IncTick();
}
/* USER CODE BEGIN Callback 1 */
/* USER CODE END Callback 1 */
}
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)//这个是收发的IO口控制,RS485半双工中使用。
{
if (huart->Instance ==USART2 ) {
HAL_GPIO_WritePin(ModbusControl_GPIO_Port,ModbusControl_Pin,GPIO_PIN_RESET);//设置modbus为接收模式。
}
}
|
评分
-
查看全部评分
|