|
一、前言:事情是这样的,很久之前买了一个降压模块,用的挺好的,3A内的模块,大概就是长下面这个样子:
二、问题识别:这个模块有以下几个问题:
1. 怎么还是数码管,它不需要在恶劣环境下工作,所以想换个液晶屏。
2. 按键太小了,这个用起来比较难扣,扣着扣着还扣坏了。
这时想到了很久之前买到的屏幕,LCD1602:这个东西是老杨家那时候买的应该是,至少得有5-6年了,就换这个屏幕上去吧。
三、分析原有模块:这个模块有一个好处,控制板是插上去的,所以直接对控制板进行抄板
因为要修改的部分就是显示部分,所以就直接看这个部分,很典型奥,就是用单片机三根线刷两片595d移位寄存器来刷屏,用逻辑分析仪抓一下:
放大来看:
可以看出每显示一次需要传输16个bit。高八位决定了显示的内容,低八位决定亮的数码管的哪一位。
然后就是对照抄板得到的接线方法,把什么代表什么找出来,得到下面的字典,最上面三行就是显示了高八位对应显示的数字是多少(这里有点无点就是说 比如8. 和 8 这样);
低八位对应四位数码管的哪一位:11 11 11 00 这是第一位,11 11 00 11 这是第二位,以此类推。
四、画电路图,画PCB:因为不想分析电源控制的部分,所以直接外挂一个单片机对这个原有的输出信号进行解码,然后输出到1602屏幕。最先选用的是QN9021,因为这个东西也就做这一个,不想用手里比较多的片子,结果发现速度跟不上,因为这个片子固化了蓝牙部分,运行耗时间严重。 最后找到一个孤品,stc15w408as,就用这个吧,内部晶振运行到35Mhz,基本采集正常。
电路板就是下面这样,这里有两个小问题,
1.一个就是这个LCD1602模块比较特殊,对比度调节是在vcc上串联一个电阻,但是画板子时没有注意到,最后直接手工补上一个680Ω电阻,对比度就正常了。
2.二个就是没有把孔位和板子原孔位对齐,不是那么美观。
五、写程序:这里程序给起来还是比较清楚的,把stcp和shcp信号都挂到中断引脚上,DS挂到普通IO口上。schp中断时存储DS数据,是16bit,两个字节;stcp中断时送入LCD1602显示,程序比较简单,把主要的这个解码的部分给出来,写的不太好,能用就行.
论坛的代码显示很不清楚,我解释一下:就是这里有几个问题是怎么解决的:
1. 原有的显示模块是一会显示电流,一会显示电压,在LCD1602上肯定是分到两行显示的,怎么确定此刻原主控输出的是电流还是电压呢?
这里做了一个BitFlag指示位, //bitflag的第五位来指示电压,第六位来指示电流,因为这个模块电流永远是0.000 到3.000 而电压是00.00到35.00,电流的小数点只会跟着第一位出现,电压的小数点只会跟着第二位出现,由此就可以分离电压和电流。
2. 即使分离了电压,其它位怎么知道是电压还是电流呢?
这里是用了OrderFlag标志位,从显示第一位时就控制标志位为1,然后是2...3...4,这样就可以把电压串成一串,电流串成一串。
3. 刷新总是有可能出错的,出错怎么解决,怎么知道在设置电压还是电流?
这里肯定有些问题没有解决,但是有个办法,就是当初发现这个lcd1602模块下方还有一颗多余的LED,(其它三颗用来指示 CC CV OUT),这颗LED连接到P54:当刷新电流时 LED1亮,当刷新电压时 LED1灭。起到一定的辅助作用。
程序搞到这里就结束了。再花时间就太多了。最终的结果见下图:
六、结果:
设置状态(电流设置,显示电流指示灯亮):
输出状态(此时正在刷新显示电压,CV 和 OUT灯亮):
- unsigned int volatile databus = 0;
- unsigned char BitFlag =0; //这两个变量要放到全局去
- unsigned char OrderFlag =1; //用来指示目前显示到哪一位了
- void give(unsigned int VALUE){
- unsigned char VALUE_HI =0;
- unsigned char VALUE_LO =0;
- //VALUE = (VALUE << 1);
- VALUE_LO = VALUE & 0xFF;
- VALUE_HI = (VALUE >> 8) & 0xFF;
- if(OrderFlag == 4){ //这个要放在第三位前面 是第四位
- if(BitFlag & 0x10){ //bitflag的第五位来指示电压,第六位来指示电流
- switch (VALUE_HI) {
- case 0x3F: //
- LCD1602_numeral_Display(0x8d,0); //给电压第四位置0
- break;
- case 0x06: //1
- LCD1602_numeral_Display(0x8d,1); //给电压第四位置1
- break;
- case 0x5B: //2
- LCD1602_numeral_Display(0x8d,2); //给电压第四位置2
- break;
- case 0x4F: //3
- LCD1602_numeral_Display(0x8d,3); //给电压第四位置3
- break;
- case 0x66: //4
- LCD1602_numeral_Display(0x8d,4); //给电压第四位置4
- break;
- case 0x6D: //5
- LCD1602_numeral_Display(0x8d,5); //给电压第四位置5
- break;
- case 0x7D: //6
- LCD1602_numeral_Display(0x8d,6); //给电压第四位置6
- break;
- case 0x07: //7
- LCD1602_numeral_Display(0x8d,7); //给电压第四位置7
- break;
- case 0x7F: //8
- LCD1602_numeral_Display(0x8d,8); //给电压第四位置8
- break;
- case 0x6F: //9
- LCD1602_numeral_Display(0x8d,9); //给电压第四位置9
- break;
- default:{
- //LCD1602_numeral_Display(0x8d,10);
- //可以显示error等调试信息
- break;}
- }
- }
- else if(BitFlag & 0x20){//bitflag的第五位来指示电压,第六位来指示电流
- switch (VALUE_HI) {
- case 0x3F: //
- LCD1602_numeral_Display(0xCd,0); //给电流第四位置0
- break;
- case 0x06: //1
- LCD1602_numeral_Display(0xCd,1); //给电流第四位置1
- break;
- case 0x5B: //2
- LCD1602_numeral_Display(0xCd,2); //给电流第四位置2
- break;
- case 0x4F: //3
- LCD1602_numeral_Display(0xCd,3); //给电流第四位置3
- break;
- case 0x66: //4
- LCD1602_numeral_Display(0xCd,4); //给电流第四位置4
- break;
- case 0x6D: //5
- LCD1602_numeral_Display(0xCd,5); //给电流第四位置5
- break;
- case 0x7D: //6
- LCD1602_numeral_Display(0xCd,6); //给电流第四位置6
- break;
- case 0x07: //7
- LCD1602_numeral_Display(0xCd,7); //给电流第四位置7
- break;
- case 0x7F: //8
- LCD1602_numeral_Display(0xCd,8); //给电流第四位置8
- break;
- case 0x6F: //9
- LCD1602_numeral_Display(0xCd,9); //给电流第四位置9
- break;
- default:{
- LCD1602_numeral_Display(0xcd,10);
- //可以显示error等调试信息
- break;}
- }
- }
- OrderFlag = 1;
- //return 0;
- }
- else if(OrderFlag == 3){ //这个要放在第二位前面 // 是第三位
- if(BitFlag & 0x10){ //bitflag的第五位来指示电压,第六位来指示电流
- switch (VALUE_HI) {
- case 0x3F: //
- LCD1602_numeral_Display(0x8c,0); //给电压第三位置0
- OrderFlag = 4;
- break;
- case 0x06: //1
- LCD1602_numeral_Display(0x8c,1); //给电压第三位置1
- OrderFlag = 4;
- break;
- case 0x5B: //2
- LCD1602_numeral_Display(0x8c,2); //给电压第三位置2
- OrderFlag = 4;
- break;
- case 0x4F: //3
- LCD1602_numeral_Display(0x8c,3); //给电压第三位置3
- OrderFlag = 4;
- break;
- case 0x66: //4
- LCD1602_numeral_Display(0x8c,4); //给电压第三位置4
- OrderFlag = 4;
- break;
- case 0x6D: //5
- LCD1602_numeral_Display(0x8c,5); //给电压第三位置5
- OrderFlag = 4;
- break;
- case 0x7D: //6
- LCD1602_numeral_Display(0x8c,6); //给电压第三位置6
- OrderFlag = 4;
- break;
- case 0x07: //7
- LCD1602_numeral_Display(0x8c,7); //给电压第三位置7
- OrderFlag = 4;
- break;
- case 0x7F: //8
- LCD1602_numeral_Display(0x8c,8); //给电压第三位置8
- OrderFlag = 4;
- break;
- case 0x6F: //9
- LCD1602_numeral_Display(0x8c,9); //给电压第三位置9
- OrderFlag = 4;
- break;
- default:{
- LCD1602_numeral_Display(0x8c,10);
- //可以显示error等调试信息
- OrderFlag = 1;
- break;}
- }
- }
- else if(BitFlag & 0x20){//bitflag的第五位来指示电压,第六位来指示电流
- switch (VALUE_HI) {
- case 0x3F: //
- LCD1602_numeral_Display(0xCc,0); //给电流第三位置0
- OrderFlag = 4;
- break;
- case 0x06: //1
- LCD1602_numeral_Display(0xCc,1); //给电流第三位置1
- OrderFlag = 4;
- break;
- case 0x5B: //2
- LCD1602_numeral_Display(0xCc,2); //给电流第三位置2
- OrderFlag = 4;
- break;
- case 0x4F: //3
- LCD1602_numeral_Display(0xCc,3); //给电流第三位置3
- OrderFlag = 4;
- break;
- case 0x66: //4
- LCD1602_numeral_Display(0xCc,4); //给电流第三位置4
- OrderFlag = 4;
- break;
- case 0x6D: //5
- LCD1602_numeral_Display(0xCc,5); //给电流第三位置5
- OrderFlag = 4;
- break;
- case 0x7D: //6
- LCD1602_numeral_Display(0xCc,6); //给电流第三位置6
- OrderFlag = 4;
- break;
- case 0x07: //7
- LCD1602_numeral_Display(0xCc,7); //给电流第三位置7
- OrderFlag = 4;
- break;
- case 0x7F: //8
- LCD1602_numeral_Display(0xCc,8); //给电流第三位置8
- OrderFlag = 4;
- break;
- case 0x6F: //9
- LCD1602_numeral_Display(0xCc,9); //给电流第三位置9
- OrderFlag = 4;
- break;
- default:{
- LCD1602_numeral_Display(0xcc,10);
- //可以显示error等调试信息
- OrderFlag = 1;
- break;}
- }
- }
- }
- else if(OrderFlag == 2){ //这个要放在第一位前面 // 是第二位
- if(BitFlag & 0x10){ //bitflag的第五位来指示电压,第六位来指示电流
- //LCD1602_String_Display(0x80,(unsigned char *)&VALUE_HI);
- switch (VALUE_HI) { //第一位里面位置判断,这个用bitflag的第五位来指示电压,第六位来指示电流
- case 0xBF: //0
- LCD1602_numeral_Display(0x8a,0); //给电压第二位置0
- OrderFlag = 3;
- break;
- case 0x86: //1
- LCD1602_numeral_Display(0x8a,1); //给电压第二位置1
- OrderFlag = 3;
- break;
- case 0xDB: //2
- LCD1602_numeral_Display(0x8a,2); //给电压第二位置2
- OrderFlag = 3;
- break;
- case 0xCF: //3
- LCD1602_numeral_Display(0x8a,3); //给电压第二位置3
- OrderFlag = 3;
- break;
- case 0xE6: //4
- LCD1602_numeral_Display(0x8a,4); //给电压第二位置4
- OrderFlag = 3;
- break;
- case 0xED: //5
- LCD1602_numeral_Display(0x8a,5); //给电压第二位置5
- OrderFlag = 3;
- break;
- //case 0x7D:
- case 0xFD: //6
- LCD1602_numeral_Display(0x8a,6); //给电压第二位置6
- OrderFlag = 3;
- break;
- case 0x87: //7
- LCD1602_numeral_Display(0x8a,7); //给电压第二位置7
- OrderFlag = 3;
- break;
- case 0xFF: //8
- LCD1602_numeral_Display(0x8a,8); //给电压第二位置8
- OrderFlag = 3;
- break;
- case 0xEF: //9
- LCD1602_numeral_Display(0x8a,9); //给电压第二位置9
- OrderFlag = 3;
- break;
- default:
- LCD1602_numeral_Display(0x8a,10);
- //可以显示error等调试信息
- OrderFlag = 1;
- break;
- }
- }
- else if(BitFlag & 0x20){//bitflag的第五位来指示电压,第六位来指示电流
- switch (VALUE_HI) {
- case 0x3F: //
- LCD1602_numeral_Display(0xCb,0); //给电流第二位置0
- OrderFlag = 3;
- break;
- case 0x06: //1
- LCD1602_numeral_Display(0xCb,1); //给电流第二位置1
- OrderFlag = 3;
- break;
- case 0x5B: //2
- LCD1602_numeral_Display(0xCb,2); //给电流第二位置2
- OrderFlag = 3;
- break;
- case 0x4F: //3
- LCD1602_numeral_Display(0xCb,3); //给电流第二位置3
- OrderFlag = 3;
- break;
- case 0x66: //4
- LCD1602_numeral_Display(0xCb,4); //给电流第二位置4
- OrderFlag = 3;
- break;
- case 0x6D: //5
- LCD1602_numeral_Display(0xCb,5); //给电流第二位置5
- OrderFlag = 3;
- break;
- case 0x7D: //6
- LCD1602_numeral_Display(0xCb,6); //给电流第二位置6
- OrderFlag = 3;
- break;
- case 0x07: //7
- LCD1602_numeral_Display(0xCb,7); //给电流第二位置7
- OrderFlag = 3;
- break;
- case 0x7F: //8
- LCD1602_numeral_Display(0xCb,8); //给电流第二位置8
- OrderFlag = 3;
- break;
- case 0x6F: //9
- LCD1602_numeral_Display(0xCb,9); //给电流第二位置9
- OrderFlag = 3;
- break;
- default:
- LCD1602_numeral_Display(0xCb,10);
- //可以显示error等调试信息
- OrderFlag = 1;
- break;
- }
- }
-
- //return 0;
- }
- else if(VALUE_LO == 0xFC && OrderFlag == 1){ //是第一位//
- //if(VALUE_LO == 0xFC ){ //是第一位//
- BitFlag = 0;
- switch (VALUE_HI) { //第一位里面位置判断,这个用bitflag的第五位来指示电压,第六位来指示电流
- case 0x3F: //
- LCD1602_numeral_Display(0x89,0); //给电压最高位置0
- BitFlag = BitFlag | 0x10; //拉高bitflag的电压位
- P54 = 1; //LED1灭
- OrderFlag = 2;
- break;
- case 0x06: //1
- LCD1602_numeral_Display(0x89,1); //给电压最高位置1
- BitFlag = BitFlag | 0x10; //拉高bitflag的电压位
- P54 = 1; //LED1灭
- OrderFlag = 2;
- break;
- case 0x5B: //2
- LCD1602_numeral_Display(0x89,2); //给电压最高位置2
- BitFlag = BitFlag | 0x10; //拉高bitflag的电压位
- P54 = 1; //LED1灭
- OrderFlag = 2;
- break;
- case 0x4F: //3
- LCD1602_numeral_Display(0x89,3); //给电压最高位置3
- BitFlag = BitFlag | 0x10; //拉高bitflag的电压位
- P54 = 1; //LED1灭
- OrderFlag = 2;
- break;
- case 0x66: //4
- LCD1602_numeral_Display(0x89,4); //给电压最高位置4
- BitFlag = BitFlag | 0x10; //拉高bitflag的电压位
- P54 = 1; //LED1灭
- OrderFlag = 2;
- break;
- case 0x6D: //5
- LCD1602_numeral_Display(0x89,5); //给电压最高位置5
- BitFlag = BitFlag | 0x10; //拉高bitflag的电压位
- P54 = 1; //LED1灭
- OrderFlag = 2;
- break;
- case 0x7D: //6
- LCD1602_numeral_Display(0x89,6); //给电压最高位置6
- BitFlag = BitFlag | 0x10; //拉高bitflag的电压位
- P54 = 1; //LED1灭
- OrderFlag = 2;
- break;
- case 0x07: //7
- LCD1602_numeral_Display(0x89,7); //给电压最高位置7
- BitFlag = BitFlag | 0x10; //拉高bitflag的电压位
- P54 = 1; //LED1灭
- OrderFlag = 2;
- break;
- case 0x7F: //8
- LCD1602_numeral_Display(0x89,8); //给电压最高位置8
- BitFlag = BitFlag | 0x10; //拉高bitflag的电压位
- P54 = 1; //LED1灭
- OrderFlag = 2;
- break;
- case 0x6F: //9
- LCD1602_numeral_Display(0x89,9); //给电压最高位置9
- BitFlag = BitFlag | 0x10; //拉高bitflag的电压位
- P54 = 1; //LED1灭
- OrderFlag = 2;
- break;
- case 0xBF: //0.
- LCD1602_numeral_Display(0xC9,0); //给电流最高位置0.
- BitFlag = BitFlag | 0x20; //拉高bitflag的电流位
- P54 = 0; //LED1亮
- OrderFlag = 2;
- break;
- case 0x86: //1.
- LCD1602_numeral_Display(0xC9,1); //给电流最高位置1.
- BitFlag = BitFlag | 0x20; //拉高bitflag的电流位
- P54 = 0; //LED1亮
- OrderFlag = 2;
- break;
- case 0xDB: //2.
- LCD1602_numeral_Display(0xC9,2); //给电流最高位置2.
- BitFlag = BitFlag | 0x20; //拉高bitflag的电流位
- P54 = 0; //LED1亮
- OrderFlag = 2;
- break;
- case 0xCF: //3.
- LCD1602_numeral_Display(0xC9,3); //给电流最高位置3.
- BitFlag = BitFlag | 0x20; //拉高bitflag的电流位
- P54 = 0; //LED1亮
- OrderFlag = 2;
- break;
- default:
- LCD1602_numeral_Display(0xC9,10);
- //可以显示error等调试信息
- P54 = 0; //LED1亮
- OrderFlag = 1;
- break;
- }
- //return 0;
- }
- else
- OrderFlag = 1;
- //return 0;
- }
复制代码
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
打赏
-
查看全部打赏
|