(4)基于RS232 接口的 Modbus-RTU 从机实现
1、modbus 协议是工业运用比较成熟的通信协议,本例基于瑞萨RA6M4单片机进行modbus协议的实现,开源的modbus 协议较多,本例以移植Xtiny-Modbus为展示:
(1)第一步:搭建硬件环境
由于开发板没有带串口,需要外接一个串口收发模块
(2)第二步:下载开源的源码,下载地址:Xtiny-Modbus移植示例 https://gitee.com/zhang_en/xtiny_-modbus_test.git
(3)第三步:建立工程,配置时钟
由于外部高速晶振24MHz没有焊接,需要配置为内部晶振16MHz,然后再2分频
(4)第四步:配置串口
设置波特率、回调函数、中断优先级
(5)第五步:配置定时器
设置定时器计时的周期,回调函数、中断优先级
(6)第六步:编写串口驱动函数
volatile uint8_t flag=false;
void RS485RWConvInit(void)
{
//收发引脚配置
// R_IOPORT_Open(&g_ioport_ctrl,g_ioport.p_cfg);
// R_IOPORT_PinWrite(&g_ioport_ctrl,BSP_IO_PORT_05_PIN_03,BSP_IO_LEVEL_LOW);
}
//串口1配置
void init_usart3(void)
{
R_SCI_UART_Open(&g_uart0_ctrl,g_uart0.p_cfg);
RS485RWConvInit();
}
void usart3_send_byte(uint8_t byte)
{
R_SCI_UART_Write(&g_uart0_ctrl,(uint8_t*)(&(byte)),1);
while(flag!=true);
flag=false;
}
void usart3_send_bytes(uint8_t *bytes,int len)
{
int i;
for(i=0;i
usart3_send_byte(bytes[i]);
}
}
void usart3_send_string(char *string)
{
while(*string)
{
usart3_send_byte(*string++);
}
}
void uart_callback(uart_callback_args_t *arg)
{
uint8_t data_r;
switch(arg->event)
{
case UART_EVENT_RX_CHAR:
// R_SCI_UART_Read(&g_uart0_ctrl,(u8*)(&(data_r)),1);
data_r=(uint8_t)(arg->data);
MDSSerialRecvByte(data_r);
MDMSerialRecvByte(data);
extern Modbus_RTU modbus_RTU;
MD_RTU_MsgPut((PModbusBase)(&modbus_RTU), MD_RTU_MSG_HANDLE_ARG(&modbus_RTU),(void*)(data),0);
break;
case UART_EVENT_TX_COMPLETE:
flag=true;
break;
default:
break;
}
}
(7)第7步编写定时器驱动程序:
//#include "MDS_RTU_Serial_1.h"
volatile uint32_t sys_tick_100us=0;
void TIM3_Int_Init(void)
{
R_AGT_Open(&g_timer0_ctrl,g_timer0.p_cfg);
R_AGT_Start(&g_timer0_ctrl);
}
void timer_callback(timer_callback_args_t *arg)
{
if(arg->event==TIMER_EVENT_CYCLE_END)
// if (timer_interrupt_flag_get(TIMER5, TIMER_INT_FLAG_UP) != RESET)
{
sys_tick_100us++;
MDSTimeHandler100US(sys_tick_100us);
MDMTimeHandler100US(sys_tick_100us);
}
}
(8)第八步:编写应用程序
static void MDS_RTU_UserUpdate(void){
uint16 temp=0xff;
uint16 temp1[]={1,2,3,4,5};
MDS_RTU_WriteCoils(&modbusS_RTU,1,5,&temp);
MDS_RTU_WriteHoldReg(&modbusS_RTU,11, temp);
MDS_RTU_WriteHoldRegs(&modbusS_RTU,5,5,temp1);
}
(9)第九步:编写处理程序
FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER
/*******************************************************************************************************************//**
* main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used. This function
* is called by main() when no RTOS is used.
**********************************************************************************************************************/
void hal_entry(void)
{
/* TODO: add your own code here */
OSInit();
//delay_init();
MDS_RTU_APPInit();
MDM_RTU_APPInit();
TIM3_Int_Init();
task1=OSCreateTask(mdTestTask0,NULL,6,256);
task2=OSCreateTask(mdTestTask1,NULL,6,256);
SysTick_Config(SystemCoreClock / OS_T IC KS_PER_SEC);
OSStart();
while(1){
MDS_RTU_Loop();
MDM_RTU_Loop();
MDM_RW_CtrlLoop();
}
/* Enter non-secure code */
R_BSP_NonSecureEnter();
}
(10)第十步:连接Modbus 主机,查看结果
END
点击阅读原文,免费申请