这几天开始准备要要利用网络上的资源,移植modbus master的library。CSDN以及Amos的论坛上都有例子。但是我想移植的例子,却是基于STM32的标准库。初略的想想,应该不算难。于是动手开始移植。但是有一个功能,却卡住了。
在Modbus里,判定帧结束,是利用时间的。这个时间,和波特率是息息相关的。一般是3.5个byte的时间。这个一般是使用一个专用的定时器来实现的。但是这个定时器,在每次接收完一个字符之后,开始运行,但是却无需周期性运行,并且该定时器,要求的精度较高,一般采用us级的分辨率。
由于参考的例子,是采用标准库写的,无法照抄,因此,只能自己写了。测试的方法大致上如下:
1. 等待某个按键按下
2. 将另一个IO口置高,并且开启timer17(看17比较简单)
3.等待按键释放
4. 在对应的定时器中断里,将置高的IO口置低。
5. 通过测量IO口的高电平持续时间,来判定程序是否执行成功。
目前利用的是STM32G070的开发板,stm32 cube配置如下:
1. Timer17,主频是48MHz,48分频,因此分辨率为1uS
并开启全局中断
主程序基本如下:
main()
{
......
while (1)
{
/* USER CODE END WHILE */
while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_SET);
htim17.Instance->CNT = 0;
HAL_TIM_Base_Start(&htim17);
Delay = htim17.Instance->CNT;
Delay = Delay + 1000; //延时1000个计数值
htim17.Instance->CCR1 = Delay;
htim17.Instance->SR &= ~TIM_IT_CC1;
htim17.Instance->DIER |= TIM_IT_CC1;
while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_RESET);
/* USER CODE BEGIN 3 */
}
......
}
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM17)
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_RESET);
htim17.Instance->SR &= ~TIM_IT_CC1;
HAL_TIM_Base_Stop(htim);
}
}
其余的代码,基本上STM32cube基本上都完成了,直接略过即可。但是实际上,我不太喜欢ST的HAL库,繁琐,有些基本操作,还不如直接操作寄存器呢。如下图是示波器抓出来的波形。我在代码里的延时量是1000个计数值CMP=(CNT+1000),因此高电平时间,也应该在1000us左右。