找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 9511|回复: 13
打印 上一主题 下一主题
收起左侧

STM8S st7565-LCD12864 USB电压电流表PCB与单片机源程序

  [复制链接]
跳转到指定楼层
楼主
STM8S003F3P6 LCD12864USB电压电流表

之前看到sabaka发的帖子“STM8S003F3表头自校准版”,正好在 学习STM8S003F3P6,加上之前手头有废弃的U,已参考网上帖子成功点亮其中的ST7565 12864LCD屏,就 想着利用这12864屏来做这个USB电压电流表。原帖采用1602显示,经过一番摸索改写ST7565驱动,略微调整源程序,终于完成了这个试验品。
先上图。正面:
背面:
点亮:
带个USB小台灯:
改变小台灯亮度:
使用的(中间长条型的)
拆开的样子:排线印字FPC11289B-V0.3

试验品考虑不周,PCB切割飞线,STM8调试接口也没预留,带来很多麻烦,LCD屏接口线也只好飞线连接。下面提供经修改改善的PCB工程和IAR源程序工程供大家参考。程序中电量统计只画了界面,计算部分未加入。
电路图:
PCB:打算12864LCD屏单独一层PCB,2层叠放,有空再做一个。

附件:


另手头还有2种,屏幕都不一样,其中一种背光与屏幕一体的,排线印字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模式?              期待高手搞定

Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)

单片机源程序如下:
  1. #include <iostm8s103f2.h>
  2. #include "ST7565_12864.h"
  3. #include "ziku.h"
  4. #define uchar  unsigned char
  5. #define uint   unsigned int
  6. #define KEY PA_IDR_IDR3    //PA 的第3位做KEY

  7. void EEP_Init(void)  //EEPROM初始化        
  8. {
  9.   FLASH_CR1  = 0x00;
  10.   FLASH_CR2  = 0x00;
  11.   FLASH_NCR2 = 0xFF;
  12.   FLASH_DUKR = 0xae;          //写入第一个秘钥
  13.   FLASH_DUKR = 0x56;          //写入第二个秘钥
  14.   while(!(FLASH_IAPSR&0x08)); //等待就绪
  15. }
  16. void EEP_W(uchar addr,float data) //写EEPROM
  17. {
  18.   float *p;
  19.   p=(float *)(0x4000+addr);
  20.   *p=data;
  21.   while(!(FLASH_IAPSR&0x04)); //等待完成
  22. }
  23. float EEP_R(uchar addr)  //读EEPROM
  24. {
  25.   float *p;
  26.   p=(float *)(0x4000+addr);
  27.   return *p;
  28. }

  29. void Hellow(void)     //初始屏幕
  30. {
  31.     ClearScreen();    //清除屏幕
  32.     DisplayFont(2, 8+4, FONT_8X16,19);  //U
  33.     DisplayFont(2, 16+4, FONT_8X16,17); //S
  34.     DisplayFont(2, 24+4, FONT_8X16,14); //B
  35.     DisplayFont(2, 32+4, FONT_16X16,0);//电
  36.     DisplayFont(2, 48+4, FONT_16X16,1);//压
  37.     DisplayFont(2, 64+4, FONT_16X16,0);//电
  38.     DisplayFont(2, 80+4, FONT_16X16,2);//流
  39.     DisplayFont(2, 96+4, FONT_16X16,3);//表
  40.     DisplayFont(5, 40+4, FONT_16X16,9);//丑
  41.     DisplayFont(5, 56+4, FONT_16X16,10);//孩
  42. }

  43. void ADC_Init(void)
  44. {
  45.     ADC_CR1  = 0x20;       //分频系数为4 单次转换模式 先不启动ADC转换      
  46.     ADC_CR2  = 0x00;       //非外部触发  数据左对齐   禁止扫描模式   
  47.     ADC_CSR  = 0x03;       //禁止转换结束中断 设置转换通道为AIN3
  48.     ADC_TDRL|= 0x60;      //禁止AIN5AIN6施密特触发器功能  
  49. }


  50. uint Get_Adc(uchar ac)           //获取adc值
  51. {
  52.         uint Value;
  53.         ADC_CSR  = ac;                 //选择通道
  54.     ADC_CR1 |= 0x01;       //第一次写1是从低功耗模式唤醒
  55.         ADC_CSR &= ~0x80;              //清除转换标志
  56.         ADC_CR1 |= 0x01;               //开始转换
  57.         while(!(0x80&ADC_CSR));        //等待转换完成
  58.         Value  = (uint) ADC_DRH;       //取高8位
  59.         Value  = Value<<2;             //左移两位
  60.         Value += ADC_DRL;              //取低两位
  61.         return(Value);                 //返回adc值
  62. }
  63. float Ad_Av(uchar ac)       //采样400次求平均
  64. {
  65.         float Val_Av=0;                     
  66.         uint num;                           
  67.         for(num=0;num<400;num++)  
  68.         {
  69.                 Val_Av += Get_Adc(ac);               
  70.         }
  71.         Val_Av = Val_Av/400;                    
  72.         return(Val_Av);                       
  73. }


  74. void Write_Lcd0(void)    //固定显示底板发去LCD
  75. {
  76.     DisplayFont(0, 8+4, FONT_16X16,0);    //电
  77.     DisplayFont(0, 24+4, FONT_16X16,1);   //压
  78.     DisplayFont(0, 40+4, FONT_8X16,12);   //:
  79.     DisplayFont(0, 112+4, FONT_8X16,20);  //V
  80.     DisplayFont(2, 8+4, FONT_16X16,0);    //电
  81.     DisplayFont(2, 24+4, FONT_16X16,2);   //流
  82.     DisplayFont(2, 40+4, FONT_8X16,12);   //:
  83.     DisplayFont(2, 112+4, FONT_8X16,13);  //A
  84.     DisplayFont(4, 8+4, FONT_16X16,4);    //功
  85.     DisplayFont(4, 24+4, FONT_16X16,5);   //率  
  86.     DisplayFont(4, 40+4, FONT_8X16,12);   //:
  87.     DisplayFont(4, 104+4, FONT_16X16,11);  //W
  88.     DisplayFont(6, 8+4, FONT_16X16,14);    //容
  89.     DisplayFont(6, 24+4, FONT_16X16,15);   //量
  90.     DisplayFont(6, 40+4, FONT_8X16,12);   //:
  91.     DisplayFont(6, 96+4, FONT_8X16,22);  //m
  92.     DisplayFont(6, 104+4, FONT_8X16,13);  //A
  93.     DisplayFont(6, 112+4, FONT_8X16,15);  //H
  94. //    DisplayFont(6, 104+4, FONT_16X16,12);  //Ω
  95. }
  96.    
  97. void Write_Lcd1(int ad,uchar xl,uchar yl)//把电压电阻功率发去LCD,ad采集数值,xl yl显示位置
  98. {
  99.         if(ad/1000>=1)                         //电压如果不足10V,就把1位显示为空
  100.         {
  101.         DisplayFont(xl,yl+4, FONT_8X16,ad/1000);      //十位
  102.     }
  103.     else  DisplayFont(xl,yl+4,FONT_8X16,10);         //空格
  104.         DisplayFont(xl,yl+8+4, FONT_8X16,(ad%1000)/100);  //个位
  105.         DisplayFont(xl,yl+16+4, FONT_8X16,11);           //"."小数点
  106.         DisplayFont(xl,yl+24+4, FONT_8X16,ad%100/10);    //十分位
  107.         DisplayFont(xl,yl+32+4, FONT_8X16,ad%10);        //百分位
  108. }

  109. void Write_Lcd2(int ad,uchar xl,uchar yl) //把电流值发去LCD
  110. {
  111.     DisplayFont(xl,yl+4, FONT_8X16,ad/1000);       //个位
  112.     DisplayFont(xl,yl+8+4, FONT_8X16,11);           //"."小数点
  113.     DisplayFont(xl,yl+16+4, FONT_8X16,ad%1000/100);  //十分位
  114.     DisplayFont(xl,yl+24+4, FONT_8X16,ad%100/10);    //百分位
  115.     DisplayFont(xl,yl+32+4, FONT_8X16,ad%10);          //千分位
  116. }

  117. void Write_Lcd3(int ad,uchar xl,uchar yl) //把容量值发去LCD
  118. {
  119.     DisplayFont(xl,yl+4, FONT_8X16,ad/10000);       //万位
  120.     DisplayFont(xl,yl+8+4, FONT_8X16,ad%10000/1000); //千位
  121.     DisplayFont(xl,yl+16+4, FONT_8X16,ad%1000/100);  //百位
  122.     DisplayFont(xl,yl+24+4, FONT_8X16,ad%100/10);    //十位
  123.     DisplayFont(xl,yl+32+4, FONT_8X16,ad%10);          //个位
  124. }




  125. void Correct(void)         //校准
  126. {
  127.         float V2,Iov,I1,I2,I3,AIN7;
  128.         uchar a,flag;
  129.     ClearScreen();    //清除屏幕
  130.     DisplayFont(1, 48+4, FONT_16X16,7);    //校
  131.     DisplayFont(1, 64+4, FONT_16X16,8);   //准
  132.     DisplayFont(4, 8+4, FONT_8X16,16);   //I
  133.     DisplayFont(4, 16+4, FONT_8X16,23);  //n
  134.     DisplayFont(4, 24+4, FONT_8X16,24);   //p
  135.     DisplayFont(4, 32+4, FONT_8X16,26);  //u
  136.     DisplayFont(4, 40+4, FONT_8X16,25);  //t
  137.     DisplayFont(4, 48+4, FONT_8X16,12);   //:
  138.    
  139.     DisplayFont(4, 64+4, FONT_8X16,10);   //空格
  140.     DisplayFont(4, 72+4, FONT_8X16,10);   //空格
  141.     DisplayFont(4, 80+4, FONT_8X16,10);  //空格
  142.     DisplayFont(4, 88+4, FONT_8X16,5);  //5
  143.     DisplayFont(4, 96+4, FONT_8X16,10);   //空格
  144.     DisplayFont(4, 104+4, FONT_8X16,20);   //V

  145.     Delay(40);               
  146.         flag=1;
  147.         while(flag)
  148.   {
  149.                 if(!KEY)
  150.           {
  151.                         Delay1(20);
  152.                         if(KEY)
  153.                         {
  154.                           AIN7 = Ad_Av(7);     //取得基准的ADC数值
  155.                     V2   = Ad_Av(5);         //取得校准电压的ADC数值
  156.                           V2   = V2*10/AIN7;   //????
  157. //                          V2   = V2/AIN7;   //????
  158.                           EEP_W(0x04,V2);
  159.               flag = 0;
  160.                         }
  161.           }
  162.         }
  163.   for(a=0;a<16;a++)
  164.         {
  165.         DisplayFont(4, 64+4, FONT_8X16,10);   //空格
  166.         DisplayFont(4, 72+4, FONT_8X16,10);   //空格
  167.         DisplayFont(4, 80+4, FONT_8X16,10);  //空格
  168.         DisplayFont(4, 88+4, FONT_8X16,0);  //0
  169.         DisplayFont(4, 96+4, FONT_8X16,22);   //m
  170.         DisplayFont(4, 104+4, FONT_8X16,13);   //A
  171.                 Delay(40);               
  172.         }
  173.         flag=1;
  174.         while(flag)
  175.   {
  176.                 if(!KEY)
  177.           {
  178.                         Delay1(20);
  179.                         if(KEY)
  180.                         {
  181.                     Iov  = Ad_Av(6);
  182.                                 EEP_W(0x10,Iov);
  183.               flag = 0;
  184.                         }
  185.           }
  186.         }
  187.   for(a=0;a<16;a++)
  188.         {
  189.         DisplayFont(4, 64+4, FONT_8X16,10);   //空格
  190.         DisplayFont(4, 72+4, FONT_8X16,1);   //1
  191.         DisplayFont(4, 80+4, FONT_8X16,0);  //0
  192.         DisplayFont(4, 88+4, FONT_8X16,0);  //0
  193.         DisplayFont(4, 96+4, FONT_8X16,22);   //m
  194.         DisplayFont(4, 104+4, FONT_8X16,13);   //A
  195.                 Delay(40);               
  196.         }
  197.         flag=1;
  198.         while(flag)
  199.   {
  200.                 if(!KEY)
  201.           {
  202.                         Delay1(20);
  203.                         if(KEY)
  204.                         {
  205.                           AIN7 = Ad_Av(7);
  206.                     I1   = Ad_Av(6);
  207.                           I1   = (I1-Iov)/AIN7;
  208.                           EEP_W(0x08,I1);
  209.               flag = 0;
  210.                         }
  211.           }
  212.         }
  213.   for(a=0;a<16;a++)
  214.         {
  215.         DisplayFont(4, 64+4, FONT_8X16,1);   //1
  216.         DisplayFont(4, 72+4, FONT_8X16,0);   //0
  217.         DisplayFont(4, 80+4, FONT_8X16,0);  //0
  218.         DisplayFont(4, 88+4, FONT_8X16,0);  //0
  219.         DisplayFont(4, 96+4, FONT_8X16,22);   //m
  220.         DisplayFont(4, 104+4, FONT_8X16,13);   //A
  221.                 Delay(40);               
  222.         }
  223.         flag=1;
  224.         while(flag)
  225.   {
  226.                 if(!KEY)
  227.           {
  228.                         Delay1(20);
  229.                         if(KEY)
  230.                         {
  231.                           AIN7 = Ad_Av(7);
  232.                     I2   = Ad_Av(6);
  233.                           I2   = (I2-Iov)/AIN7;
  234.                           EEP_W(0x0c,I2);
  235.               flag = 0;
  236.                         }
  237.           }
  238.         }
  239.   for(a=0;a<16;a++)
  240.         {
  241.         DisplayFont(4, 64+4, FONT_8X16,3);   //3
  242.         DisplayFont(4, 72+4, FONT_8X16,0);   //0
  243.         DisplayFont(4, 80+4, FONT_8X16,0);  //0
  244.         DisplayFont(4, 88+4, FONT_8X16,0);  //0
  245.         DisplayFont(4, 96+4, FONT_8X16,22);   //m
  246.         DisplayFont(4, 104+4, FONT_8X16,13);   //A
  247.                 Delay(40);               
  248.         }
  249.         flag=1;
  250.         while(flag)
  251.   {
  252.                 if(!KEY)
  253.           {
  254.                         Delay1(20);
  255.                         if(KEY)
  256.                         {
  257.                           AIN7 = Ad_Av(7);
  258.                     I3   = Ad_Av(6);
  259.                           I3   = (I3-Iov)/AIN7;
  260.                           EEP_W(0x14,I3);
  261.               flag = 0;
  262.                         }
  263.           }
  264.         }
  265. }
  266. void main() //主函数
  267. {
  268.         float V,V2,I,I1,I2,I3,Iov,AIN7,R,W;
  269.         CLK_CKDIVR=0x00;
  270.         //Delay(1000);
  271.         GPIO_Init();
  272.     ADC_Init();
  273.         EEP_Init();
  274.         Lcd_Init();
  275.         Hellow();
  276.         Delay1(800);
  277.         while(!KEY)
  278.         {
  279.                 Delay1(10);
  280.                 if(KEY)
  281.         Correct();
  282.     }
  283.         V2  = EEP_R(0x04);      //对应5V
  284.         I1  = EEP_R(0x08);      //对应100MA  电流校正值
  285.         I2  = EEP_R(0x0c);      //对应1000MA   电流校正值
  286.         Iov = EEP_R(0x10);      //对应0MA  电流校正值
  287.         I3  = EEP_R(0x14);      //对应3000MA   电流校正值
  288.     ClearScreen();    //清除屏幕
  289.         while(1)
  290.         {
  291.         Write_Lcd0();                 //显示固定底版
  292.         AIN7 = Ad_Av(7);              //通道7为内部参考电压
  293.                    I = Ad_Av(6);               //通道6电流采样
  294.                    V = Ad_Av(5);                                 //通道5电压采样
  295.                 if(V>1)
  296.                 {
  297.             V = V/AIN7/V2*5069;          //5V校正时输入5.069V
  298.                 }
  299.                 else
  300.                 {
  301.                         V = 0;
  302.                 }
  303.                 if((I-Iov)>0 & (I/AIN7)<=I1*2)        //计算电流
  304.             I = (I-Iov)/AIN7/I1*100;
  305.                 else if((I/AIN7)>I1*2 & (I/AIN7)<=I2*2)
  306.                     I = (I-Iov)/AIN7/I2*1000;
  307.                 else
  308.                     I = (I-Iov)/AIN7/I3*3000;
  309.                 R = V/I;                 //计算电阻
  310.                 W = V*I/1000;       //计算功率
  311.                 Delay1(5);
  312.                 Write_Lcd1((int)V,0,56);    //写入电压
  313.                 Write_Lcd2((int)I,2,64);    //电流
  314. /*
  315.                 if(I<1)
  316.                 {
  317.                         Write_Lcd1(0,4,64);      //写入电阻
  318.                 }
  319.                 else
  320.                 {
  321.                         Write_Lcd1((int)R,4,64); //电阻。
  322.                 }
  323. */
  324.                 Write_Lcd1((int)W,4,56);    //功率
  325.                 Write_Lcd3(0,6,56);         //容量
  326.                 Delay1(400);
  327.     }
  328. }
复制代码

所有资料51hei提供下载:
STM8S st7565-12864 USB电压电流表源程序及PCB工程.zip (3.29 MB, 下载次数: 189)


评分

参与人数 2黑币 +62 收起 理由
YJGG + 12 很给力!
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏27 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:98767 发表于 2018-7-26 18:13 | 只看该作者
不错,对着做个试下
回复

使用道具 举报

板凳
ID:239055 发表于 2018-10-11 06:40 来自手机 | 只看该作者
请问下,电压电流的量程各是多少?还有精度怎么样?
回复

使用道具 举报

地板
ID:378605 发表于 2018-10-11 19:54 | 只看该作者
回复

使用道具 举报

5#
ID:239055 发表于 2018-10-17 11:29 来自手机 | 只看该作者
我也要问下精度和量程多少
回复

使用道具 举报

6#
ID:239055 发表于 2018-11-18 20:14 来自手机 | 只看该作者
请问下stm8这芯片怎么编译程序以及烧写?可以帮我编译一份软件不?谢了
回复

使用道具 举报

7#
ID:433321 发表于 2018-11-26 11:51 | 只看该作者
这芯片里面的HEX数据可以直接读取出来吗
回复

使用道具 举报

8#
ID:471797 发表于 2019-1-23 19:09 | 只看该作者
请问这个电流是双相的还是单相的
回复

使用道具 举报

9#
ID:675521 发表于 2020-3-29 19:34 | 只看该作者

留一个记号,备用。
回复

使用道具 举报

10#
ID:65297 发表于 2020-3-30 14:54 | 只看该作者
谢谢分享,最近也在学习STM8
回复

使用道具 举报

11#
ID:57411 发表于 2020-8-10 16:10 | 只看该作者
谢谢分享,最近在学习7565驱动。
回复

使用道具 举报

12#
ID:337139 发表于 2020-10-21 17:47 | 只看该作者
这个驱动写得很好的。
回复

使用道具 举报

13#
ID:960224 发表于 2021-8-12 17:40 | 只看该作者
很厉害的发明,敬佩
回复

使用道具 举报

14#
ID:523221 发表于 2021-10-29 14:35 | 只看该作者
你好,可以解析一下LM358的电路吗?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表