這幾天開始準備要要利用網絡上的資源,移植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左右。