You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
335 lines
10 KiB
335 lines
10 KiB
2 years ago
|
/*
|
||
|
* FreeModbus Libary: BARE Port
|
||
|
* Copyright (C) 2006 Christian Walter <wolti@sil.at>
|
||
|
*
|
||
|
* 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 <FreeRTOS.h>
|
||
|
|
||
|
/* ----------------------- 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
|