/* * FreeModbus Libary: BARE Port * Copyright (C) 2006 Christian Walter * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * File: $Id$ */ /* ----------------------- Platform includes --------------------------------*/ #include "port.h" /* ----------------------- Modbus includes ----------------------------------*/ #include "mb.h" #include "mbport.h" #include "main.h" #include "tim.h" // #include "base.h" /* ----------------------- static functions ---------------------------------*/ static void prvvTIMERExpiredISR(void); /* ----------------------- variables ---------------------------------*/ #ifndef FREERTOS_USED /* ----------------------- variables ---------------------------------*/ // extern TIM_HandleTypeDef htim7; TIM_HandleTypeDef *pModbusTim = &htim7; volatile uint16_t timeout = 0; volatile uint16_t counter = 0; volatile uint16_t dd = 0; /* ----------------------- Start implementation -----------------------------*/ BOOL xMBPortTimersInit(USHORT usTim1Timerout50us) { TIM_MasterConfigTypeDef sMasterConfig; pModbusTim->Instance = TIM7; pModbusTim->Init.Prescaler = ( 2 * 50 * HAL_RCC_GetPCLK1Freq() / 1000000) - 1; pModbusTim->Init.CounterMode = TIM_COUNTERMODE_UP; pModbusTim->Init.Period = usTim1Timerout50us - 1; pModbusTim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; timeout = usTim1Timerout50us; // 赋值timeout 多少个周期 if (HAL_TIM_Base_Init(pModbusTim) != HAL_OK) { return FALSE; } sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(pModbusTim, &sMasterConfig) != HAL_OK) { return FALSE; } /* 避免一开始进入了超时中断,关闭中断,停止计数,归0 */ __HAL_TIM_CLEAR_FLAG( &htim7, TIM_FLAG_UPDATE ); // 先清除一下定时器的中断标记,防止使能中断后直接触发中断 __HAL_TIM_CLEAR_IT( &htim7, TIM_IT_UPDATE ); __HAL_TIM_ENABLE_IT(&htim7, TIM_IT_UPDATE); // 使能定时器更新中断 // __HAL_TIM_DISABLE(&htim7); // __HAL_TIM_CLEAR_FLAG( pModbusTim, TIM_FLAG_UPDATE ); // __HAL_TIM_SET_COUNTER( pModbusTim, 0 ); // __HAL_TIM_DISABLE_IT( pModbusTim,TIM_FLAG_UPDATE ); // HAL_TIM_Base_Stop( pModbusTim ); // __HAL_TIM_SET_COUNTER( pModbusTim, 0 ); // HAL_TIM_Base_Stop_IT( pModbusTim ); return TRUE; } inline void vMBPortTimersEnable() { /* Enable the timer with the timeout passed to xMBPortTimersInit( ) */ counter = 0; // 启用定时器时, // HAL_TIM_Base_Start_IT(pModbusTim); // __HAL_TIM_SET_COUNTER(pModbusTim, 0); // 清空计数器 // __HAL_TIM_SET_COUNTER( pModbusTim, 0 ); // __HAL_TIM_ENABLE_IT( pModbusTim,TIM_FLAG_UPDATE ); // HAL_TIM_Base_Start( pModbusTim ); __HAL_TIM_CLEAR_IT(&htim7,TIM_IT_UPDATE); __HAL_TIM_ENABLE_IT(&htim7,TIM_IT_UPDATE); __HAL_TIM_SET_COUNTER(&htim7,0); __HAL_TIM_ENABLE(&htim7); // __HAL_TIM_SET_COUNTER(&htim7, 0); // 清空计数器 // __HAL_TIM_ENABLE(&htim7); // 使能定时器 } inline void vMBPortTimersDisable() { /* Disable any pending timers. */ // HAL_TIM_Base_Stop_IT(pModbusTim); // __HAL_TIM_SET_COUNTER(pModbusTim, 0); // 清空计数器 // __HAL_TIM_SET_COUNTER( pModbusTim, 0 ); // __HAL_TIM_DISABLE_IT( pModbusTim,TIM_FLAG_UPDATE ); // HAL_TIM_Base_Stop( pModbusTim ); // __HAL_TIM_SET_COUNTER( pModbusTim, 0 ); __HAL_TIM_DISABLE(&htim7); __HAL_TIM_SET_COUNTER(&htim7,0); __HAL_TIM_DISABLE_IT(&htim7,TIM_IT_UPDATE); __HAL_TIM_CLEAR_IT(&htim7,TIM_IT_UPDATE); // __HAL_TIM_DISABLE(&htim7); // 禁能定时器 } /* Create an ISR which is called whenever the timer has expired. This function * must then call pxMBPortCBTimerExpired( ) to notify the protocol stack that * the timer has expired. */ static void prvvTIMERExpiredISR(void) { (void)pxMBPortCBTimerExpired(); } void TIM7_IRQHandler(void) { if(__HAL_TIM_GET_FLAG(&htim7, TIM_FLAG_UPDATE)) // 更新中断标记被置位 { // __HAL_TIM_CLEAR_FLAG(&htim7, TIM_FLAG_UPDATE); // 清除中断标记 // __HAL_TIM_CLEAR_IT(&htim7,TIM_IT_UPDATE); // __HAL_TIM_SET_COUNTER(&htim7, 0); dd++; prvvTIMERExpiredISR(); // 通知modbus3.5个字符等待时间到 } HAL_TIM_IRQHandler( &htim7 ); } #else #include /* ----------------------- static functions ---------------------------------*/ osTimerId_t modbusTimerHandle; const osTimerAttr_t modbusTimer_attributes = { .name = "modbusTimer" }; volatile uint32_t timer_ticks = 0; static void prvvTIMERExpiredISR(void); static void timer_timeout_ind(TIM_HandleTypeDef *xTimer); /* ----------------------- Start implementation -----------------------------*/ BOOL xMBPortTimersInit(USHORT usTim1Timerout50us) { /* Freertos can't create timer in isr! 预先创建定时器? 先初始化好? So,I use hardware timer here! req=1Mhz */ timer_ticks = (50 * usTim1Timerout50us) / (1000 * 1000 / configTICK_RATE_HZ) + 1; modbusTimerHandle = osTimerNew( timer_timeout_ind, osTimerPeriodic, NULL, &modbusTimer_attributes); // modbusTimerHandle = xTimerCreate( // "Slave timer", // (50 * usTim1Timerout50us) / (1000 * 1000 / configTICK_RATE_HZ) + 1, // pdFALSE, (void *)2, timer_timeout_ind); if (modbusTimerHandle == NULL) return FALSE; // osTimerStart( modbusTimerHandle, (50 * usTim1Timerout50us) / (1000 * 1000 / configTICK_RATE_HZ) + 1); return TRUE; } void vMBPortTimersEnable() { osTimerStart( modbusTimerHandle, timer_ticks); // if (IS_IRQ()) { // xTimerStartFromISR((TimerHandle_t)slave_timer, 0); // } else { // xTimerStart((TimerHandle_t)slave_timer, 0); // } } void vMBPortTimersDisable() { osTimerStop(modbusTimerHandle); // if (IS_IRQ()) { // xTimerStopFromISR((TimerHandle_t)slave_timer, 0); // } else { // xTimerStop((TimerHandle_t)slave_timer, 0); // } } void prvvTIMERExpiredISR(void) { (void)pxMBPortCBTimerExpired(); } static void timer_timeout_ind(TIM_HandleTypeDef *xTimer) { prvvTIMERExpiredISR(); } #endif #if 0 /* ----------------------- Start implementation -----------------------------*/ BOOL xMBPortTimersInit(USHORT usTim1Timerout50us) { TIM_MasterConfigTypeDef sMasterConfig; pModbusTim->Instance = TIM7; pModbusTim->Init.Prescaler = ( 2 * 50 * HAL_RCC_GetPCLK1Freq() / 1000000) - 1; pModbusTim->Init.CounterMode = TIM_COUNTERMODE_UP; pModbusTim->Init.Period = usTim1Timerout50us - 1; pModbusTim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; timeout = usTim1Timerout50us; // 赋值timeout 多少个周期 if (HAL_TIM_Base_Init(pModbusTim) != HAL_OK) { return FALSE; } sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(pModbusTim, &sMasterConfig) != HAL_OK) { return FALSE; } /* 避免一开始进入了超时中断,关闭中断,停止计数,归0 */ __HAL_TIM_CLEAR_FLAG( &htim7, TIM_FLAG_UPDATE ); // 先清除一下定时器的中断标记,防止使能中断后直接触发中断 __HAL_TIM_CLEAR_IT( &htim7, TIM_IT_UPDATE ); __HAL_TIM_ENABLE_IT(&htim7, TIM_IT_UPDATE); // 使能定时器更新中断 // __HAL_TIM_DISABLE(&htim7); // __HAL_TIM_CLEAR_FLAG( pModbusTim, TIM_FLAG_UPDATE ); // __HAL_TIM_SET_COUNTER( pModbusTim, 0 ); // __HAL_TIM_DISABLE_IT( pModbusTim,TIM_FLAG_UPDATE ); // HAL_TIM_Base_Stop( pModbusTim ); // __HAL_TIM_SET_COUNTER( pModbusTim, 0 ); // HAL_TIM_Base_Stop_IT( pModbusTim ); return TRUE; } inline void vMBPortTimersEnable() { /* Enable the timer with the timeout passed to xMBPortTimersInit( ) */ counter = 0; // 启用定时器时, // HAL_TIM_Base_Start_IT(pModbusTim); // __HAL_TIM_SET_COUNTER(pModbusTim, 0); // 清空计数器 // __HAL_TIM_SET_COUNTER( pModbusTim, 0 ); // __HAL_TIM_ENABLE_IT( pModbusTim,TIM_FLAG_UPDATE ); // HAL_TIM_Base_Start( pModbusTim ); __HAL_TIM_CLEAR_IT(&htim7,TIM_IT_UPDATE); __HAL_TIM_ENABLE_IT(&htim7,TIM_IT_UPDATE); __HAL_TIM_SET_COUNTER(&htim7,0); __HAL_TIM_ENABLE(&htim7); // __HAL_TIM_SET_COUNTER(&htim7, 0); // 清空计数器 // __HAL_TIM_ENABLE(&htim7); // 使能定时器 } inline void vMBPortTimersDisable() { /* Disable any pending timers. */ // HAL_TIM_Base_Stop_IT(pModbusTim); // __HAL_TIM_SET_COUNTER(pModbusTim, 0); // 清空计数器 // __HAL_TIM_SET_COUNTER( pModbusTim, 0 ); // __HAL_TIM_DISABLE_IT( pModbusTim,TIM_FLAG_UPDATE ); // HAL_TIM_Base_Stop( pModbusTim ); // __HAL_TIM_SET_COUNTER( pModbusTim, 0 ); __HAL_TIM_DISABLE(&htim7); __HAL_TIM_SET_COUNTER(&htim7,0); __HAL_TIM_DISABLE_IT(&htim7,TIM_IT_UPDATE); __HAL_TIM_CLEAR_IT(&htim7,TIM_IT_UPDATE); // __HAL_TIM_DISABLE(&htim7); // 禁能定时器 } /* Create an ISR which is called whenever the timer has expired. This function * must then call pxMBPortCBTimerExpired( ) to notify the protocol stack that * the timer has expired. */ static void prvvTIMERExpiredISR(void) { (void)pxMBPortCBTimerExpired(); } void TIM7_IRQHandler(void) { if(__HAL_TIM_GET_FLAG(&htim7, TIM_FLAG_UPDATE)) // 更新中断标记被置位 { // __HAL_TIM_CLEAR_FLAG(&htim7, TIM_FLAG_UPDATE); // 清除中断标记 // __HAL_TIM_CLEAR_IT(&htim7,TIM_IT_UPDATE); // __HAL_TIM_SET_COUNTER(&htim7, 0); prvvTIMERExpiredISR(); // 通知modbus3.5个字符等待时间到 } HAL_TIM_IRQHandler( &htim7 ); } #endif