概述
系统的规划界面见第一页,大致分为三类页面: - 数据刷新页面 - 寄存器设置界面 - 其他辅助界面
系统初始化
由于串口1是主串口,切换到I2C后,将无法使用上位机的串口连接,只能通过TF卡刷机,因此我们的方法是第一屏显示一个LOGO界面,然后初始化函数放在“进入”按钮的事件中,并且在按钮status状态里面设置一个定时事件,这样无论手工点击进入还是自动延时进入,都会执行初始化函数;同时在刚上电的时候,系统可以通过串口连接上位机,完成ROM更新;
void system_init(){ //系统硬件初始化
int a;
//E1- 4052 切换
gpio_mode(0,1);//设置E1为输出
gpio_out(0,0); //输出低电平,切换到第1路
gpio_mode(1,1);//设置E2为输出
gpio_out(1,1); //输出高电平,1路的CC1空载;高电平时cc1接5.1K
gpio_mode(2,1);//设置E3为输出
gpio_out(2,1); //输出高电平,2路的CC1空载;高电平时cc1接5.1K
i2c_init(0,1,0x3c);//串口0
a=i2c_recvbyte(1,1); //读取版本号
if (a==0){
//cls(0);
ds(16,0,0,"未发现充电器设备!",1);
return;
}
}
数据采集获取
按照shmictrl的开发规范,每个页面都首先调用appbase控件,也可以理解为全局控件,因此数据的采集和处理要放在appbase控件中;因此数据采集需要放在appbase控件中,采集代码如下:
int status=1310720; //通过appbase的status属性设置定时,系统会0.3秒左右调用一次ontimer()事件
void ontimer()
{ //在此书写有关定期器对数据的修改代码
readval();
}
因此系统无论在哪个页面,都会每隔0.3秒左右调用一次readval()函数,因此我们可以在readval()函数中书写读取I2C接口获取电压电流参数的代码;
//-----下面在appbase中设置属性(全局变量),以方便其他代码直接调用------
int inV=0; //输入电压,单位mV
int V1=0; //1路输出电压,单位mV
int A1=0; //1路输出电流,单位mA
int XY1=0; //1路协议
int V2=0; //2路输出电压,单位mV
int A2=0; //2路输出电流,单位mA
int XY2=0; //2路协议
void on1sdraw(){} //用于数据刷新后界面继承
void readval() //获取i2c的快捷值,1秒一次
{ int a;
int b;
str s;
gpio_out(0,0); //输出低电平,切换到第1路
i2c_sendbyte(0x3a,2,1);
//a=i2c_recvbyte(0x03,1);b=i2c_recvbyte(0x04,1);
//a=(a<<4)+(b>>4);
a=i2c_recvbyte(0x3B,1);b=i2c_recvbyte(0x3c,1);
a=(a<<4)+(b&0x0f);
V1=a*6; //Buck输出电压
i2c_sendbyte(0x3a,3,1);
a=i2c_recvbyte(0x3B,1);b=i2c_recvbyte(0x3c,1);
a=(a<<4)+(b&0x0f);
A1=a*2.5; //3B精密读取电流
a=i2c_recvbyte(0x30,1);
inV=a*160;//输入电压:(mV)
a=i2c_recvbyte(0x06,1);
XY1=a&0x0f; //协议
if ((XY1==5)|(XY1==6)){
gpio_out(1,0); //输出低电平,1路的CC1空载;
}
else{
gpio_out(1,1); //输出高电平,cc1接5.1K
}
gpio_out(0,1); //输出高电平,切换到第2路
i2c_sendbyte(0x3a,2,1);
a=i2c_recvbyte(0x3B,1);b=i2c_recvbyte(0x3c,1);
a=(a<<4)+(b&0x0f);
V2=a*6; //Vout输出电压
i2c_sendbyte(0x3a,3,1);
a=i2c_recvbyte(0x3B,1);b=i2c_recvbyte(0x3c,1);
a=(a<<4)+(b&0x0f);
A2=a*2.5; //3B精密读取电流
a=i2c_recvbyte(0x06,1);
XY2=a&0x0f; //协议
if ((XY2==5)|(XY2==6)){
gpio_out(2,0); //输出低电平,1路的CC1空载;
}
else{
gpio_out(2,1); //输出高电平,cc1接5.1K
}
on1sdraw();//界面刷新
}
代码中,首先通过gpio_out语句切换CD4052电子开关选择是哪路充电芯片,然后按照SW3526官方寄存器资料读取电压电流等参数;值得注意的是SW3526在C口使用PD协议的时候,如果是按照A口的电路,则可能导致拔掉USB线后电压不能恢复到5V;因此我们通过:
if ((XY1==5)|(XY1==6)){
gpio_out(1,0); //输出低电平,1路的CC1空载;
}
else{
gpio_out(1,1); //输出高电平,cc1接5.1K
}
首先,XY1=5 表示是PD FIX 协议;XY1=6是PD PPS协议,而PD协议必须使用C口才能触发,而A口是无法触发PD协议的,因此系统在识别出PD协议后,一定是使用C口触发的,因此立即改变CC1的接法,完成对应的A、C口适应;官方的SW3526芯片是无法做到这点的,这需要我们外部程序来辅助;
readval()函数最后调用on1sdraw();而在appbase原控件中,on1sdraw()方法是空代码,也就是说,这个函数是在页面代码中来继承的,通过继承,可以在页面代码中继承这个函数书写界面控件属性刷新的代码,这样读取的数据可以迅速刷新到界面中;
数据刷新页面
//在本页面代码中添加数据刷新函数
void app.on1sdraw(){
float v;
float a;
float b;
float w;
int ww;
lv.text=itos(app.V1,4,3)+"V";
la.text=itos(app.A1,4,3)+"A";
v=app.V1/1000.0;
a=app.A1/1000.0;
w=v*a;
lw.text=ftos(w,2)+"W";
if (a==0){
lr.text="---";
}
else{
b=v/a;
lr.text=ftos(b,2)+"欧";
}
linv.text=itos(app.inV,4,2)+"V";
lxy.text=app.getxy(app.XY1);
if (type==0) {c1.set(app.V1,app.A1,0,0);}
else{
ww=w*1000;
if (type==1) {c1.set(ww,app.A1,0,0);}
if (type==2) {c1.set(ww,app.V1,0,0);}
}
}
在前面数据采集获取中,appbase中在采集数据后调用on1sdraw()方法,因此我们在页面代码中继承函数,void app.on1sdraw();因此在此函数中,我们通过比如:
lv.text=itos(app.V1,4,3)+"V";
将appbase中获取的全局变量的电压值转换显示格式后赋值给lv.text完成显示;其他代码也都是完成界面刷新的,尤其是最后的曲线数据的刷新代码;
寄存器设置界面
首先在页面代码中设置一个全局变量route,用于确定当前读取的是哪一个I2C的数据。
int route=0; //=0 A路 =1表示B路
void pageinit(){
//页面初始化
int a;
gpio_out(0,route);
a=i2c_recvbyte(0xA8,1);
l2.num=a;
s0.val=1-(a&1);
s1.val=1-(a>>1)&1;
s2.val=1-(a>>2)&1;
s3.val=1-(a>>3)&1;
s4.val=1-(a>>4)&1;
s5.val=1-(a>>5)&1;
s7.val=1-(a>>7)&1;
}
pageinit();
在页面进入后,调用pageinit();函数,读取寄存器后,然后刷新界面;当用户点击“应用”按钮时,
void sk4.onclick()
{
int a=0;
gpio_out(0,route);
a=a|(1-s0.val);
a=a|((1-s1.val)<<1);
a=a|((1-s2.val)<<2);
a=a|((1-s3.val)<<3);
a=a|((1-s4.val)<<4);
a=a|((1-s5.val)<<5);
a=a|((1-s7.val)<<7);
l3.num=a;
i2c_sendbyte(0x12,0x20,1);
i2c_sendbyte(0x12,0x40,1);
i2c_sendbyte(0x12,0x80,1);
i2c_sendbyte(0xa8,a,1);
pageinit();
}
通过界面控件的参数合成数据,写入I2C寄存器
点击“切换到B路”按钮,通过代码切换route变量,完成线路切换
void scw.onclick()
{
if (route==0){
scw.text="切换到B路";
l1.text="A 路协议设置1";
route=1;
}
else{
scw.text="切换到A路";
l1.text="B 路协议设置1";
route=0;
}
pageinit();
}