标题: 基于单片机的0-22V电压表电路图+源程序 [打印本页]

作者: yunduobala    时间: 2019-4-14 15:50
标题: 基于单片机的0-22V电压表电路图+源程序
基于单片机的0-24V电压表 电路原理图如下:


单片机源程序如下:
  1. #include"reg52.h"
  2. #include"intrins.h"
  3. typedef unsigned char uchar;
  4. typedef unsigned int uint;
  5. #define _Nop() _nop_()
  6. unsigned char data_char_table[]= {"0123456789ABCDEF"};                        //LCD数据
  7. unsigned char Lcd_Dis1_table[] = {"Position:No.    "};                        //第一行显示框架
  8. unsigned char pos_char_table[] = {"             D  "};                        //      显示位置
  9. unsigned char Lcd_Dis2_table[] = {"Voltage :      V"};                        //第二行显示框架
  10. unsigned char num_char_table[] = {"         9A.CD V"};                        //      显示位置
  11. sbit lcd_rs_port=P2^5; //定义 LCD控制端口,根据硬件调整
  12. sbit lcd_rw_port=P2^6;
  13. sbit lcd_en_port=P2^7;
  14. sbit X=P3^4;
  15. sbit Y=P3^3;
  16. sbit Z=P3^2;
  17. #define lcd_data_port P0
  18. void lcd_delay(uchar ms); //LCD1602延时
  19. void lcd_busy_wait(); //LCD1602忙等待
  20. void lcd_command_write(uint command); //LCD1602命令字写入
  21. void lcd_system_reset(); //LCD1602初始化
  22. void lcd_char_write(uint x_pos,y_pos,lcd_dat); //LCD1602字符写入
  23. void lcd_bad_check(); //LCD1602坏点检查
  24. void Num_to_Disp(uchar i,uint Num); //显示数据处理
  25. void LcdDisp(uchar j,uint num); //液晶显示函数
  26. float adadverage();
  27. /*****定义与 ADC相关的特殊功能寄存器 *****/
  28. sfr ADC_CONTR= 0xBC; //ADC控制寄存器
  29. sfr ADC_RES = 0xBD; //ADChight8-bitresultregister
  30. sfr ADC_RESL = 0xBE; //ADClow2-bitresultregister
  31. sfr P1ASF = 0x9D; //P1口功能控制寄存器 P1ASF
  32. /************定义相应操作位***************/
  33. #define ADC_POWER 0x80 //ADC电源控制位,0:关闭,1:打开
  34. #define ADC_FLAG 0x10 //ADC结束标志位
  35. #define ADC_START 0x08 //ADC启动控制位
  36. #define ADC_SPEEDLL 0x00 //540clocks__________选择转换速度
  37. void InitADC(); //ADC初始化
  38. uint GetADCResult(uchar ch);
  39. void Delay(uint n); //延时程序
  40. void delay_1ms(uchar x);
  41. void decide();


  42. /*--------------------------------主函数 --------------------------------*/
  43. void main()
  44. {
  45.         lcd_system_reset(); //LCD1602初始化
  46.         lcd_bad_check(); //LCD1602坏点检查
  47.         InitADC(); //初始化 ADC特殊功能寄存器
  48.         while(1)
  49.         {
  50.                  decide();        
  51.                  Delay(1000);
  52.         }
  53. }
  54. /*--------------------------------域值判断 ------------------------------*/
  55. void decide()
  56. {
  57.         unsigned int res;
  58.         float NUM;
  59.         NUM=0.0;
  60.         X=1;
  61.         Y=1;
  62.         Z=1;
  63.         res=GetADCResult(0);
  64.         NUM=(res*5.00/1024.0);
  65.         NUM=NUM*5;
  66. if(NUM<4.99)
  67. {
  68.         X=1;
  69.         Y=1;
  70.         Z=0;
  71.         Delay(10);
  72.         LcdDisp(4,adadverage());
  73. }
  74. else if(NUM>=4.99&&NUM<6.24)
  75. {
  76.         X=0;
  77.         Y=0;
  78.         Z=1;
  79.         Delay(10);
  80.         LcdDisp(3,adadverage());
  81. }
  82. else if(NUM>=6.24&&NUM<8.2)
  83. {
  84.         X=1;
  85.         Y=0;
  86.         Z=1;
  87.         Delay(10);
  88.         LcdDisp(2,adadverage());
  89. }
  90. else if(NUM>=8.2&&NUM<12.4)
  91. {
  92.         X=0;
  93.         Y=1;
  94.         Z=1;
  95.         Delay(10);
  96.         LcdDisp(1,GetADCResult(0));
  97. }
  98. else if(NUM>=12.4&&NUM<25.0)
  99. {
  100.         X=1;
  101.         Y=1;
  102.         Z=1;
  103.         Delay(10);
  104.         LcdDisp(0,adadverage());
  105. }
  106.         else
  107.         {
  108.         LcdDisp(8,0);
  109.         }
  110. }
  111. /*--------------------------------ADC取值 ------------------------------*/
  112. uint GetADCResult(uchar ch)
  113. {
  114.         ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ch|ADC_START;
  115.         _nop_(); //Mustwaitbeforeinquiry
  116.         _nop_();
  117.         _nop_();
  118.         _nop_();

  119.         while(!(ADC_CONTR & ADC_FLAG)); //Waitcompleteflag
  120.         ADC_CONTR &=ADC_FLAG; //Close ADC
  121.         return(ADC_RES*4+ADC_RESL); //ReturnADCresult
  122. }
  123.         /*AD初始化*/
  124.         void InitADC()
  125. {
  126.         P1ASF=P1|0x3f; //Set P1.0-P1.5 as an alogin putport
  127.         ADC_RES =0; //Clearpreviousresult
  128.         ADC_RESL=0;
  129.         ADC_CONTR=ADC_POWER|ADC_SPEEDLL;
  130.         Delay(20);
  131.         } //ADCpower-ondelayandStartA/Dconversion}
  132. ///////////////以下为 LCD显示数据处理/////////////////
  133. void Num_to_Disp(uchar i,uint Num)
  134. {
  135.         float NUM;
  136.         int xx,yy,zz,vv;
  137.         NUM=(Num*5.00/1024.0);//计算公式:10-bitA/DConversionResult=1024x(Vin/Vcc)
  138.         switch(i)
  139.         {
  140.         case 0:NUM=NUM*5.10;break;
  141.         case 1:NUM=NUM*2.52;break;
  142.         case 2:NUM=NUM*1.69;break;
  143.         case 3:NUM=NUM*1.27;break;
  144.         case 4:NUM=NUM*1.00;break;
  145.         }
  146.         xx=(int)NUM;
  147.         yy=(int)((NUM-(float)(xx))*10);
  148.         zz=(int)((NUM-(float)(xx))*100)%10;
  149.         vv=(int)((NUM-(float)(xx))*1000)%10;
  150.         num_char_table[9]=data_char_table[xx / 10]; //电压值十位
  151.         num_char_table[10]=data_char_table[xx % 10]; //电压值个位
  152.         num_char_table[12]=data_char_table[yy];  //电压值小数点后一位
  153.         num_char_table[13]=data_char_table[zz]; //电压值小数点后两位
  154.         num_char_table[14]=data_char_table[vv]; //电压值小数点后三位
  155.         pos_char_table[13]=data_char_table[i]; //当前 ADC接口
  156.         }
  157. //////////////////以下为 LCD显示////////////////////
  158. void LcdDisp(uchar j,uint num)
  159. {
  160.         uint i=0;
  161.         for(i=0;i<16;i++)
  162.         {
  163.                 lcd_char_write(i,0,Lcd_Dis1_table[i]);
  164.                 lcd_char_write(i,1,Lcd_Dis2_table[i]); //显示框架
  165.                 }
  166.                 Num_to_Disp(j,num);
  167.                 lcd_char_write(13,0,pos_char_table[13]);
  168.                 for(i=9;i<15;i++)
  169.                      {
  170.                         lcd_char_write(i,1,num_char_table[i]); //显示电压
  171.                         }
  172.                         delay_1ms(100);
  173.                         }
  174. //////////////以下是 LCD1602驱动程序////////////////

  175. /*LCD1602延时*/
  176. void lcd_delay(uchar ms)
  177. {
  178.         uchar j;
  179.         while(ms--)
  180.         {
  181.                 for(j=0;j<250;j++)
  182.                 {;}
  183.         }
  184. }


  185. /*LCD1602忙等待*/
  186. void lcd_busy_wait()
  187. {
  188.         lcd_rs_port=0;
  189.         lcd_rw_port=1;
  190.         lcd_en_port=1;
  191.         lcd_data_port=0xff;
  192.         while(lcd_data_port&0x80);
  193.         lcd_en_port=0;
  194.         }

  195. /*LCD1602命令字写入*/
  196. void lcd_command_write(uint command)
  197. {
  198.         lcd_busy_wait();
  199.         lcd_rs_port=0;
  200.         lcd_rw_port=0;
  201.         lcd_en_port=0;
  202.         lcd_data_port=command;
  203.         lcd_en_port=1;
  204.         lcd_en_port=0;
  205. }

  206. /*LCD1602初始化*/
  207. void lcd_system_reset( )
  208. {
  209.         lcd_delay(20);
  210.         lcd_command_write(0x38);
  211.         lcd_delay(100);
  212.         lcd_command_write(0x38);
  213.         lcd_delay(50);
  214.         lcd_command_write(0x38);
  215.         lcd_delay(10);
  216.         lcd_command_write(0x08);
  217.         lcd_command_write(0x01);
  218.         lcd_command_write(0x06);
  219.         lcd_command_write(0x0c);
  220. }

  221. /*LCD1602字符写入*/
  222. void lcd_char_write(uint x_pos,y_pos,lcd_dat)

  223. {
  224.         x_pos &=0x0f;/*X位置范围 0~15*/
  225.         y_pos &=0x01;/*Y位置范围 0~1*/
  226.         if(y_pos==1)
  227.         x_pos +=0x40;
  228.         x_pos +=0x80;

  229.         lcd_command_write(x_pos);
  230.         lcd_busy_wait();
  231.         lcd_rs_port=1;
  232.         lcd_rw_port=0;
  233.         lcd_en_port=0;
  234.         lcd_data_port=lcd_dat;
  235.         lcd_en_port=1;
  236.         lcd_en_port=0;}

  237. /*LCD1602坏点检查*/
  238. void lcd_bad_check()
  239. {
  240.         char i,j;
  241.         for(i=0;i<2;i++)
  242.         {
  243.                 for(j=0;j<16;j++)
  244.                 {
  245.                 lcd_char_write(j,i,0xff);
  246.                 }
  247.         }
  248.         lcd_delay(200);
  249.         lcd_delay(200);
  250.         lcd_delay(200);
  251.         lcd_delay(100);
  252.         lcd_delay(200);
  253.         lcd_command_write(0x01);/*clearlcddisp*/
  254. }
  255. //////////////////以上是 LCD1602驱动程序////////////////
  256. void Delay(uint n)
  257.         {
  258.         uint x;
  259.         while(n--)
  260.         {
  261.         x=500;
  262.         while(x--);
  263.         }
  264.         }
  265. /*1MS为单位的延时程序*/
  266. void delay_1ms(uchar x)
  267. {
  268.         uchar j;
  269.         while(x--)
  270.         {
  271.         for(j=0;j<125;j++)
  272.         {;}                           
  273.         }
  274. }


  275. float adadverage()
  276. {
  277.         float adverageval;
  278.         unsigned char i;
  279.         for(i=0;i<200;i++)
  280.         {
  281.           adverageval += GetADCResult(0);
  282.         }
  283.           adverageval=adverageval/200;
  284.           return(adverageval);
  285. }
复制代码

所有资料51hei提供下载:
程序.rar (33.74 KB, 下载次数: 20)







欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1