【简介】
本地在压测过程中需要使用继电器模块,手头正好有个 DockerPi 4 继电器。查看继电器的使用手册用起来是很简单对应的I2C通信接口来控制继电器。以下是 DockerPi 4 的Feature 说明对应模块有四路的的继电器通路,硬件上通过I2C的接口来控制支持3A 250V AC和3A 30V DC 的参数。

对应寄存器模块的I2C 7bit 的访问地址可以通过拨码开关来配置,默认拨码地址为0x10.

对应的寄存器配置也很简单每每个通道对应一个寄存器地址,写入0关闭 1/255 开启。

本地通过瑞萨的RA6M4 的开发板来控制该寄存器模组配置好I2C接口即可 控制 DockerPi 4 模块,对应的I2C配置如下:


配置完成后后添加如下的测试代码来控制继电器。
#include <string.h>
#include <stdlib.h>
#include "dev_i2c.h"
#include "bsp_api.h"
#include "hal_data.h"
/*==================================================================================================
* LOCAL CONSTANTS
*================================================================================================*/
/*==================================================================================================
* LOCAL FUNCTIONS
*================================================================================================*/
/*==================================================================================================
* LOCAL VARIABLES
*================================================================================================*/
static uint8_t i2c_init = 0;
volatile i2c_master_event_t g_i2c_callback_event;
/*==================================================================================================
* LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS)
*================================================================================================*/
/*==================================================================================================
* LOCAL FUNCTION PROTOTYPES
*================================================================================================*/
int32_t ra6m4_i2c_master_xfer(struct dev_i2c_bus *bus,
struct dev_i2c_msg *msgs,
uint32_t num)
{
/* Set i2c slave address */
R_SCI_I2C_SlaveAddressSet(&g_i2c3_ctrl, msgs[0].addr, I2C_MASTER_ADDR_MODE_7BIT);
for(uint32_t i = 0; i < num; i++)
{
if((msgs[i].flags == DEV_I2C_RD) == 0)
{
printf("I2C write.\r\n");
R_SCI_I2C_Write(&g_i2c3_ctrl, msgs[i].buf, msgs[i].len, true);
}
else
{
printf("I2C read.\r\n");
/* read */
R_SCI_I2C_Read(&g_i2c3_ctrl, msgs[i].buf, msgs[i].len, true);
}
}
return 0;
}
static int i2c_probe(char addr)
{
fsp_err_t err;
if(i2c_init == 0)
{
err = R_SCI_I2C_Open(&g_i2c3_ctrl,&g_i2c3_cfg);
if(FSP_SUCCESS != err)
{
mini_printf("i2c init failed %d \r\n",err);
}
else
{
i2c_init = 1;
}
}
if(i2c_init)
{
/* Send data to I2C slave on the same channel */
R_SCI_I2C_SlaveAddressSet(&g_i2c3_ctrl, addr, I2C_MASTER_ADDR_MODE_7BIT);
static uint8_t data;
data = 0x00;
uint32_t timeout = 0x1000;
/* Send data to I2C slave */
g_i2c_callback_event = I2C_MASTER_EVENT_ABORTED;
err = R_SCI_I2C_Write(&g_i2c3_ctrl, &data, 1, true);
if(FSP_SUCCESS != err)
{
mini_printf("i2c write failed %d \r\n",err);
}
/* Since there is nothing else to do, block until Callback triggers*/
while ((I2C_MASTER_EVENT_TX_COMPLETE != g_i2c_callback_event) && timeout)
{
timeout--;
}
}
return (g_i2c_callback_event == I2C_MASTER_EVENT_TX_COMPLETE) ? 1 : 0 ;
}
static void i2c_scan(uint8_t start_addr, uint8_t stop_addr)
{
mini_printf(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F");
uint8_t pos = start_addr <= 0xF? 0x00: start_addr & 0xF;
for(; pos < stop_addr; pos++)
{
if((pos & 0xF) == 0)
{
printf("\r\n%02X: ", pos);
}
if(pos < start_addr)
{
mini_printf(" ");
continue;
}
if( i2c_probe(pos) == 1)
{
printf("%02X", pos);
}
else
{
printf("--");
}
printf(" ");
}
printf("\r\n");
}
/*==================================================================================================
* GLOBAL VARIABLES
*================================================================================================*/
/*==================================================================================================
* GLOBAL CONSTANTS
*================================================================================================*/
/*==================================================================================================
* GLOBAL FUNCTIONS
*================================================================================================*/
void sci_i2c_master_callback(i2c_master_callback_args_t *p_args)
{
switch(p_args->event)
{
case I2C_MASTER_EVENT_TX_COMPLETE:
g_i2c_callback_event = I2C_MASTER_EVENT_TX_COMPLETE;
break;
case I2C_MASTER_EVENT_ABORTED:
break;
default:
break;
}
}
unsigned int i2c(char argc, char **argv)
{
if(strcmp(argv[1],"scan") == 0)
{
i2c_scan(0x00,0x7f);
}
else if(strcmp(argv[1],"send") == 0)
{
static struct dev_i2c_msg msg;
msg.addr = myatoi(argv[2]);
msg.flags = DEV_I2C_WR;
msg.len = 2;
static uint8_t data[2];
data[0] = myatoi(argv[3]);
data[1] = myatoi(argv[4]);
msg.buf = &data[0];
ra6m4_i2c_master_xfer(NULL, &msg, 1);
}
else if(strcmp(argv[1],"recv") == 0)
{
static struct dev_i2c_msg msg;
msg.addr = myatoi(argv[2]);
msg.flags = DEV_I2C_RD;
msg.len = 1;
static uint8_t data;
msg.buf = &data;
ra6m4_i2c_master_xfer(NULL, &msg, 1);
printf("recv data: %02x\r\n", data);
}
return 0;
}通过 i2c scan 接口读取到I2C 0X10 的地址状态信息。

本地试验通过i2c send 控制四路继电器的吸合和关闭。

我要赚赏金
