附件是別的大神設計制作的 我只是做分享。
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)
2018-11-25 22:20 上傳
點擊文件名下載附件
|