stm32+CSE7761电能芯片驱动
这篇文章介绍CSE7761电能计量芯片的驱动和应用的部分程序,如需要完整解决方案(电压、电流、功率、电量、过载、过零、漏电),请私信。
spi引脚配置
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(SPI_PIN_MISO_PORT_CLK | SPI_PIN_MOSI_PORT_CLK |
SPI_PIN_SCK_PORT_CLK,
ENABLE);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = SPI_PIN_SCK;
GPIO_Init(SPI_PIN_SCK_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = SPI_PIN_MOSI;
GPIO_Init(SPI_PIN_MOSI_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Pin = SPI_PIN_MISO;
GPIO_Init(SPI_PIN_MISO_PORT, &GPIO_InitStructure);
spi读写
static uint8_t SpiInOut(uint8_t outData, BOOL w_or_r)
{
uint8_t i;
uint8_t vpdata = 0;
if (w_or_r) //spi软件模拟写
{
for (i = 0; i < 8; i++)
{
if (outData & (0x80 >> i))
MOSI_H;
else
MOSI_L;
CLK_H;
CLK_L;
}
}
else //spi软件模拟读
{
for (i = 0; i < 8; i++)
{
CLK_H;
(vpdata) <<= 1;
if (ReadMISO != Bit_SET)
(vpdata) |= 1;
CLK_L;
}
vpdata = (~vpdata);
}
return vpdata;
}
电能芯片读写
Error_code_t spi_read(u8 addr, u8 *dat, u8 len, u8 channel, u8 check)
{
CS_ENABLE(channel);//片选
SpiInOut(addr & 0x7f,TRUE);//写待读寄存器地址
CS_DISABLE(channel);
return RET_POW_SUC;
}
Error_code_t spi_write(u8 addr, u8 *dat, u8 len, const u8 channel)
{
CS_ENABLE(channel);
//写使能命令,使能写操作
SpiInOut(0xea, TRUE);
SpiInOut(0xe5, TRUE);
CS_DISABLE(channel);
CS_ENABLE(channel);
SpiInOut(addr | 0x80, TRUE);
for (char i = len-1; i >=0; i--)
SpiInOut(dat[i], TRUE);
CS_DISABLE(channel);
spi_read(addr,(u8*)&temp_read,2,channel);
return RET_POW_SUC;
}
电能芯片寄存器配置
Error_code_t set_powercheck_ic(CPowerCheck *c_ics, const u32 m_ch)
{
//系统控制寄存器
//计量控制寄存器
//中断配置
}
电压读取
Error_code_t read_ch_vol(u16 *Vol, u8 ch)
{
u32 temp_vol = 0;
u32 check_data = 0;
spi_read(RMSU_CFG, (u8 *)&temp_vol, 3, ch); //读取电压值
spi_read(RDATA_CFG, (u8 *)&check_data, 3, ch); //读取校验值
if (temp_vol == check_data)
{
temp_vol = (temp_vol & 0x800000) ? 0 : temp_vol;//最高位为1时,作为0处理
*Vol = (u16)((((uint64_t)temp_vol * m_para[ch - 1].vol_para)) >> 22)/100;//单位V
return RET_POW_SUC;
}
else
{
return RET_POW_FAL;
}
}