一、硬件设计
(1)、主体方案
主控采用GD32F303,显示驱动采用HT16C23,电源为开关电源,采样转换芯片采用电量计量芯片RN8302,掉电保护采用内部flash和EEPROM,支持RS485通讯接口;
(2)、显示
显示采用笔段式液晶屏,驱动芯片采用HT16C23,与MCU采用IIC协议进行通讯,本次开发采用硬件IIC,不用模拟;
(3)、通讯
通讯采样RS485接口,位于电源板,采用modbus协议
(4)、采样
(5)、电源
电源采样开关电源,输出12V、5V、和3.3V
二、软件设计
(1)、HT16C23接口
//初始化背光控制并点亮屏幕
void back_light_config(void)
{
rcu_periph_clock_enable(RCU_GPIOB);
gpio_init(GPIOB,GPIO_MODE_OUT_PP,GPIO_OSPEED_MAX,GPIO_PIN_5);
BG=1;
}
void HT16C23_interface_set(void)
{
//使能时钟
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_I2C1);
//采用标准I2C协议
gpio_init(GPIOB,GPIO_MODE_AF_OD,GPIO_OSPEED_MAX,GPIO_PIN_10);
gpio_init(GPIOB,GPIO_MODE_AF_OD,GPIO_OSPEED_MAX,GPIO_PIN_11);
//设置I2C1的时钟为400KHz
i2c_clock_config(I2C1,400000,I2C_DTCY_2);
//设置为I2C模式和GD32F303 的地址
i2c_mode_addr_config(I2C1,I2C_I2CMODE_ENABLE,I2C_ADDFORMAT_7BITS,0x7c);//0x3e
//使能I2C1和应答信号
i2c_enable(I2C1);
i2c_ack_config(I2C1,I2C_ACK_ENABLE);
}
void HT16C23_byte_write(u8 command, u8 command_set)
{
//等待I2C1释放总线
while(i2c_flag_get(I2C1, I2C_FLAG_I2CBSY));
//GD32F303产生一个起始信号,等待起始信号发送完成
i2c_start_on_bus(I2C1);
while(!i2c_flag_get(I2C1, I2C_FLAG_SBSEND));
//发送从机写地址,等待发送完成,并清除标志
i2c_master_addressing(I2C1, 0x7c, I2C_TRANSMITTER);//0x3e
while(!i2c_flag_get(I2C1, I2C_FLAG_ADDSEND));
i2c_flag_clear(I2C1,I2C_FLAG_ADDSEND);
//等待发送缓冲区为空
while(SET != i2c_flag_get(I2C1, I2C_FLAG_TBE));
//发送命令,并等待发送完成
i2c_data_transmit(I2C1, command);
while(!i2c_flag_get(I2C1, I2C_FLAG_BTC));
//发送命令设置,并等待发送完成
i2c_data_transmit(I2C1, command_set);
while(!i2c_flag_get(I2C1, I2C_FLAG_BTC));
//GD32F303产生一个停止信号
i2c_stop_on_bus(I2C1);
while(I2C_CTL0(I2C1)&0x0200);
}
(2)显示相关函数
//相电压的显示界面
void show_phase_voltage(u32 ua,u32 ub,u32 uc,long long int tol)
{
u8 vol_a_0=0,vol_a_1=0,vol_a_2=0,vol_a_3=0,vol_a_4=0;
u8 vol_b_0=0,vol_b_1=0,vol_b_2=0,vol_b_3=0,vol_b_4=0;
u8 vol_c_0=0,vol_c_1=0,vol_c_2=0,vol_c_3=0,vol_c_4=0;
u8 tol_0=0,tol_1=0,tol_2=0,tol_3=0,tol_4=0,tol_5=0,tol_6=0,tol_7=0,tol_8=0;
//显示‘U’和**
Display_RAM_write_byte(0x80,seg_ram(12),0x49);
LCD_wait_standby_state();
Display_RAM_write_byte(0x80,seg_ram(13),0x89);
LCD_wait_standby_state();
//显示‘a’
Display_RAM_write_byte(0x80,seg_ram(14),0x80);
LCD_wait_standby_state();
//显示‘b’和‘c’
Display_RAM_write_byte(0x80,seg_ram(16),0x22);
LCD_wait_standby_state();
//显示‘KV’、‘KWH’、‘TOTAL’
if(ua>=1000000||ub>=1000000||uc>=1000000)
{
Display_RAM_write_byte(0x80,seg_ram(1),lcd_bit(1));
LCD_wait_standby_state();
Display_RAM_write_byte(0x80,seg_ram(43),lcd_bit(7));
LCD_wait_standby_state();
Display_RAM_write_byte(0x80,seg_ram(17),lcd_bit(7));
LCD_wait_standby_state();
vol_a_0=ua/10000/1000;
vol_a_1=(ua-vol_a_0*10000*1000)/1000/1000;
vol_a_2=(ua-vol_a_0*10000*1000-vol_a_1*1000*1000)/100/1000;
vol_a_3=(ua-vol_a_0*10000*1000-vol_a_1*1000*1000-vol_a_2*100*1000)/10/1000;
vol_a_4=(ua-vol_a_0*10000*1000-vol_a_1*1000*1000-vol_a_2*100*1000-vol_a_3*10*1000)/1000;
vol_b_0=ub/10000/1000;
vol_b_1=(ub-vol_b_0*10000*1000)/1000/1000;
vol_b_2=(ub-vol_b_0*10000*1000-vol_b_1*1000*1000)/100/1000;
vol_b_3=(ub-vol_b_0*10000*1000-vol_b_1*1000*1000-vol_b_2*100*1000)/10/1000;
vol_b_4=(ub-vol_b_0*10000*1000-vol_b_1*1000*1000-vol_b_2*100*1000-vol_b_3*10*1000)/1000;
vol_c_0=uc/10000/1000;
vol_c_1=(uc-vol_c_0*10000*1000)/1000/1000;
vol_c_2=(uc-vol_c_0*10000*1000-vol_c_1*1000*1000)/100/1000;
vol_c_3=(uc-vol_c_0*10000*1000-vol_c_1*1000*1000-vol_c_2*100*1000)/10/1000;
vol_c_4=(uc-vol_c_0*10000*1000-vol_c_1*1000*1000-vol_c_2*100*1000-vol_c_3*10*1000)/1000;
tol_0=tol/100000000;
tol_1=(tol-tol_0*100000000)/10000000;
tol_2=(tol-tol_0*100000000-tol_1*10000000)/1000000;
tol_3=(tol-tol_0*100000000-tol_1*10000000-tol_2*1000000)/100000;
tol_4=(tol-tol_0*100000000-tol_1*10000000-tol_2*1000000-tol_3*100000)/10000;
tol_5=(tol-tol_0*100000000-tol_1*10000000-tol_2*1000000-tol_3*100000-tol_4*10000)/1000;
tol_6=(tol-tol_0*100000000-tol_1*10000000-tol_2*1000000-tol_3*100000-tol_4*10000-tol_5*1000)/100;
tol_7=(tol-tol_0*100000000-tol_1*10000000-tol_2*1000000-tol_3*100000-tol_4*10000-tol_5*1000-tol_6*100)/10;
tol_8=(tol-tol_0*100000000-tol_1*10000000-tol_2*1000000-tol_3*100000-tol_4*10000-tol_5*1000-tol_6*100-tol_7*10);
//显示AB的电压
Display_RAM_write_byte(0x80,seg_ram(11),num_ab_hig[vol_a_0]|(num_ab_hig[vol_b_0]>>4));
Display_RAM_write_byte(0x80,seg_ram(10),num_ab_low[vol_a_0]|(num_ab_low[vol_b_0]>>4));
Display_RAM_write_byte(0x80,seg_ram(9),num_ab_hig[vol_a_1]|(num_ab_hig[vol_b_1]>>4));
Display_RAM_write_byte(0x80,seg_ram(8),num_ab_low[vol_a_1]|(num_ab_low[vol_b_1]>>4));
Display_RAM_write_byte(0x80,seg_ram(7),num_ab_hig[vol_a_2]|(num_ab_hig[vol_b_2]>>4));
Display_RAM_write_byte(0x80,seg_ram(6),num_ab_low[vol_a_2]|(num_ab_low[vol_b_2]>>4)|lcd_bit(4)|lcd_bit(0));
Display_RAM_write_byte(0x80,seg_ram(5),num_ab_hig[vol_a_3]|(num_ab_hig[vol_b_3]>>4));
Display_RAM_write_byte(0x80,seg_ram(4),num_ab_low[vol_a_3]|(num_ab_low[vol_b_3]>>4));
Display_RAM_write_byte(0x80,seg_ram(3),num_ab_hig[vol_a_4]|(num_ab_hig[vol_b_4]>>4));
Display_RAM_write_byte(0x80,seg_ram(2),num_ab_low[vol_a_4]|(num_ab_low[vol_b_4]>>4));
//显示C相电压
Display_RAM_write_byte(0x80,seg_ram(48),num_c[vol_c_0]);
Display_RAM_write_byte(0x80,seg_ram(47),num_c[vol_c_1]);
Display_RAM_write_byte(0x80,seg_ram(46),num_c[vol_c_2]|lcd_bit(7));
Display_RAM_write_byte(0x80,seg_ram(45),num_c[vol_c_3]);
Display_RAM_write_byte(0x80,seg_ram(44),num_c[vol_c_4]);
//显示总电能
Display_RAM_write_byte(0x80,seg_ram(18),num_tol[tol_0]);
Display_RAM_write_byte(0x80,seg_ram(19),num_tol[tol_1]);
Display_RAM_write_byte(0x80,seg_ram(20),num_tol[tol_2]);
Display_RAM_write_byte(0x80,seg_ram(21),num_tol[tol_3]);
Display_RAM_write_byte(0x80,seg_ram(22),num_tol[tol_4]);
Display_RAM_write_byte(0x80,seg_ram(23),num_tol[tol_5]);
Display_RAM_write_byte(0x80,seg_ram(24),num_tol[tol_6]|lcd_bit(0));
Display_RAM_write_byte(0x80,seg_ram(25),num_tol[tol_7]);
Display_RAM_write_byte(0x80,seg_ram(26),num_tol[tol_8]);
}
//显示‘V’、‘KWH’、‘TOTAL’
else
{
Display_RAM_write_byte(0x80,seg_ram(1),lcd_bit(2));
LCD_wait_standby_state();
Display_RAM_write_byte(0x80,seg_ram(43),lcd_bit(7));
LCD_wait_standby_state();
Display_RAM_write_byte(0x80,seg_ram(17),lcd_bit(7));
LCD_wait_standby_state();
vol_a_0=ua/10000;
vol_a_1=(ua-vol_a_0*10000)/1000;
vol_a_2=(ua-vol_a_0*10000-vol_a_1*1000)/100;
vol_a_3=(ua-vol_a_0*10000-vol_a_1*1000-vol_a_2*100)/10;
vol_a_4=(ua-vol_a_0*10000-vol_a_1*1000-vol_a_2*100-vol_a_3*10);
vol_b_0=ub/10000;
vol_b_1=(ub-vol_b_0*10000)/1000;
vol_b_2=(ub-vol_b_0*10000-vol_b_1*1000)/100;
vol_b_3=(ub-vol_b_0*10000-vol_b_1*1000-vol_b_2*100)/10;
vol_b_4=(ub-vol_b_0*10000-vol_b_1*1000-vol_b_2*100-vol_b_3*10);
vol_c_0=uc/10000;
vol_c_1=(uc-vol_c_0*10000)/1000;
vol_c_2=(uc-vol_c_0*10000-vol_c_1*1000)/100;
vol_c_3=(uc-vol_c_0*10000-vol_c_1*1000-vol_c_2*100)/10;
vol_c_4=(uc-vol_c_0*10000-vol_c_1*1000-vol_c_2*100-vol_c_3*10);
tol_0=tol/100000000;
tol_1=(tol-tol_0*100000000)/10000000;
tol_2=(tol-tol_0*100000000-tol_1*10000000)/1000000;
tol_3=(tol-tol_0*100000000-tol_1*10000000-tol_2*1000000)/100000;
tol_4=(tol-tol_0*100000000-tol_1*10000000-tol_2*1000000-tol_3*100000)/10000;
tol_5=(tol-tol_0*100000000-tol_1*10000000-tol_2*1000000-tol_3*100000-tol_4*10000)/1000;
tol_6=(tol-tol_0*100000000-tol_1*10000000-tol_2*1000000-tol_3*100000-tol_4*10000-tol_5*1000)/100;
tol_7=(tol-tol_0*100000000-tol_1*10000000-tol_2*1000000-tol_3*100000-tol_4*10000-tol_5*1000-tol_6*100)/10;
tol_8=(tol-tol_0*100000000-tol_1*10000000-tol_2*1000000-tol_3*100000-tol_4*10000-tol_5*1000-tol_6*100-tol_7*10);
//显示AB的电压
Display_RAM_write_byte(0x80,seg_ram(11),num_ab_hig[vol_a_0]|(num_ab_hig[vol_b_0]>>4));
Display_RAM_write_byte(0x80,seg_ram(10),num_ab_low[vol_a_0]|(num_ab_low[vol_b_0]>>4));
Display_RAM_write_byte(0x80,seg_ram(9),num_ab_hig[vol_a_1]|(num_ab_hig[vol_b_1]>>4));
Display_RAM_write_byte(0x80,seg_ram(8),num_ab_low[vol_a_1]|(num_ab_low[vol_b_1]>>4));
Display_RAM_write_byte(0x80,seg_ram(7),num_ab_hig[vol_a_2]|(num_ab_hig[vol_b_2]>>4));
Display_RAM_write_byte(0x80,seg_ram(6),num_ab_low[vol_a_2]|(num_ab_low[vol_b_2]>>4)|lcd_bit(4)|lcd_bit(0));
Display_RAM_write_byte(0x80,seg_ram(5),num_ab_hig[vol_a_3]|(num_ab_hig[vol_b_3]>>4));
Display_RAM_write_byte(0x80,seg_ram(4),num_ab_low[vol_a_3]|(num_ab_low[vol_b_3]>>4));
Display_RAM_write_byte(0x80,seg_ram(3),num_ab_hig[vol_a_4]|(num_ab_hig[vol_b_4]>>4));
Display_RAM_write_byte(0x80,seg_ram(2),num_ab_low[vol_a_4]|(num_ab_low[vol_b_4]>>4));
//显示C相电压
Display_RAM_write_byte(0x80,seg_ram(48),num_c[vol_c_0]);
Display_RAM_write_byte(0x80,seg_ram(47),num_c[vol_c_1]);
Display_RAM_write_byte(0x80,seg_ram(46),num_c[vol_c_2]|lcd_bit(7));
Display_RAM_write_byte(0x80,seg_ram(45),num_c[vol_c_3]);
Display_RAM_write_byte(0x80,seg_ram(44),num_c[vol_c_4]);
//显示总电能
Display_RAM_write_byte(0x80,seg_ram(18),num_tol[tol_0]);
Display_RAM_write_byte(0x80,seg_ram(19),num_tol[tol_1]);
Display_RAM_write_byte(0x80,seg_ram(20),num_tol[tol_2]);
Display_RAM_write_byte(0x80,seg_ram(21),num_tol[tol_3]);
Display_RAM_write_byte(0x80,seg_ram(22),num_tol[tol_4]);
Display_RAM_write_byte(0x80,seg_ram(23),num_tol[tol_5]);
Display_RAM_write_byte(0x80,seg_ram(24),num_tol[tol_6]|lcd_bit(0));
Display_RAM_write_byte(0x80,seg_ram(25),num_tol[tol_7]);
Display_RAM_write_byte(0x80,seg_ram(26),num_tol[tol_8]);
}
}
(3)RN8302接口
//写寄存器
u32 RN8302_reg_write(u8* pDataBuf, u8 nNum, u8 nAddr)
{
u8 i,temp;
RN8302_CS=0;
temp = nAddr|0x80;
RN8302_send_byte(temp);
for(i=0;i<nNum;i++)
{
RN8302_send_byte(pDataBuf[i]);
}
RN8302_CS=1;
return 0;
}
//读寄存器
u32 RN8302_reg_read(u8 nNum, u8 nAddr,u8 Dummy_Byte)
{
u32 Temp = 0;
u8 Temp0 = 0, Temp1 = 0, Temp2 = 0, Temp3 = 0;
RN8302_CS=0;
RN8302_send_byte(nAddr);
switch(nNum)
{
case 1:
Temp0 = RN8302_send_byte(Dummy_Byte);
Temp = Temp0;
break;
case 2:
Temp0 = RN8302_send_byte(Dummy_Byte);
Temp1 = RN8302_send_byte(Dummy_Byte);
Temp = (Temp0 << 8) | Temp1;
break;
case 3:
Temp0 = RN8302_send_byte(Dummy_Byte);
Temp1 = RN8302_send_byte(Dummy_Byte);
Temp2 = RN8302_send_byte(Dummy_Byte);
Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2;
break;
case 4:
Temp0 = RN8302_send_byte(Dummy_Byte);
Temp1 = RN8302_send_byte(Dummy_Byte);
Temp2 = RN8302_send_byte(Dummy_Byte);
Temp3 = RN8302_send_byte(Dummy_Byte);
Temp = (Temp0 << 24) | (Temp1 << 16) | (Temp2 << 8) | Temp3;
break;
default:
break;
}
RN8302_CS=1;
return Temp;
}
三、总结
整体功能还在调试中,基本通讯和相关参数显示均已完成,
|
|