【瑞萨 RA6M4】快速傅里叶变换(FFT)测试(2)
【瑞萨 RA6M4】定时器实现SPWM(3)
【瑞萨 RA6M4】基于RS232 接口的 Modbus-RTU 从机实现 (4)
【瑞萨 RA6M4】基于FSP的FreeRTOS移植 (5)
1、modbus 协议是工业运用比较成熟的通信协议,本例基于瑞萨RA6M4单片机进行modbus协议的实现,开源的modbus 协议较多,本例以移植Xtiny-Modbus为展示:
(1)、第一步:搭建硬件环境
由于开发板没有带串口,需要外接一个串口收发模块
(2)、第二步:下载开源的源码,下载地址:Xtiny-Modbus移植示例
(3)、第三步:建立工程,配置时钟
由于外部高速晶振24MHz没有焊接,需要配置为内部晶振16MHz,然后再2分频
(4)、第四步:配置串口
设置波特率、回调函数、中断优先级
(5)、第五步:配置定时器
设置定时器计时的周期,回调函数、中断优先级
(6)、第六步:编写串口驱动函数
#include "usart3.h"#include "Sys_Config.h" #if MD_USD_SALVE #include "MDS_RTU_Serial.h" #else #include "MDM_RTU_Serial.h" #include "MD_RTU_SysInterface.h" #include "MDM_RTU_Fun.h" #endif 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<len;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); #if !MD_RTU_USED_OS #if MD_USD_SALVE MDSSerialRecvByte(data_r); #else #if MDM_USD_USART3 MDMSerialRecvByte(data); #endif #endif #else extern Modbus_RTU modbus_RTU; MD_RTU_MsgPut((PModbusBase)(&modbus_RTU), MD_RTU_MSG_HANDLE_ARG(&modbus_RTU),(void*)(data),0); #endif break; case UART_EVENT_TX_COMPLETE: flag=true; break; default: break; } }
复制代码#include "tim3.h"#include "Sys_Config.h" #if MD_USD_SALVE #include "MDS_RTU_Serial.h" //#include "MDS_RTU_Serial_1.h" #else #include "MDM_RTU_Serial.h" #endif 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++; #if !MD_RTU_USED_OS #if MD_USD_SALVE MDSTimeHandler100US(sys_tick_100us); #else MDMTimeHandler100US(sys_tick_100us); #endif #endif } }
复制代码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); }
复制代码#include "hal_data.h"#include "tim3.h" #include "Sys_Config.h" #if MD_USD_SALVE #include "MDS_RTU_APP.h" #else #include "MDM_RTU_APP.h" #include "MDM_RTU_Fun.h" #include "MDM_RTU_User_Fun.h" #endif 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 */ #if MD_RTU_USED_OS OSInit(); #endif //delay_init(); #if MD_USD_SALVE MDS_RTU_APPInit(); #else MDM_RTU_APPInit(); #endif TIM3_Int_Init(); #if MD_RTU_USED_OS task1=OSCreateTask(mdTestTask0,NULL,6,256); task2=OSCreateTask(mdTestTask1,NULL,6,256); SysTick_Config(SystemCoreClock / OS_TICKS_PER_SEC); OSStart(); #endif while(1){ #if !MD_RTU_USED_OS #if MD_USD_SALVE MDS_RTU_Loop(); #else MDM_RTU_Loop(); MDM_RW_CtrlLoop(); #endif #endif } #if BSP_TZ_SECURE_BUILD /* Enter non-secure code */ R_BSP_NonSecureEnter(); #endif }
复制代码