Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PHPmihuan
rt-thread
提交
2a14e407
R
rt-thread
项目概览
PHPmihuan
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
2a14e407
编写于
2月 05, 2015
作者:
armink_ztl
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[modbus]port modbus master and slave by rtt device framework.
上级
d8bbb5f1
变更
11
展开全部
隐藏空白更改
内联
并排
Showing
11 changed file
with
1081 addition
and
703 deletion
+1081
-703
components/net/freemodbus-v1.6.0/port/port.c
components/net/freemodbus-v1.6.0/port/port.c
+7
-8
components/net/freemodbus-v1.6.0/port/port.h
components/net/freemodbus-v1.6.0/port/port.h
+4
-10
components/net/freemodbus-v1.6.0/port/portevent.c
components/net/freemodbus-v1.6.0/port/portevent.c
+24
-14
components/net/freemodbus-v1.6.0/port/portevent_m.c
components/net/freemodbus-v1.6.0/port/portevent_m.c
+192
-14
components/net/freemodbus-v1.6.0/port/portserial.c
components/net/freemodbus-v1.6.0/port/portserial.c
+155
-122
components/net/freemodbus-v1.6.0/port/portserial_m.c
components/net/freemodbus-v1.6.0/port/portserial_m.c
+154
-121
components/net/freemodbus-v1.6.0/port/porttimer.c
components/net/freemodbus-v1.6.0/port/porttimer.c
+14
-58
components/net/freemodbus-v1.6.0/port/porttimer_m.c
components/net/freemodbus-v1.6.0/port/porttimer_m.c
+35
-85
components/net/freemodbus-v1.6.0/port/user_mb_app.c
components/net/freemodbus-v1.6.0/port/user_mb_app.c
+175
-238
components/net/freemodbus-v1.6.0/port/user_mb_app.h
components/net/freemodbus-v1.6.0/port/user_mb_app.h
+27
-33
components/net/freemodbus-v1.6.0/port/user_mb_app_m.c
components/net/freemodbus-v1.6.0/port/user_mb_app_m.c
+294
-0
未找到文件。
components/net/freemodbus-v1.6.0/port/port.c
浏览文件 @
2a14e407
/*
* FreeModbus Libary:
LPC214X
Port
* Copyright (C) 20
07 Tiago Prado Lone <tiago@maxwellbohr.com.br
>
* FreeModbus Libary:
RT-Thread
Port
* Copyright (C) 20
13 Armink <armink.ztl@gmail.com
>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
...
...
@@ -16,7 +16,7 @@
* 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: port
.c,v 1.1 2007/04/24 23:15:18 wolti Exp
$
* File: $Id: port
event.c,v 1.60 2015/02/01 9:18:05 Armink
$
*/
/* ----------------------- System includes --------------------------------*/
...
...
@@ -24,16 +24,15 @@
/* ----------------------- Modbus includes ----------------------------------*/
#include "port.h"
/* ----------------------- Variables ----------------------------------------*/
static
rt_base_t
level
;
/* ----------------------- Start implementation -----------------------------*/
void
EnterCriticalSection
(
void
)
{
//关闭全局中断
__disable_irq
();
level
=
rt_hw_interrupt_disable
();
}
void
ExitCriticalSection
(
void
)
{
//开启全局中断
__enable_irq
();
rt_hw_interrupt_enable
(
level
);
}
components/net/freemodbus-v1.6.0/port/port.h
浏览文件 @
2a14e407
/*
* FreeModbus Libary: BARE Port
* Copyright (C) 20
06 Christian Walter <wolti@sil.at
>
* Copyright (C) 20
13 Armink <armink.ztl@gmail.com
>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
...
...
@@ -34,18 +34,9 @@
#define PR_BEGIN_EXTERN_C extern "C" {
#define PR_END_EXTERN_C }
//TODO 暂时先写B13引脚,等组网测试时再确认
#define SLAVE_RS485_SEND_MODE GPIO_SetBits(GPIOB,GPIO_Pin_13)
#define SLAVE_RS485_RECEIVE_MODE GPIO_ResetBits(GPIOB,GPIO_Pin_13)
#define MASTER_RS485_SEND_MODE GPIO_SetBits(GPIOB,GPIO_Pin_13)
#define MASTER_RS485_RECEIVE_MODE GPIO_ResetBits(GPIOB,GPIO_Pin_13)
#define ENTER_CRITICAL_SECTION() EnterCriticalSection()
#define EXIT_CRITICAL_SECTION() ExitCriticalSection()
void
EnterCriticalSection
(
void
);
void
ExitCriticalSection
(
void
);
typedef
uint8_t
BOOL
;
typedef
unsigned
char
UCHAR
;
...
...
@@ -65,4 +56,7 @@ typedef int32_t LONG;
#define FALSE 0
#endif
void
EnterCriticalSection
(
void
);
void
ExitCriticalSection
(
void
);
#endif
components/net/freemodbus-v1.6.0/port/portevent.c
浏览文件 @
2a14e407
/*
* FreeModbus Libary:
STM32
Port
* FreeModbus Libary:
RT-Thread
Port
* Copyright (C) 2013 Armink <armink.ztl@gmail.com>
*
* This library is free software; you can redistribute it and/or
...
...
@@ -24,35 +24,45 @@
#include "mbport.h"
/* ----------------------- Variables ----------------------------------------*/
static
eMBEventType
eQueuedEvent
;
static
BOOL
xEventInQueue
;
static
struct
rt_event
xSlaveOsEvent
;
/* ----------------------- Start implementation -----------------------------*/
BOOL
xMBPortEventInit
(
void
)
{
xEventInQueue
=
FALSE
;
rt_event_init
(
&
xSlaveOsEvent
,
"slave event"
,
RT_IPC_FLAG_PRIO
)
;
return
TRUE
;
}
BOOL
xMBPortEventPost
(
eMBEventType
eEvent
)
{
xEventInQueue
=
TRUE
;
eQueuedEvent
=
eEvent
;
rt_event_send
(
&
xSlaveOsEvent
,
eEvent
);
return
TRUE
;
}
BOOL
xMBPortEventGet
(
eMBEventType
*
eEvent
)
{
BOOL
xEventHappened
=
FALSE
;
if
(
xEventInQueue
)
rt_uint32_t
recvedEvent
;
/* waiting forever OS event */
rt_event_recv
(
&
xSlaveOsEvent
,
EV_READY
|
EV_FRAME_RECEIVED
|
EV_EXECUTE
|
EV_FRAME_SENT
,
RT_EVENT_FLAG_OR
|
RT_EVENT_FLAG_CLEAR
,
RT_WAITING_FOREVER
,
&
recvedEvent
);
switch
(
recvedEvent
)
{
*
eEvent
=
eQueuedEvent
;
xEventInQueue
=
FALSE
;
xEventHappened
=
TRUE
;
case
EV_READY
:
*
eEvent
=
EV_READY
;
break
;
case
EV_FRAME_RECEIVED
:
*
eEvent
=
EV_FRAME_RECEIVED
;
break
;
case
EV_EXECUTE
:
*
eEvent
=
EV_EXECUTE
;
break
;
case
EV_FRAME_SENT
:
*
eEvent
=
EV_FRAME_SENT
;
break
;
}
return
xEventHappened
;
return
TRUE
;
}
components/net/freemodbus-v1.6.0/port/portevent_m.c
浏览文件 @
2a14e407
/*
* FreeModbus Libary:
STM32
Port
* FreeModbus Libary:
RT-Thread
Port
* Copyright (C) 2013 Armink <armink.ztl@gmail.com>
*
* This library is free software; you can redistribute it and/or
...
...
@@ -21,41 +21,219 @@
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mb_m.h"
#include "mbport.h"
#include "port.h"
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
/* ----------------------- Defines ------------------------------------------*/
/* ----------------------- Variables ----------------------------------------*/
static
eMBMasterEventType
eMasterQueuedEvent
;
static
BOOL
xMasterEventInQueue
;
static
struct
rt_semaphore
xMasterRunRes
;
static
struct
rt_event
xMasterOsEvent
;
/* ----------------------- Start implementation -----------------------------*/
BOOL
xMBMasterPortEventInit
(
void
)
{
xMasterEventInQueue
=
FALSE
;
rt_event_init
(
&
xMasterOsEvent
,
"master event"
,
RT_IPC_FLAG_PRIO
)
;
return
TRUE
;
}
BOOL
xMBMasterPortEventPost
(
eMBMasterEventType
eEvent
)
{
xMasterEventInQueue
=
TRUE
;
eMasterQueuedEvent
=
eEvent
;
rt_event_send
(
&
xMasterOsEvent
,
eEvent
);
return
TRUE
;
}
BOOL
xMBMasterPortEventGet
(
eMBMasterEventType
*
eEvent
)
{
BOOL
xEventHappened
=
FALSE
;
rt_uint32_t
recvedEvent
;
/* waiting forever OS event */
rt_event_recv
(
&
xMasterOsEvent
,
EV_MASTER_READY
|
EV_MASTER_FRAME_RECEIVED
|
EV_MASTER_EXECUTE
|
EV_MASTER_FRAME_SENT
|
EV_MASTER_ERROR_PROCESS
,
RT_EVENT_FLAG_OR
|
RT_EVENT_FLAG_CLEAR
,
RT_WAITING_FOREVER
,
&
recvedEvent
);
/* the enum type couldn't convert to int type */
switch
(
recvedEvent
)
{
case
EV_MASTER_READY
:
*
eEvent
=
EV_MASTER_READY
;
break
;
case
EV_MASTER_FRAME_RECEIVED
:
*
eEvent
=
EV_MASTER_FRAME_RECEIVED
;
break
;
case
EV_MASTER_EXECUTE
:
*
eEvent
=
EV_MASTER_EXECUTE
;
break
;
case
EV_MASTER_FRAME_SENT
:
*
eEvent
=
EV_MASTER_FRAME_SENT
;
break
;
case
EV_MASTER_ERROR_PROCESS
:
*
eEvent
=
EV_MASTER_ERROR_PROCESS
;
break
;
}
return
TRUE
;
}
/**
* This function is initialize the OS resource for modbus master.
* Note:The resource is define by OS.If you not use OS this function can be empty.
*
*/
void
vMBMasterOsResInit
(
void
)
{
rt_sem_init
(
&
xMasterRunRes
,
"master res"
,
0x01
,
RT_IPC_FLAG_PRIO
);
}
/**
* This function is take Mobus Master running resource.
* Note:The resource is define by Operating System.If you not use OS this function can be just return TRUE.
*
* @param lTimeOut the waiting time.
*
* @return resource taked result
*/
BOOL
xMBMasterRunResTake
(
LONG
lTimeOut
)
{
/*If waiting time is -1 .It will wait forever */
return
rt_sem_take
(
&
xMasterRunRes
,
lTimeOut
)
?
FALSE
:
TRUE
;
}
/**
* This function is release Mobus Master running resource.
* Note:The resource is define by Operating System.If you not use OS this function can be empty.
*
*/
void
vMBMasterRunResRelease
(
void
)
{
/* release resource */
rt_sem_release
(
&
xMasterRunRes
);
}
/**
* This is modbus master respond timeout error process callback function.
* @note There functions will block modbus master poll while execute OS waiting.
* So,for real-time of system.Do not execute too much waiting process.
*
* @param ucDestAddress destination salve address
* @param pucPDUData PDU buffer data
* @param ucPDULength PDU buffer length
*
*/
void
vMBMasterErrorCBRespondTimeout
(
UCHAR
ucDestAddress
,
const
UCHAR
*
pucPDUData
,
USHORT
ucPDULength
)
{
/**
* @note This code is use OS's event mechanism for modbus master protocol stack.
* If you don't use OS, you can change it.
*/
rt_event_send
(
&
xMasterOsEvent
,
EV_MASTER_ERROR_RESPOND_TIMEOUT
);
/* You can add your code under here. */
if
(
xMasterEventInQueue
)
}
/**
* This is modbus master receive data error process callback function.
* @note There functions will block modbus master poll while execute OS waiting.
* So,for real-time of system.Do not execute too much waiting process.
*
* @param ucDestAddress destination salve address
* @param pucPDUData PDU buffer data
* @param ucPDULength PDU buffer length
*
*/
void
vMBMasterErrorCBReceiveData
(
UCHAR
ucDestAddress
,
const
UCHAR
*
pucPDUData
,
USHORT
ucPDULength
)
{
/**
* @note This code is use OS's event mechanism for modbus master protocol stack.
* If you don't use OS, you can change it.
*/
rt_event_send
(
&
xMasterOsEvent
,
EV_MASTER_ERROR_RECEIVE_DATA
);
/* You can add your code under here. */
}
/**
* This is modbus master execute function error process callback function.
* @note There functions will block modbus master poll while execute OS waiting.
* So,for real-time of system.Do not execute too much waiting process.
*
* @param ucDestAddress destination salve address
* @param pucPDUData PDU buffer data
* @param ucPDULength PDU buffer length
*
*/
void
vMBMasterErrorCBExecuteFunction
(
UCHAR
ucDestAddress
,
const
UCHAR
*
pucPDUData
,
USHORT
ucPDULength
)
{
/**
* @note This code is use OS's event mechanism for modbus master protocol stack.
* If you don't use OS, you can change it.
*/
rt_event_send
(
&
xMasterOsEvent
,
EV_MASTER_ERROR_EXECUTE_FUNCTION
);
/* You can add your code under here. */
}
/**
* This is modbus master request process success callback function.
* @note There functions will block modbus master poll while execute OS waiting.
* So,for real-time of system.Do not execute too much waiting process.
*
*/
void
vMBMasterCBRequestScuuess
(
void
)
{
/**
* @note This code is use OS's event mechanism for modbus master protocol stack.
* If you don't use OS, you can change it.
*/
rt_event_send
(
&
xMasterOsEvent
,
EV_MASTER_PROCESS_SUCESS
);
/* You can add your code under here. */
}
/**
* This function is wait for modbus master request finish and return result.
* Waiting result include request process success, request respond timeout,
* receive data error and execute function error.You can use the above callback function.
* @note If you are use OS, you can use OS's event mechanism. Otherwise you have to run
* much user custom delay for waiting.
*
* @return request error code
*/
eMBMasterReqErrCode
eMBMasterWaitRequestFinish
(
void
)
{
eMBMasterReqErrCode
eErrStatus
=
MB_MRE_NO_ERR
;
rt_uint32_t
recvedEvent
;
/* waiting for OS event */
rt_event_recv
(
&
xMasterOsEvent
,
EV_MASTER_PROCESS_SUCESS
|
EV_MASTER_ERROR_RESPOND_TIMEOUT
|
EV_MASTER_ERROR_RECEIVE_DATA
|
EV_MASTER_ERROR_EXECUTE_FUNCTION
,
RT_EVENT_FLAG_OR
|
RT_EVENT_FLAG_CLEAR
,
RT_WAITING_FOREVER
,
&
recvedEvent
);
switch
(
recvedEvent
)
{
*
eEvent
=
eMasterQueuedEvent
;
xMasterEventInQueue
=
FALSE
;
xEventHappened
=
TRUE
;
case
EV_MASTER_PROCESS_SUCESS
:
break
;
case
EV_MASTER_ERROR_RESPOND_TIMEOUT
:
{
eErrStatus
=
MB_MRE_TIMEDOUT
;
break
;
}
case
EV_MASTER_ERROR_RECEIVE_DATA
:
{
eErrStatus
=
MB_MRE_REV_DATA
;
break
;
}
case
EV_MASTER_ERROR_EXECUTE_FUNCTION
:
{
eErrStatus
=
MB_MRE_EXE_FUN
;
break
;
}
}
return
xEventHappened
;
return
eErrStatus
;
}
#endif
components/net/freemodbus-v1.6.0/port/portserial.c
浏览文件 @
2a14e407
/*
* FreeModbus Libary:
STM32
Port
* FreeModbus Libary:
RT-Thread
Port
* Copyright (C) 2013 Armink <armink.ztl@gmail.com>
*
* This library is free software; you can redistribute it and/or
...
...
@@ -24,122 +24,148 @@
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"
#include "rtdevice.h"
#include "bsp.h"
/* ----------------------- Static variables ---------------------------------*/
ALIGN
(
RT_ALIGN_SIZE
)
/* software simulation serial transmit IRQ handler thread stack */
static
rt_uint8_t
serial_soft_trans_irq_stack
[
512
];
/* software simulation serial transmit IRQ handler thread */
static
struct
rt_thread
thread_serial_soft_trans_irq
;
/* serial event */
static
struct
rt_event
event_serial
;
/* modbus slave serial device */
static
rt_serial_t
*
serial
;
/* ----------------------- Defines ------------------------------------------*/
/* serial transmit event */
#define EVENT_SERIAL_TRANS_START (1<<0)
/* ----------------------- static functions ---------------------------------*/
static
void
prvvUARTTxReadyISR
(
void
);
static
void
prvvUARTRxISR
(
void
);
static
rt_err_t
serial_rx_ind
(
rt_device_t
dev
,
rt_size_t
size
);
static
void
serial_soft_trans_irq
(
void
*
parameter
);
/* ----------------------- Start implementation -----------------------------*/
BOOL
xMBPortSerialInit
(
UCHAR
ucPORT
,
ULONG
ulBaudRate
,
UCHAR
ucDataBits
,
eMBParity
eParity
)
{
/**
* set 485 mode receive and transmit control IO
* @note MODBUS_SLAVE_RT_CONTROL_PIN_INDEX need be defined by user
*/
rt_pin_mode
(
MODBUS_SLAVE_RT_CONTROL_PIN_INDEX
,
PIN_MODE_OUTPUT
);
/* set serial name */
if
(
ucPORT
==
1
)
{
#if defined(RT_USING_UART1) || defined(RT_USING_REMAP_UART1)
extern
struct
rt_serial_device
serial1
;
serial
=
&
serial1
;
#endif
}
else
if
(
ucPORT
==
2
)
{
#if defined(RT_USING_UART2)
extern
struct
rt_serial_device
serial2
;
serial
=
&
serial2
;
#endif
}
else
if
(
ucPORT
==
3
)
{
#if defined(RT_USING_UART3)
extern
struct
rt_serial_device
serial3
;
serial
=
&
serial3
;
#endif
}
/* set serial configure parameter */
serial
->
config
.
baud_rate
=
ulBaudRate
;
serial
->
config
.
stop_bits
=
STOP_BITS_1
;
switch
(
eParity
){
case
MB_PAR_NONE
:
{
serial
->
config
.
data_bits
=
DATA_BITS_8
;
serial
->
config
.
parity
=
PARITY_NONE
;
break
;
}
case
MB_PAR_ODD
:
{
serial
->
config
.
data_bits
=
DATA_BITS_9
;
serial
->
config
.
parity
=
PARITY_ODD
;
break
;
}
case
MB_PAR_EVEN
:
{
serial
->
config
.
data_bits
=
DATA_BITS_9
;
serial
->
config
.
parity
=
PARITY_EVEN
;
break
;
}
}
/* set serial configure */
serial
->
ops
->
configure
(
serial
,
&
(
serial
->
config
));
/* open serial device */
if
(
!
serial
->
parent
.
open
(
&
serial
->
parent
,
RT_DEVICE_OFLAG_RDWR
|
RT_DEVICE_FLAG_INT_RX
))
{
serial
->
parent
.
rx_indicate
=
serial_rx_ind
;
}
else
{
return
FALSE
;
}
/* software initialize */
rt_thread_init
(
&
thread_serial_soft_trans_irq
,
"slave trans"
,
serial_soft_trans_irq
,
RT_NULL
,
serial_soft_trans_irq_stack
,
sizeof
(
serial_soft_trans_irq_stack
),
10
,
5
);
rt_thread_startup
(
&
thread_serial_soft_trans_irq
);
rt_event_init
(
&
event_serial
,
"slave event"
,
RT_IPC_FLAG_PRIO
);
return
TRUE
;
}
void
vMBPortSerialEnable
(
BOOL
xRxEnable
,
BOOL
xTxEnable
)
{
if
(
xRxEnable
)
{
SLAVE_RS485_RECEIVE_MODE
;
USART_ITConfig
(
USART1
,
USART_IT_RXNE
,
ENABLE
);
}
else
{
SLAVE_RS485_SEND_MODE
;
USART_ITConfig
(
USART1
,
USART_IT_RXNE
,
DISABLE
);
}
if
(
xTxEnable
)
{
USART_ITConfig
(
USART1
,
USART_IT_TXE
,
ENABLE
);
}
else
{
USART_ITConfig
(
USART1
,
USART_IT_TXE
,
DISABLE
);
}
rt_uint32_t
recved_event
;
if
(
xRxEnable
)
{
/* enable RX interrupt */
serial
->
ops
->
control
(
serial
,
RT_DEVICE_CTRL_SET_INT
,
(
void
*
)
RT_DEVICE_FLAG_INT_RX
);
/* switch 485 to receive mode */
rt_pin_write
(
MODBUS_SLAVE_RT_CONTROL_PIN_INDEX
,
PIN_LOW
);
}
else
{
/* switch 485 to transmit mode */
rt_pin_write
(
MODBUS_SLAVE_RT_CONTROL_PIN_INDEX
,
PIN_HIGH
);
/* disable RX interrupt */
serial
->
ops
->
control
(
serial
,
RT_DEVICE_CTRL_CLR_INT
,
(
void
*
)
RT_DEVICE_FLAG_INT_RX
);
}
if
(
xTxEnable
)
{
/* start serial transmit */
rt_event_send
(
&
event_serial
,
EVENT_SERIAL_TRANS_START
);
}
else
{
/* stop serial transmit */
rt_event_recv
(
&
event_serial
,
EVENT_SERIAL_TRANS_START
,
RT_EVENT_FLAG_OR
|
RT_EVENT_FLAG_CLEAR
,
0
,
&
recved_event
);
}
}
void
vMBPortClose
(
void
)
{
USART_ITConfig
(
USART1
,
USART_IT_TXE
|
USART_IT_RXNE
,
DISABLE
);
USART_Cmd
(
USART1
,
DISABLE
);
}
//默认一个从机 串口1 波特率可设置 奇偶检验可设置
BOOL
xMBPortSerialInit
(
UCHAR
ucPORT
,
ULONG
ulBaudRate
,
UCHAR
ucDataBits
,
eMBParity
eParity
)
{
GPIO_InitTypeDef
GPIO_InitStructure
;
USART_InitTypeDef
USART_InitStructure
;
NVIC_InitTypeDef
NVIC_InitStructure
;
//======================时钟初始化=======================================
RCC_APB2PeriphClockCmd
(
RCC_APB2Periph_GPIOA
|
RCC_APB2Periph_GPIOB
|
RCC_APB2Periph_USART1
,
ENABLE
);
//======================IO初始化=======================================
//USART1_TX
GPIO_InitStructure
.
GPIO_Speed
=
GPIO_Speed_50MHz
;
GPIO_InitStructure
.
GPIO_Mode
=
GPIO_Mode_AF_PP
;
GPIO_InitStructure
.
GPIO_Pin
=
GPIO_Pin_9
;
GPIO_Init
(
GPIOA
,
&
GPIO_InitStructure
);
//USART1_RX
GPIO_InitStructure
.
GPIO_Mode
=
GPIO_Mode_IN_FLOATING
;
GPIO_InitStructure
.
GPIO_Pin
=
GPIO_Pin_10
;
GPIO_Init
(
GPIOA
,
&
GPIO_InitStructure
);
//配置485发送和接收模式
// TODO 暂时先写B13 等之后组网测试时再修改
GPIO_InitStructure
.
GPIO_Mode
=
GPIO_Mode_Out_PP
;
GPIO_InitStructure
.
GPIO_Pin
=
GPIO_Pin_13
;
GPIO_Init
(
GPIOB
,
&
GPIO_InitStructure
);
//======================串口初始化=======================================
USART_InitStructure
.
USART_BaudRate
=
ulBaudRate
;
//设置校验模式
switch
(
eParity
)
{
case
MB_PAR_NONE
:
//无校验
USART_InitStructure
.
USART_Parity
=
USART_Parity_No
;
USART_InitStructure
.
USART_WordLength
=
USART_WordLength_8b
;
break
;
case
MB_PAR_ODD
:
//奇校验
USART_InitStructure
.
USART_Parity
=
USART_Parity_Odd
;
USART_InitStructure
.
USART_WordLength
=
USART_WordLength_9b
;
break
;
case
MB_PAR_EVEN
:
//偶校验
USART_InitStructure
.
USART_Parity
=
USART_Parity_Even
;
USART_InitStructure
.
USART_WordLength
=
USART_WordLength_9b
;
break
;
default:
return
FALSE
;
}
USART_InitStructure
.
USART_StopBits
=
USART_StopBits_1
;
USART_InitStructure
.
USART_HardwareFlowControl
=
USART_HardwareFlowControl_None
;
USART_InitStructure
.
USART_Mode
=
USART_Mode_Rx
|
USART_Mode_Tx
;
if
(
ucPORT
!=
1
)
return
FALSE
;
ENTER_CRITICAL_SECTION
();
//关全局中断
USART_Init
(
USART1
,
&
USART_InitStructure
);
USART_ITConfig
(
USART1
,
USART_IT_RXNE
,
ENABLE
);
USART_Cmd
(
USART1
,
ENABLE
);
//=====================中断初始化======================================
//设置NVIC优先级分组为Group2:0-3抢占式优先级,0-3的响应式优先级
NVIC_PriorityGroupConfig
(
NVIC_PriorityGroup_2
);
NVIC_InitStructure
.
NVIC_IRQChannel
=
USART1_IRQn
;
NVIC_InitStructure
.
NVIC_IRQChannelPreemptionPriority
=
0
;
NVIC_InitStructure
.
NVIC_IRQChannelSubPriority
=
1
;
NVIC_InitStructure
.
NVIC_IRQChannelCmd
=
ENABLE
;
NVIC_Init
(
&
NVIC_InitStructure
);
EXIT_CRITICAL_SECTION
();
//开全局中断
return
TRUE
;
serial
->
parent
.
close
(
&
(
serial
->
parent
));
}
BOOL
xMBPortSerialPutByte
(
CHAR
ucByte
)
{
USART_SendData
(
USART1
,
ucByte
);
return
TRUE
;
serial
->
parent
.
write
(
&
(
serial
->
parent
),
0
,
&
ucByte
,
1
);
return
TRUE
;
}
BOOL
xMBPortSerialGetByte
(
CHAR
*
pucByte
)
{
*
pucByte
=
USART_ReceiveData
(
USART
1
);
return
TRUE
;
serial
->
parent
.
read
(
&
(
serial
->
parent
),
0
,
pucByte
,
1
);
return
TRUE
;
}
/*
...
...
@@ -151,7 +177,7 @@ BOOL xMBPortSerialGetByte(CHAR * pucByte)
*/
void
prvvUARTTxReadyISR
(
void
)
{
pxMBFrameCBTransmitterEmpty
();
pxMBFrameCBTransmitterEmpty
();
}
/*
...
...
@@ -162,28 +188,35 @@ void prvvUARTTxReadyISR(void)
*/
void
prvvUARTRxISR
(
void
)
{
pxMBFrameCBByteReceived
();
pxMBFrameCBByteReceived
();
}
/*******************************************************************************
* Function Name : USART1_IRQHandler
* Description : This function handles USART1 global interrupt request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void
USART1_IRQHandler
(
void
)
{
rt_interrupt_enter
();
//接收中断
if
(
USART_GetITStatus
(
USART1
,
USART_IT_RXNE
)
==
SET
)
{
USART_ClearITPendingBit
(
USART1
,
USART_IT_RXNE
);
prvvUARTRxISR
();
}
//发送中断
if
(
USART_GetITStatus
(
USART1
,
USART_IT_TXE
)
==
SET
)
{
prvvUARTTxReadyISR
();
}
rt_interrupt_leave
();
/**
* Software simulation serial transmit IRQ handler.
*
* @param parameter parameter
*/
static
void
serial_soft_trans_irq
(
void
*
parameter
)
{
rt_uint32_t
recved_event
;
while
(
1
)
{
/* waiting for serial transmit start */
rt_event_recv
(
&
event_serial
,
EVENT_SERIAL_TRANS_START
,
RT_EVENT_FLAG_OR
,
RT_WAITING_FOREVER
,
&
recved_event
);
/* execute modbus callback */
prvvUARTTxReadyISR
();
}
}
/**
* This function is serial receive callback function
*
* @param dev the device of serial
* @param size the data size that receive
*
* @return return RT_EOK
*/
static
rt_err_t
serial_rx_ind
(
rt_device_t
dev
,
rt_size_t
size
)
{
prvvUARTRxISR
();
return
RT_EOK
;
}
components/net/freemodbus-v1.6.0/port/portserial_m.c
浏览文件 @
2a14e407
/*
* FreeModbus Libary:
STM32
Port
* FreeModbus Libary:
RT-Thread
Port
* Copyright (C) 2013 Armink <armink.ztl@gmail.com>
*
* This library is free software; you can redistribute it and/or
...
...
@@ -24,123 +24,149 @@
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"
#include "rtdevice.h"
#include "bsp.h"
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
/* ----------------------- Static variables ---------------------------------*/
ALIGN
(
RT_ALIGN_SIZE
)
/* software simulation serial transmit IRQ handler thread stack */
static
rt_uint8_t
serial_soft_trans_irq_stack
[
512
];
/* software simulation serial transmit IRQ handler thread */
static
struct
rt_thread
thread_serial_soft_trans_irq
;
/* serial event */
static
struct
rt_event
event_serial
;
/* modbus slave serial device */
static
rt_serial_t
*
serial
;
/* ----------------------- Defines ------------------------------------------*/
/* serial transmit event */
#define EVENT_SERIAL_TRANS_START (1<<0)
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED
/* ----------------------- static functions ---------------------------------*/
static
void
prvvUARTTxReadyISR
(
void
);
static
void
prvvUARTRxISR
(
void
);
static
rt_err_t
serial_rx_ind
(
rt_device_t
dev
,
rt_size_t
size
);
static
void
serial_soft_trans_irq
(
void
*
parameter
);
/* ----------------------- Start implementation -----------------------------*/
BOOL
xMBMasterPortSerialInit
(
UCHAR
ucPORT
,
ULONG
ulBaudRate
,
UCHAR
ucDataBits
,
eMBParity
eParity
)
{
/**
* set 485 mode receive and transmit control IO
* @note MODBUS_MASTER_RT_CONTROL_PIN_INDEX need be defined by user
*/
rt_pin_mode
(
MODBUS_MASTER_RT_CONTROL_PIN_INDEX
,
PIN_MODE_OUTPUT
);
/* set serial name */
if
(
ucPORT
==
1
)
{
#if defined(RT_USING_UART1) || defined(RT_USING_REMAP_UART1)
extern
struct
rt_serial_device
serial1
;
serial
=
&
serial1
;
#endif
}
else
if
(
ucPORT
==
2
)
{
#if defined(RT_USING_UART2)
extern
struct
rt_serial_device
serial2
;
serial
=
&
serial2
;
#endif
}
else
if
(
ucPORT
==
3
)
{
#if defined(RT_USING_UART3)
extern
struct
rt_serial_device
serial3
;
serial
=
&
serial3
;
#endif
}
/* set serial configure parameter */
serial
->
config
.
baud_rate
=
ulBaudRate
;
serial
->
config
.
stop_bits
=
STOP_BITS_1
;
switch
(
eParity
){
case
MB_PAR_NONE
:
{
serial
->
config
.
data_bits
=
DATA_BITS_8
;
serial
->
config
.
parity
=
PARITY_NONE
;
break
;
}
case
MB_PAR_ODD
:
{
serial
->
config
.
data_bits
=
DATA_BITS_9
;
serial
->
config
.
parity
=
PARITY_ODD
;
break
;
}
case
MB_PAR_EVEN
:
{
serial
->
config
.
data_bits
=
DATA_BITS_9
;
serial
->
config
.
parity
=
PARITY_EVEN
;
break
;
}
}
/* set serial configure */
serial
->
ops
->
configure
(
serial
,
&
(
serial
->
config
));
/* open serial device */
if
(
!
serial
->
parent
.
open
(
&
serial
->
parent
,
RT_DEVICE_OFLAG_RDWR
|
RT_DEVICE_FLAG_INT_RX
))
{
serial
->
parent
.
rx_indicate
=
serial_rx_ind
;
}
else
{
return
FALSE
;
}
/* software initialize */
rt_thread_init
(
&
thread_serial_soft_trans_irq
,
"slave trans"
,
serial_soft_trans_irq
,
RT_NULL
,
serial_soft_trans_irq_stack
,
sizeof
(
serial_soft_trans_irq_stack
),
10
,
5
);
rt_thread_startup
(
&
thread_serial_soft_trans_irq
);
rt_event_init
(
&
event_serial
,
"slave event"
,
RT_IPC_FLAG_PRIO
);
return
TRUE
;
}
void
vMBMasterPortSerialEnable
(
BOOL
xRxEnable
,
BOOL
xTxEnable
)
{
if
(
xRxEnable
)
{
MASTER_RS485_RECEIVE_MODE
;
USART_ITConfig
(
USART2
,
USART_IT_RXNE
,
ENABLE
);
}
else
{
MASTER_RS485_SEND_MODE
;
USART_ITConfig
(
USART2
,
USART_IT_RXNE
,
DISABLE
);
}
if
(
xTxEnable
)
{
USART_ITConfig
(
USART2
,
USART_IT_TXE
,
ENABLE
);
}
else
{
USART_ITConfig
(
USART2
,
USART_IT_TXE
,
DISABLE
);
}
rt_uint32_t
recved_event
;
if
(
xRxEnable
)
{
/* enable RX interrupt */
serial
->
ops
->
control
(
serial
,
RT_DEVICE_CTRL_SET_INT
,
(
void
*
)
RT_DEVICE_FLAG_INT_RX
);
/* switch 485 to receive mode */
rt_pin_write
(
MODBUS_MASTER_RT_CONTROL_PIN_INDEX
,
PIN_LOW
);
}
else
{
/* switch 485 to transmit mode */
rt_pin_write
(
MODBUS_MASTER_RT_CONTROL_PIN_INDEX
,
PIN_HIGH
);
/* disable RX interrupt */
serial
->
ops
->
control
(
serial
,
RT_DEVICE_CTRL_CLR_INT
,
(
void
*
)
RT_DEVICE_FLAG_INT_RX
);
}
if
(
xTxEnable
)
{
/* start serial transmit */
rt_event_send
(
&
event_serial
,
EVENT_SERIAL_TRANS_START
);
}
else
{
/* stop serial transmit */
rt_event_recv
(
&
event_serial
,
EVENT_SERIAL_TRANS_START
,
RT_EVENT_FLAG_OR
|
RT_EVENT_FLAG_CLEAR
,
0
,
&
recved_event
);
}
}
void
vMBMasterPortClose
(
void
)
{
USART_ITConfig
(
USART2
,
USART_IT_TXE
|
USART_IT_RXNE
,
DISABLE
);
USART_Cmd
(
USART2
,
DISABLE
);
}
//默认一个主机 串口2 波特率可设置 奇偶检验可设置
BOOL
xMBMasterPortSerialInit
(
UCHAR
ucPORT
,
ULONG
ulBaudRate
,
UCHAR
ucDataBits
,
eMBParity
eParity
)
{
GPIO_InitTypeDef
GPIO_InitStructure
;
USART_InitTypeDef
USART_InitStructure
;
NVIC_InitTypeDef
NVIC_InitStructure
;
//======================时钟初始化=======================================
RCC_APB2PeriphClockCmd
(
RCC_APB2Periph_GPIOA
|
RCC_APB2Periph_GPIOB
,
ENABLE
);
RCC_APB1PeriphClockCmd
(
RCC_APB1Periph_USART2
,
ENABLE
);
//======================IO初始化=======================================
//USART2_TX
GPIO_InitStructure
.
GPIO_Speed
=
GPIO_Speed_50MHz
;
GPIO_InitStructure
.
GPIO_Mode
=
GPIO_Mode_AF_PP
;
GPIO_InitStructure
.
GPIO_Pin
=
GPIO_Pin_2
;
GPIO_Init
(
GPIOA
,
&
GPIO_InitStructure
);
//USART2_RX
GPIO_InitStructure
.
GPIO_Mode
=
GPIO_Mode_IN_FLOATING
;
GPIO_InitStructure
.
GPIO_Pin
=
GPIO_Pin_3
;
GPIO_Init
(
GPIOA
,
&
GPIO_InitStructure
);
//配置485发送和接收模式
// TODO 暂时先写B13 等之后组网测试时再修改
GPIO_InitStructure
.
GPIO_Mode
=
GPIO_Mode_Out_PP
;
GPIO_InitStructure
.
GPIO_Pin
=
GPIO_Pin_13
;
GPIO_Init
(
GPIOB
,
&
GPIO_InitStructure
);
//======================串口初始化=======================================
USART_InitStructure
.
USART_BaudRate
=
ulBaudRate
;
//设置校验模式
switch
(
eParity
)
{
case
MB_PAR_NONE
:
//无校验
USART_InitStructure
.
USART_Parity
=
USART_Parity_No
;
USART_InitStructure
.
USART_WordLength
=
USART_WordLength_8b
;
break
;
case
MB_PAR_ODD
:
//奇校验
USART_InitStructure
.
USART_Parity
=
USART_Parity_Odd
;
USART_InitStructure
.
USART_WordLength
=
USART_WordLength_9b
;
break
;
case
MB_PAR_EVEN
:
//偶校验
USART_InitStructure
.
USART_Parity
=
USART_Parity_Even
;
USART_InitStructure
.
USART_WordLength
=
USART_WordLength_9b
;
break
;
default:
return
FALSE
;
}
USART_InitStructure
.
USART_StopBits
=
USART_StopBits_1
;
USART_InitStructure
.
USART_HardwareFlowControl
=
USART_HardwareFlowControl_None
;
USART_InitStructure
.
USART_Mode
=
USART_Mode_Rx
|
USART_Mode_Tx
;
if
(
ucPORT
!=
2
)
return
FALSE
;
ENTER_CRITICAL_SECTION
();
//关全局中断
USART_Init
(
USART2
,
&
USART_InitStructure
);
USART_ITConfig
(
USART2
,
USART_IT_RXNE
,
ENABLE
);
USART_Cmd
(
USART2
,
ENABLE
);
//=====================中断初始化======================================
//设置NVIC优先级分组为Group2:0-3抢占式优先级,0-3的响应式优先级
NVIC_PriorityGroupConfig
(
NVIC_PriorityGroup_2
);
NVIC_InitStructure
.
NVIC_IRQChannel
=
USART2_IRQn
;
NVIC_InitStructure
.
NVIC_IRQChannelPreemptionPriority
=
0
;
NVIC_InitStructure
.
NVIC_IRQChannelSubPriority
=
0
;
NVIC_InitStructure
.
NVIC_IRQChannelCmd
=
ENABLE
;
NVIC_Init
(
&
NVIC_InitStructure
);
EXIT_CRITICAL_SECTION
();
//开全局中断
return
TRUE
;
serial
->
parent
.
close
(
&
(
serial
->
parent
));
}
BOOL
xMBMasterPortSerialPutByte
(
CHAR
ucByte
)
{
USART_SendData
(
USART2
,
ucByte
);
serial
->
parent
.
write
(
&
(
serial
->
parent
),
0
,
&
ucByte
,
1
);
return
TRUE
;
}
BOOL
xMBMasterPortSerialGetByte
(
CHAR
*
pucByte
)
{
*
pucByte
=
USART_ReceiveData
(
USART2
);
return
TRUE
;
serial
->
parent
.
read
(
&
(
serial
->
parent
),
0
,
pucByte
,
1
);
return
TRUE
;
}
/*
...
...
@@ -152,7 +178,7 @@ BOOL xMBMasterPortSerialGetByte(CHAR * pucByte)
*/
void
prvvUARTTxReadyISR
(
void
)
{
pxMBMasterFrameCBTransmitterEmpty
();
pxMBMasterFrameCBTransmitterEmpty
();
}
/*
...
...
@@ -163,30 +189,37 @@ void prvvUARTTxReadyISR(void)
*/
void
prvvUARTRxISR
(
void
)
{
pxMBMasterFrameCBByteReceived
();
pxMBMasterFrameCBByteReceived
();
}
/*******************************************************************************
* Function Name : USART2_IRQHandler
* Description : This function handles USART2 global interrupt request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void
USART2_IRQHandler
(
void
)
{
rt_interrupt_enter
();
//接收中断
if
(
USART_GetITStatus
(
USART2
,
USART_IT_RXNE
)
==
SET
)
{
USART_ClearITPendingBit
(
USART2
,
USART_IT_RXNE
);
prvvUARTRxISR
();
}
//发送中断
if
(
USART_GetITStatus
(
USART2
,
USART_IT_TXE
)
==
SET
)
{
prvvUARTTxReadyISR
();
}
rt_interrupt_leave
();
/**
* Software simulation serial transmit IRQ handler.
*
* @param parameter parameter
*/
static
void
serial_soft_trans_irq
(
void
*
parameter
)
{
rt_uint32_t
recved_event
;
while
(
1
)
{
/* waiting for serial transmit start */
rt_event_recv
(
&
event_serial
,
EVENT_SERIAL_TRANS_START
,
RT_EVENT_FLAG_OR
,
RT_WAITING_FOREVER
,
&
recved_event
);
/* execute modbus callback */
prvvUARTTxReadyISR
();
}
}
/**
* This function is serial receive callback function
*
* @param dev the device of serial
* @param size the data size that receive
*
* @return return RT_EOK
*/
static
rt_err_t
serial_rx_ind
(
rt_device_t
dev
,
rt_size_t
size
)
{
prvvUARTRxISR
();
return
RT_EOK
;
}
#endif
components/net/freemodbus-v1.6.0/port/porttimer.c
浏览文件 @
2a14e407
/*
* FreeModbus Libary:
STM32
Port
* FreeModbus Libary:
RT-Thread
Port
* Copyright (C) 2013 Armink <armink.ztl@gmail.com>
*
* This library is free software; you can redistribute it and/or
...
...
@@ -27,81 +27,37 @@
#include "mbport.h"
/* ----------------------- static functions ---------------------------------*/
static
struct
rt_timer
timer
;
static
void
prvvTIMERExpiredISR
(
void
);
static
void
timer_timeout_ind
(
void
*
parameter
);
/* ----------------------- Start implementation -----------------------------*/
BOOL
xMBPortTimersInit
(
USHORT
usTim1Timerout50us
)
{
uint16_t
PrescalerValue
=
0
;
TIM_TimeBaseInitTypeDef
TIM_TimeBaseStructure
;
NVIC_InitTypeDef
NVIC_InitStructure
;
//====================================时钟初始化===========================
//使能定时器3时钟
RCC_APB1PeriphClockCmd
(
RCC_APB1Periph_TIM3
,
ENABLE
);
//====================================定时器初始化===========================
//定时器时间基配置说明
//HCLK为72MHz,APB1经过2分频为36MHz
//TIM3的时钟倍频后为72MHz(硬件自动倍频,达到最大)
//TIM3的分频系数为3599,时间基频率为72 / (1 + Prescaler) = 20KHz,基准为50us
//TIM最大计数值为usTim1Timerout50u
PrescalerValue
=
(
uint16_t
)
(
SystemCoreClock
/
20000
)
-
1
;
//定时器1初始化
TIM_TimeBaseStructure
.
TIM_Period
=
(
uint16_t
)
usTim1Timerout50us
;
TIM_TimeBaseStructure
.
TIM_Prescaler
=
PrescalerValue
;
TIM_TimeBaseStructure
.
TIM_ClockDivision
=
0
;
TIM_TimeBaseStructure
.
TIM_CounterMode
=
TIM_CounterMode_Up
;
TIM_TimeBaseInit
(
TIM3
,
&
TIM_TimeBaseStructure
);
//预装载使能
TIM_ARRPreloadConfig
(
TIM3
,
ENABLE
);
//====================================中断初始化===========================
//设置NVIC优先级分组为Group2:0-3抢占式优先级,0-3的响应式优先级
NVIC_PriorityGroupConfig
(
NVIC_PriorityGroup_2
);
NVIC_InitStructure
.
NVIC_IRQChannel
=
TIM3_IRQn
;
NVIC_InitStructure
.
NVIC_IRQChannelPreemptionPriority
=
1
;
NVIC_InitStructure
.
NVIC_IRQChannelSubPriority
=
1
;
NVIC_InitStructure
.
NVIC_IRQChannelCmd
=
ENABLE
;
NVIC_Init
(
&
NVIC_InitStructure
);
//清除溢出中断标志位
TIM_ClearITPendingBit
(
TIM3
,
TIM_IT_Update
);
//定时器3溢出中断关闭
TIM_ITConfig
(
TIM3
,
TIM_IT_Update
,
DISABLE
);
//定时器3禁能
TIM_Cmd
(
TIM3
,
DISABLE
);
return
TRUE
;
rt_timer_init
(
&
timer
,
"slave timer"
,
timer_timeout_ind
,
/* bind timeout callback function */
RT_NULL
,
(
50
*
usTim1Timerout50us
)
/
(
1000
*
1000
/
RT_TICK_PER_SECOND
),
RT_TIMER_FLAG_ONE_SHOT
);
/* one shot */
return
TRUE
;
}
void
vMBPortTimersEnable
()
{
TIM_ClearITPendingBit
(
TIM3
,
TIM_IT_Update
);
TIM_ITConfig
(
TIM3
,
TIM_IT_Update
,
ENABLE
);
TIM_SetCounter
(
TIM3
,
0
);
TIM_Cmd
(
TIM3
,
ENABLE
);
rt_timer_start
(
&
timer
);
}
void
vMBPortTimersDisable
()
{
TIM_ClearITPendingBit
(
TIM3
,
TIM_IT_Update
);
TIM_ITConfig
(
TIM3
,
TIM_IT_Update
,
DISABLE
);
TIM_SetCounter
(
TIM3
,
0
);
TIM_Cmd
(
TIM3
,
DISABLE
);
rt_timer_stop
(
&
timer
);
}
void
prvvTIMERExpiredISR
(
void
)
{
(
void
)
pxMBPortCBTimerExpired
();
(
void
)
pxMBPortCBTimerExpired
();
}
void
TIM3_IRQHandler
(
void
)
static
void
timer_timeout_ind
(
void
*
parameter
)
{
rt_interrupt_enter
();
if
(
TIM_GetITStatus
(
TIM3
,
TIM_IT_Update
)
!=
RESET
)
{
TIM_ClearFlag
(
TIM3
,
TIM_FLAG_Update
);
//清中断标记
TIM_ClearITPendingBit
(
TIM3
,
TIM_IT_Update
);
//清除定时器T3溢出中断标志位
prvvTIMERExpiredISR
();
}
rt_interrupt_leave
();
prvvTIMERExpiredISR
();
}
components/net/freemodbus-v1.6.0/port/porttimer_m.c
浏览文件 @
2a14e407
/*
* FreeModbus Libary:
STM32
Port
* FreeModbus Libary:
RT-Thread
Port
* Copyright (C) 2013 Armink <armink.ztl@gmail.com>
*
* This library is free software; you can redistribute it and/or
...
...
@@ -27,10 +27,12 @@
#include "mb_m.h"
#include "mbport.h"
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED
> 0
/* ----------------------- Variables ----------------------------------------*/
static
USHORT
usT35TimeOut50us
;
static
USHORT
usPrescalerValue
=
0
;
static
struct
rt_timer
timer
;
static
void
prvvTIMERExpiredISR
(
void
);
static
void
timer_timeout_ind
(
void
*
parameter
);
/* ----------------------- static functions ---------------------------------*/
static
void
prvvTIMERExpiredISR
(
void
);
...
...
@@ -38,120 +40,68 @@ static void prvvTIMERExpiredISR(void);
/* ----------------------- Start implementation -----------------------------*/
BOOL
xMBMasterPortTimersInit
(
USHORT
usTimeOut50us
)
{
NVIC_InitTypeDef
NVIC_InitStructure
;
//====================================时钟初始化===========================
//使能定时器2时钟
RCC_APB1PeriphClockCmd
(
RCC_APB1Periph_TIM2
,
ENABLE
);
//====================================定时器初始化===========================
//定时器时间基配置说明
//HCLK为72MHz,APB1经过2分频为36MHz
//TIM2的时钟倍频后为72MHz(硬件自动倍频,达到最大)
//TIM2的分频系数为3599,时间基频率为72 / (1 + Prescaler) = 20KHz,基准为50us
//TIM最大计数值为usTim1Timerout50u
usPrescalerValue
=
(
uint16_t
)
(
SystemCoreClock
/
20000
)
-
1
;
//保存T35定时器计数值
usT35TimeOut50us
=
usTimeOut50us
;
//预装载使能
TIM_ARRPreloadConfig
(
TIM2
,
ENABLE
);
//====================================中断初始化===========================
//设置NVIC优先级分组为Group2:0-3抢占式优先级,0-3的响应式优先级
NVIC_PriorityGroupConfig
(
NVIC_PriorityGroup_2
);
NVIC_InitStructure
.
NVIC_IRQChannel
=
TIM2_IRQn
;
NVIC_InitStructure
.
NVIC_IRQChannelPreemptionPriority
=
1
;
NVIC_InitStructure
.
NVIC_IRQChannelSubPriority
=
0
;
NVIC_InitStructure
.
NVIC_IRQChannelCmd
=
ENABLE
;
NVIC_Init
(
&
NVIC_InitStructure
);
//清除溢出中断标志位
TIM_ClearITPendingBit
(
TIM2
,
TIM_IT_Update
);
//定时器3溢出中断关闭
TIM_ITConfig
(
TIM2
,
TIM_IT_Update
,
DISABLE
);
//定时器3禁能
TIM_Cmd
(
TIM2
,
DISABLE
);
return
TRUE
;
/* backup T35 ticks */
usT35TimeOut50us
=
usTimeOut50us
;
rt_timer_init
(
&
timer
,
"master timer"
,
timer_timeout_ind
,
/* bind timeout callback function */
RT_NULL
,
(
50
*
usT35TimeOut50us
)
/
(
1000
*
1000
/
RT_TICK_PER_SECOND
),
RT_TIMER_FLAG_ONE_SHOT
);
/* one shot */
return
TRUE
;
}
void
vMBMasterPortTimersT35Enable
()
{
TIM_TimeBaseInitTypeDef
TIM_TimeBaseStructure
;
rt_tick_t
timer_tick
=
(
50
*
usT35TimeOut50us
)
/
(
1000
*
1000
/
RT_TICK_PER_SECOND
);
/* Set current timer mode,
don't change it.*/
vMBMasterSetCurTimerMode
(
MB_TMODE_T35
);
/* Set current timer mode,
don't change it.*/
vMBMasterSetCurTimerMode
(
MB_TMODE_T35
);
TIM_TimeBaseStructure
.
TIM_Prescaler
=
usPrescalerValue
;
TIM_TimeBaseStructure
.
TIM_ClockDivision
=
0
;
TIM_TimeBaseStructure
.
TIM_CounterMode
=
TIM_CounterMode_Up
;
TIM_TimeBaseStructure
.
TIM_Period
=
(
uint16_t
)
usT35TimeOut50us
;
TIM_TimeBaseInit
(
TIM2
,
&
TIM_TimeBaseStructure
);
rt_timer_control
(
&
timer
,
RT_TIMER_CTRL_SET_TIME
,
&
timer_tick
);
TIM_ClearITPendingBit
(
TIM2
,
TIM_IT_Update
);
TIM_ITConfig
(
TIM2
,
TIM_IT_Update
,
ENABLE
);
TIM_SetCounter
(
TIM2
,
0
);
TIM_Cmd
(
TIM2
,
ENABLE
);
rt_timer_start
(
&
timer
);
}
void
vMBMasterPortTimersConvertDelayEnable
()
{
TIM_TimeBaseInitTypeDef
TIM_TimeBaseStructure
;
rt_tick_t
timer_tick
=
MB_MASTER_DELAY_MS_CONVERT
*
RT_TICK_PER_SECOND
/
1000
;
/* Set current timer mode,
don't change it.*/
vMBMasterSetCurTimerMode
(
MB_TMODE_CONVERT_DELAY
);
/* Set current timer mode,
don't change it.*/
vMBMasterSetCurTimerMode
(
MB_TMODE_CONVERT_DELAY
);
TIM_TimeBaseStructure
.
TIM_Prescaler
=
usPrescalerValue
;
TIM_TimeBaseStructure
.
TIM_ClockDivision
=
0
;
TIM_TimeBaseStructure
.
TIM_CounterMode
=
TIM_CounterMode_Up
;
TIM_TimeBaseStructure
.
TIM_Period
=
(
uint16_t
)(
MB_MASTER_DELAY_MS_CONVERT
*
1000
/
50
);
TIM_TimeBaseInit
(
TIM2
,
&
TIM_TimeBaseStructure
);
rt_timer_control
(
&
timer
,
RT_TIMER_CTRL_SET_TIME
,
&
timer_tick
);
TIM_ClearITPendingBit
(
TIM2
,
TIM_IT_Update
);
TIM_ITConfig
(
TIM2
,
TIM_IT_Update
,
ENABLE
);
TIM_SetCounter
(
TIM2
,
0
);
TIM_Cmd
(
TIM2
,
ENABLE
);
rt_timer_start
(
&
timer
);
}
void
vMBMasterPortTimersRespondTimeoutEnable
()
{
TIM_TimeBaseInitTypeDef
TIM_TimeBaseStructure
;
rt_tick_t
timer_tick
=
MB_MASTER_TIMEOUT_MS_RESPOND
*
RT_TICK_PER_SECOND
/
1000
;
/* Set current timer mode,
don't change it.*/
vMBMasterSetCurTimerMode
(
MB_TMODE_RESPOND_TIMEOUT
);
/* Set current timer mode,
don't change it.*/
vMBMasterSetCurTimerMode
(
MB_TMODE_RESPOND_TIMEOUT
);
TIM_TimeBaseStructure
.
TIM_Prescaler
=
usPrescalerValue
;
TIM_TimeBaseStructure
.
TIM_ClockDivision
=
0
;
TIM_TimeBaseStructure
.
TIM_CounterMode
=
TIM_CounterMode_Up
;
TIM_TimeBaseStructure
.
TIM_Period
=
(
uint16_t
)(
MB_MASTER_TIMEOUT_MS_RESPOND
*
1000
/
50
);
TIM_TimeBaseInit
(
TIM2
,
&
TIM_TimeBaseStructure
);
rt_timer_control
(
&
timer
,
RT_TIMER_CTRL_SET_TIME
,
&
timer_tick
);
TIM_ClearITPendingBit
(
TIM2
,
TIM_IT_Update
);
TIM_ITConfig
(
TIM2
,
TIM_IT_Update
,
ENABLE
);
TIM_SetCounter
(
TIM2
,
0
);
TIM_Cmd
(
TIM2
,
ENABLE
);
rt_timer_start
(
&
timer
);
}
void
vMBMasterPortTimersDisable
()
{
TIM_ClearITPendingBit
(
TIM2
,
TIM_IT_Update
);
TIM_ITConfig
(
TIM2
,
TIM_IT_Update
,
DISABLE
);
TIM_SetCounter
(
TIM2
,
0
);
TIM_Cmd
(
TIM2
,
DISABLE
);
rt_timer_stop
(
&
timer
);
}
void
prvvTIMERExpiredISR
(
void
)
{
(
void
)
pxMBMasterPortCBTimerExpired
();
(
void
)
pxMBMasterPortCBTimerExpired
();
}
void
TIM2_IRQHandler
(
void
)
static
void
timer_timeout_ind
(
void
*
parameter
)
{
rt_interrupt_enter
();
if
(
TIM_GetITStatus
(
TIM2
,
TIM_IT_Update
)
!=
RESET
)
{
TIM_ClearFlag
(
TIM2
,
TIM_FLAG_Update
);
//清中断标记
TIM_ClearITPendingBit
(
TIM2
,
TIM_IT_Update
);
//清除定时器TIM2溢出中断标志位
prvvTIMERExpiredISR
();
}
rt_interrupt_leave
();
prvvTIMERExpiredISR
();
}
#endif
components/net/freemodbus-v1.6.0/port/user_mb_app.c
浏览文件 @
2a14e407
此差异已折叠。
点击以展开。
components/net/freemodbus-v1.6.0/port/user_mb_app.h
浏览文件 @
2a14e407
#ifndef
USER_APP
#ifndef
USER_APP
#define USER_APP
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
...
...
@@ -8,47 +8,41 @@
#include "mbutils.h"
/* -----------------------Slave Defines -------------------------------------*/
#define S_DISCRETE_INPUT_START
1
#define S_DISCRETE_INPUT_START
0
#define S_DISCRETE_INPUT_NDISCRETES 16
#define S_COIL_START
1
#define S_COIL_START
0
#define S_COIL_NCOILS 64
#define S_REG_INPUT_START
1
#define S_REG_INPUT_START
0
#define S_REG_INPUT_NREGS 100
#define S_REG_HOLDING_START
1
#define S_REG_HOLDING_START
0
#define S_REG_HOLDING_NREGS 100
//从机模式:在保持寄存器中,各个地址对应的功能定义
#define S_HD_RESERVE 0 //保留
#define S_HD_CPU_USAGE_MAJOR 1 //当前CPU利用率的整数位
#define S_HD_CPU_USAGE_MINOR 2 //当前CPU利用率的小数位
//从机模式:在输入寄存器中,各个地址对应的功能定义
#define S_IN_RESERVE 0 //保留
//从机模式:在线圈中,各个地址对应的功能定义
#define S_CO_RESERVE 2 //保留
//从机模式:在离散输入中,各个地址对应的功能定义
#define S_DI_RESERVE 1 //保留
/* salve mode: holding register's all address */
#define S_HD_RESERVE 0
#define S_HD_CPU_USAGE_MAJOR 1
#define S_HD_CPU_USAGE_MINOR 2
/* salve mode: input register's all address */
#define S_IN_RESERVE 0
/* salve mode: coil's all address */
#define S_CO_RESERVE 0
/* salve mode: discrete's all address */
#define S_DI_RESERVE 0
/* -----------------------Master Defines -------------------------------------*/
#define M_DISCRETE_INPUT_START
1
#define M_DISCRETE_INPUT_START
0
#define M_DISCRETE_INPUT_NDISCRETES 16
#define M_COIL_START
1
#define M_COIL_START
0
#define M_COIL_NCOILS 64
#define M_REG_INPUT_START
1
#define M_REG_INPUT_START
0
#define M_REG_INPUT_NREGS 100
#define M_REG_HOLDING_START
1
#define M_REG_HOLDING_START
0
#define M_REG_HOLDING_NREGS 100
//主机模式:在保持寄存器中,各个地址对应的功能定义
#define M_HD_RESERVE 0 //保留
//主机模式:在输入寄存器中,各个地址对应的功能定义
#define M_IN_RESERVE 0 //保留
//主机模式:在线圈中,各个地址对应的功能定义
#define M_CO_RESERVE 2 //保留
//主机模式:在离散输入中,各个地址对应的功能定义
#define M_DI_RESERVE 1 //保留
/* master mode: holding register's all address */
#define M_HD_RESERVE 0
/* master mode: input register's all address */
#define M_IN_RESERVE 0
/* master mode: coil's all address */
#define M_CO_RESERVE 0
/* master mode: discrete's all address */
#define M_DI_RESERVE 0
#endif
components/net/freemodbus-v1.6.0/port/user_mb_app_m.c
0 → 100644
浏览文件 @
2a14e407
/*
* FreeModbus Libary: user callback functions and buffer define in master mode
* Copyright (C) 2013 Armink <armink.ztl@gmail.com>
*
* 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: user_mb_app_m.c,v 1.60 2013/11/23 11:49:05 Armink $
*/
#include "user_mb_app.h"
/*-----------------------Master mode use these variables----------------------*/
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
//Master mode:DiscreteInputs variables
USHORT
usMDiscInStart
=
M_DISCRETE_INPUT_START
;
#if M_DISCRETE_INPUT_NDISCRETES%8
UCHAR
ucMDiscInBuf
[
MB_MASTER_TOTAL_SLAVE_NUM
][
M_DISCRETE_INPUT_NDISCRETES
/
8
+
1
];
#else
UCHAR
ucMDiscInBuf
[
MB_MASTER_TOTAL_SLAVE_NUM
][
M_DISCRETE_INPUT_NDISCRETES
/
8
];
#endif
//Master mode:Coils variables
USHORT
usMCoilStart
=
M_COIL_START
;
#if M_COIL_NCOILS%8
UCHAR
ucMCoilBuf
[
MB_MASTER_TOTAL_SLAVE_NUM
][
M_COIL_NCOILS
/
8
+
1
];
#else
UCHAR
ucMCoilBuf
[
MB_MASTER_TOTAL_SLAVE_NUM
][
M_COIL_NCOILS
/
8
];
#endif
//Master mode:InputRegister variables
USHORT
usMRegInStart
=
M_REG_INPUT_START
;
USHORT
usMRegInBuf
[
MB_MASTER_TOTAL_SLAVE_NUM
][
M_REG_INPUT_NREGS
];
//Master mode:HoldingRegister variables
USHORT
usMRegHoldStart
=
M_REG_HOLDING_START
;
USHORT
usMRegHoldBuf
[
MB_MASTER_TOTAL_SLAVE_NUM
][
M_REG_HOLDING_NREGS
];
/**
* Modbus master input register callback function.
*
* @param pucRegBuffer input register buffer
* @param usAddress input register address
* @param usNRegs input register number
*
* @return result
*/
eMBErrorCode
eMBMasterRegInputCB
(
UCHAR
*
pucRegBuffer
,
USHORT
usAddress
,
USHORT
usNRegs
)
{
eMBErrorCode
eStatus
=
MB_ENOERR
;
USHORT
iRegIndex
;
USHORT
*
pusRegInputBuf
;
USHORT
REG_INPUT_START
;
USHORT
REG_INPUT_NREGS
;
USHORT
usRegInStart
;
pusRegInputBuf
=
usMRegInBuf
[
ucMBMasterGetDestAddress
()
-
1
];
REG_INPUT_START
=
M_REG_INPUT_START
;
REG_INPUT_NREGS
=
M_REG_INPUT_NREGS
;
usRegInStart
=
usMRegInStart
;
/* it already plus one in modbus function method. */
usAddress
--
;
if
((
usAddress
>=
REG_INPUT_START
)
&&
(
usAddress
+
usNRegs
<=
REG_INPUT_START
+
REG_INPUT_NREGS
))
{
iRegIndex
=
usAddress
-
usRegInStart
;
while
(
usNRegs
>
0
)
{
pusRegInputBuf
[
iRegIndex
]
=
*
pucRegBuffer
++
<<
8
;
pusRegInputBuf
[
iRegIndex
]
|=
*
pucRegBuffer
++
;
iRegIndex
++
;
usNRegs
--
;
}
}
else
{
eStatus
=
MB_ENOREG
;
}
return
eStatus
;
}
/**
* Modbus master holding register callback function.
*
* @param pucRegBuffer holding register buffer
* @param usAddress holding register address
* @param usNRegs holding register number
* @param eMode read or write
*
* @return result
*/
eMBErrorCode
eMBMasterRegHoldingCB
(
UCHAR
*
pucRegBuffer
,
USHORT
usAddress
,
USHORT
usNRegs
,
eMBRegisterMode
eMode
)
{
eMBErrorCode
eStatus
=
MB_ENOERR
;
USHORT
iRegIndex
;
USHORT
*
pusRegHoldingBuf
;
USHORT
REG_HOLDING_START
;
USHORT
REG_HOLDING_NREGS
;
USHORT
usRegHoldStart
;
pusRegHoldingBuf
=
usMRegHoldBuf
[
ucMBMasterGetDestAddress
()
-
1
];
REG_HOLDING_START
=
M_REG_HOLDING_START
;
REG_HOLDING_NREGS
=
M_REG_HOLDING_NREGS
;
usRegHoldStart
=
usMRegHoldStart
;
/* if mode is read, the master will write the received date to buffer. */
eMode
=
MB_REG_WRITE
;
/* it already plus one in modbus function method. */
usAddress
--
;
if
((
usAddress
>=
REG_HOLDING_START
)
&&
(
usAddress
+
usNRegs
<=
REG_HOLDING_START
+
REG_HOLDING_NREGS
))
{
iRegIndex
=
usAddress
-
usRegHoldStart
;
switch
(
eMode
)
{
/* read current register values from the protocol stack. */
case
MB_REG_READ
:
while
(
usNRegs
>
0
)
{
*
pucRegBuffer
++
=
(
UCHAR
)
(
pusRegHoldingBuf
[
iRegIndex
]
>>
8
);
*
pucRegBuffer
++
=
(
UCHAR
)
(
pusRegHoldingBuf
[
iRegIndex
]
&
0xFF
);
iRegIndex
++
;
usNRegs
--
;
}
break
;
/* write current register values with new values from the protocol stack. */
case
MB_REG_WRITE
:
while
(
usNRegs
>
0
)
{
pusRegHoldingBuf
[
iRegIndex
]
=
*
pucRegBuffer
++
<<
8
;
pusRegHoldingBuf
[
iRegIndex
]
|=
*
pucRegBuffer
++
;
iRegIndex
++
;
usNRegs
--
;
}
break
;
}
}
else
{
eStatus
=
MB_ENOREG
;
}
return
eStatus
;
}
/**
* Modbus master coils callback function.
*
* @param pucRegBuffer coils buffer
* @param usAddress coils address
* @param usNCoils coils number
* @param eMode read or write
*
* @return result
*/
eMBErrorCode
eMBMasterRegCoilsCB
(
UCHAR
*
pucRegBuffer
,
USHORT
usAddress
,
USHORT
usNCoils
,
eMBRegisterMode
eMode
)
{
eMBErrorCode
eStatus
=
MB_ENOERR
;
USHORT
iRegIndex
,
iRegBitIndex
,
iNReg
;
UCHAR
*
pucCoilBuf
;
USHORT
COIL_START
;
USHORT
COIL_NCOILS
;
USHORT
usCoilStart
;
iNReg
=
usNCoils
/
8
+
1
;
pucCoilBuf
=
ucMCoilBuf
[
ucMBMasterGetDestAddress
()
-
1
];
COIL_START
=
M_COIL_START
;
COIL_NCOILS
=
M_COIL_NCOILS
;
usCoilStart
=
usMCoilStart
;
/* if mode is read,the master will write the received date to buffer. */
eMode
=
MB_REG_WRITE
;
/* it already plus one in modbus function method. */
usAddress
--
;
if
((
usAddress
>=
COIL_START
)
&&
(
usAddress
+
usNCoils
<=
COIL_START
+
COIL_NCOILS
))
{
iRegIndex
=
(
USHORT
)
(
usAddress
-
usCoilStart
)
/
8
;
iRegBitIndex
=
(
USHORT
)
(
usAddress
-
usCoilStart
)
%
8
;
switch
(
eMode
)
{
/* read current coil values from the protocol stack. */
case
MB_REG_READ
:
while
(
iNReg
>
0
)
{
*
pucRegBuffer
++
=
xMBUtilGetBits
(
&
pucCoilBuf
[
iRegIndex
++
],
iRegBitIndex
,
8
);
iNReg
--
;
}
pucRegBuffer
--
;
/* last coils */
usNCoils
=
usNCoils
%
8
;
/* filling zero to high bit */
*
pucRegBuffer
=
*
pucRegBuffer
<<
(
8
-
usNCoils
);
*
pucRegBuffer
=
*
pucRegBuffer
>>
(
8
-
usNCoils
);
break
;
/* write current coil values with new values from the protocol stack. */
case
MB_REG_WRITE
:
while
(
iNReg
>
1
)
{
xMBUtilSetBits
(
&
pucCoilBuf
[
iRegIndex
++
],
iRegBitIndex
,
8
,
*
pucRegBuffer
++
);
iNReg
--
;
}
/* last coils */
usNCoils
=
usNCoils
%
8
;
/* xMBUtilSetBits has bug when ucNBits is zero */
if
(
usNCoils
!=
0
)
{
xMBUtilSetBits
(
&
pucCoilBuf
[
iRegIndex
++
],
iRegBitIndex
,
usNCoils
,
*
pucRegBuffer
++
);
}
break
;
}
}
else
{
eStatus
=
MB_ENOREG
;
}
return
eStatus
;
}
/**
* Modbus master discrete callback function.
*
* @param pucRegBuffer discrete buffer
* @param usAddress discrete address
* @param usNDiscrete discrete number
*
* @return result
*/
eMBErrorCode
eMBMasterRegDiscreteCB
(
UCHAR
*
pucRegBuffer
,
USHORT
usAddress
,
USHORT
usNDiscrete
)
{
eMBErrorCode
eStatus
=
MB_ENOERR
;
USHORT
iRegIndex
,
iRegBitIndex
,
iNReg
;
UCHAR
*
pucDiscreteInputBuf
;
USHORT
DISCRETE_INPUT_START
;
USHORT
DISCRETE_INPUT_NDISCRETES
;
USHORT
usDiscreteInputStart
;
iNReg
=
usNDiscrete
/
8
+
1
;
pucDiscreteInputBuf
=
ucMDiscInBuf
[
ucMBMasterGetDestAddress
()
-
1
];
DISCRETE_INPUT_START
=
M_DISCRETE_INPUT_START
;
DISCRETE_INPUT_NDISCRETES
=
M_DISCRETE_INPUT_NDISCRETES
;
usDiscreteInputStart
=
usMDiscInStart
;
/* it already plus one in modbus function method. */
usAddress
--
;
if
((
usAddress
>=
DISCRETE_INPUT_START
)
&&
(
usAddress
+
usNDiscrete
<=
DISCRETE_INPUT_START
+
DISCRETE_INPUT_NDISCRETES
))
{
iRegIndex
=
(
USHORT
)
(
usAddress
-
usDiscreteInputStart
)
/
8
;
iRegBitIndex
=
(
USHORT
)
(
usAddress
-
usDiscreteInputStart
)
%
8
;
/* write current discrete values with new values from the protocol stack. */
while
(
iNReg
>
1
)
{
xMBUtilSetBits
(
&
pucDiscreteInputBuf
[
iRegIndex
++
],
iRegBitIndex
,
8
,
*
pucRegBuffer
++
);
iNReg
--
;
}
/* last discrete */
usNDiscrete
=
usNDiscrete
%
8
;
/* xMBUtilSetBits has bug when ucNBits is zero */
if
(
usNDiscrete
!=
0
)
{
xMBUtilSetBits
(
&
pucDiscreteInputBuf
[
iRegIndex
++
],
iRegBitIndex
,
usNDiscrete
,
*
pucRegBuffer
++
);
}
}
else
{
eStatus
=
MB_ENOREG
;
}
return
eStatus
;
}
#endif
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录