附件是别的大神设计制作的 我只是做分享。
STM8S003F3P6(常用的ST7565驱动)12864USB电压电流表
之前看到sabaka发的帖子“STM8S003F3表头自校准版”,正好在 学习STM8S003F3P6,加上之前手头有废弃的U盾,已参考网上帖子成功点亮其中的ST7565 12864LCD屏,就 想着利用这12864屏来做这个USB电压电流表。原帖采用1602显示,经过一番摸索改写ST7565驱动,略微调整源程序,终于完成了这个试验品。 先上图。正面: 
背面: 
点亮: 
带个USB小台灯: 
改变小台灯亮度: 
使用的U盾(中间长条型的) 
拆开的样子:排线印字FPC11289B-V0.3 
试验品考虑不周,PCB切割飞线,STM8调试接口也没预留,带来很多麻烦,LCD屏接口线也只好飞线连接。下面提供经修改改善的PCB工程和IAR源程序工程供大家参考。程序中电量统计只画了界面,计算部分未加入。 电路图: 
PCB:打算12864LCD屏单独一层PCB,2层叠放,有空再做一个。 
附件:
另手头还有2种U盾,屏幕都不一样,其中一种背光与屏幕一体的,排线印字12864-898 A4-A, FPC-9的接口,只用到7根线,适合做个模块使用。 

根据原电路大致测出接口如下,也不知道对不对。 1、9空,2、3接背光LED,7接3.3V电源,8接GND,4、5、6接MCU,功能不明。LCD控制IC不明,猜测是否也是ST7565?三线SPI模式? 期待高手搞定 
单片机源程序如下: - <font style="font-size: 14px">#include <iostm8s103f2.h>
- #include "ST7565_12864.h"
- #include "ziku.h"
- #define uchar unsigned char
- #define uint unsigned int
- #define KEY PA_IDR_IDR3 //PA 的第3位做KEY
- void EEP_Init(void) //EEPROM初始化
- {
- FLASH_CR1 = 0x00;
- FLASH_CR2 = 0x00;
- FLASH_NCR2 = 0xFF;
- FLASH_DUKR = 0xae; //写入第一个秘钥
- FLASH_DUKR = 0x56; //写入第二个秘钥
- while(!(FLASH_IAPSR&0x08)); //等待就绪
- }
- void EEP_W(uchar addr,float data) //写EEPROM
- {
- float *p;
- p=(float *)(0x4000+addr);
- *p=data;
- while(!(FLASH_IAPSR&0x04)); //等待完成
- }
- float EEP_R(uchar addr) //读EEPROM
- {
- float *p;
- p=(float *)(0x4000+addr);
- return *p;
- }
- void Hellow(void) //初始屏幕
- {
- ClearScreen(); //清除屏幕
- DisplayFont(2, 8+4, FONT_8X16,19); //U
- DisplayFont(2, 16+4, FONT_8X16,17); //S
- DisplayFont(2, 24+4, FONT_8X16,14); //B
- DisplayFont(2, 32+4, FONT_16X16,0);//电
- DisplayFont(2, 48+4, FONT_16X16,1);//压
- DisplayFont(2, 64+4, FONT_16X16,0);//电
- DisplayFont(2, 80+4, FONT_16X16,2);//流
- DisplayFont(2, 96+4, FONT_16X16,3);//表
- DisplayFont(5, 40+4, FONT_16X16,9);//丑
- DisplayFont(5, 56+4, FONT_16X16,10);//孩
- }
- void ADC_Init(void)
- {
- ADC_CR1 = 0x20; //分频系数为4 单次转换模式 先不启动ADC转换
- ADC_CR2 = 0x00; //非外部触发 数据左对齐 禁止扫描模式
- ADC_CSR = 0x03; //禁止转换结束中断 设置转换通道为AIN3
- ADC_TDRL|= 0x60; //禁止AIN5AIN6施密特触发器功能
- }
- uint Get_Adc(uchar ac) //获取adc值
- {
- uint Value;
- ADC_CSR = ac; //选择通道
- ADC_CR1 |= 0x01; //第一次写1是从低功耗模式唤醒
- ADC_CSR &= ~0x80; //清除转换标志
- ADC_CR1 |= 0x01; //开始转换
- while(!(0x80&ADC_CSR)); //等待转换完成
- Value = (uint) ADC_DRH; //取高8位
- Value = Value<<2; //左移两位
- Value += ADC_DRL; //取低两位
- return(Value); //返回adc值
- }
- float Ad_Av(uchar ac) //采样400次求平均
- {
- float Val_Av=0;
- uint num;
- for(num=0;num<400;num++)
- {
- Val_Av += Get_Adc(ac);
- }
- Val_Av = Val_Av/400;
- return(Val_Av);
- }
- void Write_Lcd0(void) //固定显示底板发去LCD
- {
- DisplayFont(0, 8+4, FONT_16X16,0); //电
- DisplayFont(0, 24+4, FONT_16X16,1); //压
- DisplayFont(0, 40+4, FONT_8X16,12); //:
- DisplayFont(0, 112+4, FONT_8X16,20); //V
- DisplayFont(2, 8+4, FONT_16X16,0); //电
- DisplayFont(2, 24+4, FONT_16X16,2); //流
- DisplayFont(2, 40+4, FONT_8X16,12); //:
- DisplayFont(2, 112+4, FONT_8X16,13); //A
- DisplayFont(4, 8+4, FONT_16X16,4); //功
- DisplayFont(4, 24+4, FONT_16X16,5); //率
- DisplayFont(4, 40+4, FONT_8X16,12); //:
- DisplayFont(4, 104+4, FONT_16X16,11); //W
- DisplayFont(6, 8+4, FONT_16X16,14); //容
- DisplayFont(6, 24+4, FONT_16X16,15); //量
- DisplayFont(6, 40+4, FONT_8X16,12); //:
- DisplayFont(6, 96+4, FONT_8X16,22); //m
- DisplayFont(6, 104+4, FONT_8X16,13); //A
- DisplayFont(6, 112+4, FONT_8X16,15); //H
- // DisplayFont(6, 104+4, FONT_16X16,12); //Ω
- }
-
- void Write_Lcd1(int ad,uchar xl,uchar yl)//把电压电阻功率发去LCD,ad采集数值,xl yl显示位置
- {
- if(ad/1000>=1) //电压如果不足10V,就把1位显示为空
- {
- DisplayFont(xl,yl+4, FONT_8X16,ad/1000); //十位
- }
- else DisplayFont(xl,yl+4,FONT_8X16,10); //空格
- DisplayFont(xl,yl+8+4, FONT_8X16,(ad%1000)/100); //个位
- DisplayFont(xl,yl+16+4, FONT_8X16,11); //"."小数点
- DisplayFont(xl,yl+24+4, FONT_8X16,ad%100/10); //十分位
- DisplayFont(xl,yl+32+4, FONT_8X16,ad%10); //百分位
- }
- void Write_Lcd2(int ad,uchar xl,uchar yl) //把电流值发去LCD
- {
- DisplayFont(xl,yl+4, FONT_8X16,ad/1000); //个位
- DisplayFont(xl,yl+8+4, FONT_8X16,11); //"."小数点
- DisplayFont(xl,yl+16+4, FONT_8X16,ad%1000/100); //十分位
- DisplayFont(xl,yl+24+4, FONT_8X16,ad%100/10); //百分位
- DisplayFont(xl,yl+32+4, FONT_8X16,ad%10); //千分位
- }
- void Write_Lcd3(int ad,uchar xl,uchar yl) //把容量值发去LCD
- {
- DisplayFont(xl,yl+4, FONT_8X16,ad/10000); //万位
- DisplayFont(xl,yl+8+4, FONT_8X16,ad%10000/1000); //千位
- DisplayFont(xl,yl+16+4, FONT_8X16,ad%1000/100); //百位
- DisplayFont(xl,yl+24+4, FONT_8X16,ad%100/10); //十位
- DisplayFont(xl,yl+32+4, FONT_8X16,ad%10); //个位
- }
- void Correct(void) //校准
- {
- float V2,Iov,I1,I2,I3,AIN7;
- uchar a,flag;
- ClearScreen(); //清除屏幕
- DisplayFont(1, 48+4, FONT_16X16,7); //校
- DisplayFont(1, 64+4, FONT_16X16,8); //准
- DisplayFont(4, 8+4, FONT_8X16,16); //I
- DisplayFont(4, 16+4, FONT_8X16,23); //n
- DisplayFont(4, 24+4, FONT_8X16,24); //p
- DisplayFont(4, 32+4, FONT_8X16,26); //u
- DisplayFont(4, 40+4, FONT_8X16,25); //t
- DisplayFont(4, 48+4, FONT_8X16,12); //:
-
- DisplayFont(4, 64+4, FONT_8X16,10); //空格
- DisplayFont(4, 72+4, FONT_8X16,10); //空格
- DisplayFont(4, 80+4, FONT_8X16,10); //空格
- DisplayFont(4, 88+4, FONT_8X16,5); //5
- DisplayFont(4, 96+4, FONT_8X16,10); //空格
- DisplayFont(4, 104+4, FONT_8X16,20); //V
- Delay(40);
- flag=1;
- while(flag)
- {
- if(!KEY)
- {
- Delay1(20);
- if(KEY)
- {
- AIN7 = Ad_Av(7); //取得基准的ADC数值
- V2 = Ad_Av(5); //取得校准电压的ADC数值
- V2 = V2*10/AIN7; //????
- // V2 = V2/AIN7; //????
- EEP_W(0x04,V2);
- flag = 0;
- }
- }
- }
- for(a=0;a<16;a++)
- {
- DisplayFont(4, 64+4, FONT_8X16,10); //空格
- DisplayFont(4, 72+4, FONT_8X16,10); //空格
- DisplayFont(4, 80+4, FONT_8X16,10); //空格
- DisplayFont(4, 88+4, FONT_8X16,0); //0
- DisplayFont(4, 96+4, FONT_8X16,22); //m
- DisplayFont(4, 104+4, FONT_8X16,13); //A
- Delay(40);
- }
- flag=1;
- while(flag)
- {
- if(!KEY)
- {
- Delay1(20);
- if(KEY)
- {
- Iov = Ad_Av(6);
- EEP_W(0x10,Iov);
- flag = 0;
- }
- }
- }
- for(a=0;a<16;a++)
- {
- DisplayFont(4, 64+4, FONT_8X16,10); //空格
- DisplayFont(4, 72+4, FONT_8X16,1); //1
- DisplayFont(4, 80+4, FONT_8X16,0); //0
- DisplayFont(4, 88+4, FONT_8X16,0); //0
- DisplayFont(4, 96+4, FONT_8X16,22); //m
- DisplayFont(4, 104+4, FONT_8X16,13); //A
- Delay(40);
- }
- flag=1;
- while(flag)
- {
- if(!KEY)
- {
- Delay1(20);
- if(KEY)
- {
- AIN7 = Ad_Av(7);
- I1 = Ad_Av(6);
- I1 = (I1-Iov)/AIN7;
- EEP_W(0x08,I1);
- flag = 0;
- }
- }
- }
- for(a=0;a<16;a++)
- {
- DisplayFont(4, 64+4, FONT_8X16,1); //1
- DisplayFont(4, 72+4, FONT_8X16,0); //0
- DisplayFont(4, 80+4, FONT_8X16,0); //0
- DisplayFont(4, 88+4, FONT_8X16,0); //0
- DisplayFont(4, 96+4, FONT_8X16,22); //m
- DisplayFont(4, 104+4, FONT_8X16,13); //A
- Delay(40);
- }
- flag=1;
- while(flag)
- {
- if(!KEY)
- {
- Delay1(20);
- if(KEY)
- {
- AIN7 = Ad_Av(7);
- I2 = Ad_Av(6);
- I2 = (I2-Iov)/AIN7;
- EEP_W(0x0c,I2);
- flag = 0;
- }
- }
- }
- for(a=0;a<16;a++)
- {
- DisplayFont(4, 64+4, FONT_8X16,3); //3
- DisplayFont(4, 72+4, FONT_8X16,0); //0
- DisplayFont(4, 80+4, FONT_8X16,0); //0
- DisplayFont(4, 88+4, FONT_8X16,0); //0
- DisplayFont(4, 96+4, FONT_8X16,22); //m
- DisplayFont(4, 104+4, FONT_8X16,13); //A
- Delay(40);
- }
- flag=1;
- while(flag)
- {
- if(!KEY)
- {
- Delay1(20);
- if(KEY)
- {
- AIN7 = Ad_Av(7);
- I3 = Ad_Av(6);
- I3 = (I3-Iov)/AIN7;
- EEP_W(0x14,I3);
- flag = 0;
- }
- }
- }
- }
- void main() //主函数
- {
- float V,V2,I,I1,I2,I3,Iov,AIN7,R,W;
- CLK_CKDIVR=0x00;
- //Delay(1000);
- GPIO_Init();
- ADC_Init();
- EEP_Init();
- Lcd_Init();
- Hellow();
- Delay1(800);
- while(!KEY)
- {
- Delay1(10);
- if(KEY)
- Correct();
- }
- V2 = EEP_R(0x04); //对应5V
- I1 = EEP_R(0x08); //对应100MA 电流校正值
- I2 = EEP_R(0x0c); //对应1000MA 电流校正值
- Iov = EEP_R(0x10); //对应0MA 电流校正值
- I3 = EEP_R(0x14); //对应3000MA 电流校正值
- ClearScreen(); //清除屏幕
- while(1)
- {
- Write_Lcd0(); //显示固定底版
- AIN7 = Ad_Av(7); //通道7为内部参考电压
- I = Ad_Av(6); //通道6电流采样
- V = Ad_Av(5); //通道5电压采样
- if(V>1)
- {
- V = V/AIN7/V2*5069; //5V校正时输入5.069V
- }
- else
- {
- V = 0;
- }
- if((I-Iov)>0 & (I/AIN7)<=I1*2) //计算电流
- I = (I-Iov)/AIN7/I1*100;
- else if((I/AIN7)>I1*2 & (I/AIN7)<=I2*2)
- I = (I-Iov)/AIN7/I2*1000;
- else
- I = (I-Iov)/AIN7/I3*3000;
- R = V/I; //计算电阻
- W = V*I/1000; //计算功率
- Delay1(5);
- Write_Lcd1((int)V,0,56); //写入电压
- Write_Lcd2((int)I,2,64); //电流
- /*
- if(I<1)
- {
- Write_Lcd1(0,4,64); //写入电阻
- }
- else
- {
- Write_Lcd1((int)R,4,64); //电阻。
- }
- */
- Write_Lcd1((int)W,4,56); //功率
- Write_Lcd3(0,6,56); //容量
- Delay1(400);
- }
- }
- </font>
复制代码
所有资料51hei提供下载:
STM8S USB电压电流表.zip
(3.26 MB, 下载次数: 457)
|