STM32+BL0939计量芯片驱动程序
本文章介绍BL0939计量芯片基本驱动程序,如需完整方案(电压、电流、功率、电量、过载、过零、漏电)请私信。
串口配置
void BL_Config(void)
{
USART_DeInit(USART2);//复位串口
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE); //GPIOD时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);//使能USART2
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//使能重映射
GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);//IO映射
//USART2_TX GPIOD.5
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //PD.5
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //频率50M
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOD, &GPIO_InitStructure); //初始化GPIOA.2
GPIO_SetBits(GPIOD, GPIO_Pin_5);
//USART2_RX GPIOD.6
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //PD6
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_Init(GPIOD, &GPIO_InitStructure); //初始化GPIOA.3
//USART2初始化配置
USART_InitStructure.USART_BaudRate = 4800; //波特率4800
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据8位
USART_InitStructure.USART_StopBits = USART_StopBits_1_5; //1.5位停止位
USART_InitStructure.USART_Parity = USART_Parity_No; //无校验
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(USART2, &USART_InitStructure); //初始化UART2
//USART2 NVIC初始化
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure);
USART_ClearFlag(USART2, USART_FLAG_TC);
USART_ClearFlag(USART2, USART_FLAG_IDLE);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); //开启接收中断,RXNE读寄存器非空
USART_ITConfig(USART2, USART_IT_IDLE, ENABLE); //使能接收一帧数据中断
USART_ITConfig(USART2, USART_IT_TC, ENABLE); //开启发送中断,TC发送完成
USART_Cmd(USART2, ENABLE); //使能串口2
串口读
BOOL BL_Read(u8 wReg, u8 ch)
{
memset(RnSend.Data, 0, sizeof(RnSend.Data)); //清空发送缓存数组
memset(RnRece.Data, 0, sizeof(RnRece.Data)); //清空接收缓存数组
RnSend.Data[0] = BUS_ADDR[(ch-1)/2] | 0x50;//读命令+从机地址
RnSend.Data[1] = wReg;
RnSend.Len = 2;
RnSend.HaveSenLen = 1;
BL_Send();
return Block_Send();
}
串口写
BOOL BL_Write(u8 wReg, u8 *pBuf, u16 ucLen, u8 ch)
{
memset(RnSend.Data, 0, sizeof(RnSend.Data)); //清空发送缓存数组
u8 chksum = 0,num =0;
u8 addr = BUS_ADDR[(ch-1)/2] | 0xA0;//写命令+从机地址
chksum += addr;
RnSend.Data[num++] = addr;
chksum += wReg;
RnSend.Data[num++] = wReg;
for(u8 i=0; i<ucLen; i++)
{
RnSend.Data[num++] = pBuf[i];
chksum += pBuf[i];
}
chksum = ~chksum;
RnSend.Data[5] = chksum;
RnSend.Len = 6;//从机地址 寄存器 三字节数据 校验
RnSend.HaveSenLen = 1;
BL_Send();
return Block_Send();
}
读电压
Error_code_t read_ch_vol(u16 *Vol, u8 ch)
{
u8 temp_vol[3] = {0};
u32 temp_reg = 0;
if(ReadData(V_RMS, temp_vol, 3, ch) == RET_POW_SUC)
{
temp_reg = *(u32*)(temp_vol);
*Vol = (u16)(((double)temp_reg * 1.218 * (float)(200*5+0.24))/(79931*240));
return RET_POW_SUC;
}
return RET_POW_FAL;
}