单片机/MCU论坛
直播中

莫亿龙

5年用户 4经验值
擅长:电气
私信 关注
[问答]

基于52单片机的自动切换量程的数字电压表为什么不能很好地切换量程和查询以往电压值?

  1. #include
  2. #include
  3. #include
  4. #include
  5. sfr P1M0=0x92;
  6. sfr P1M1=0x91;
  7. sfr P2M0=0x96;
  8. sfr P2M1=0x95;
  9. sfr P3M0=0xb2;
  10. sfr P3M1=0xb1;
  11. #define uint  unsigned int
  12. #define uchar unsigned char
  13. ***it cs=P1^0;                                                          //0832引脚
  14. ***it clk=P1^1;
  15. ***it di=P1^2;
  16. ***it do0832=P1^3;
  17. ***it relay=P1^4;
  18. ***it led=P1^7;                                                 //LED报警
  19. ***it SFTCLK=P2^2;                                          //595引脚
  20. ***it LCHCLK=P2^1;          
  21. ***it SDI=P2^0;
  22. ***it k1=P3^2;
  23. ***it k2=P3^3;
  24. uchar smgduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
  25. uchar smgwei[]={0xef,0xdf,0xbf,0x7f};
  26. uint t[30];
  27. uchar i=0,j=0,k,ch1=0,ch2=0;
  28. void delay()                                                        //延时5us
  29. {
  30.         uchar a;
  31.         _nop_();
  32.         a=11;
  33.         while(--a);
  34. }
  35. #define pulse {delay();clk=1;delay();clk=0;} //595脉冲
  36. void adc()interrupt 1                     //1s一次adc
  37. {
  38.             uchar a,b;
  39.                 j=0;                       
  40.                 cs=0;                                             //允许0832
  41.                 di=1;
  42.                 pulse;                                                   //第一个脉冲,起始信号
  43.                 di=1;
  44.                 pulse;                                                   //第二个脉冲,DI=1表示双通道单极性输入
  45.                 di=1;
  46.                 pulse;                                                 //第三个脉冲,DI=1表示选择通道1(CH1)
  47.                 for(a=0;a<8;a++)                          //在每个脉冲的下降沿DO输出一位数据,最终ch为8位二进制数(读前八位的值)
  48.                 {
  49.                         pulse;
  50.                         ch1<<=1;
  51.                         _nop_();
  52.                         if(do0832==1)
  53.                         ch1|=0x01;
  54.                 }
  55.                 for(b=0;b<8;b++)                    //在每个脉冲的下降沿DO输出一位数据,最终ch为8位二进制数(读后八位的值)
  56.                 {               
  57.                         ch2>>=1;
  58.                         if(do0832==1)
  59.                         ch2|=0x80;
  60.                         pulse;
  61.                 }                       
  62.                 cs=1;                                                //释放ADC0832
  63.                 i++;
  64.                 if(i==30)
  65.                 {
  66.                         memset(t,0,sizeof(t));        //将t[i]初始化
  67.                         i=0;
  68.                 }                               
  69.                 t[i]=ch1;

  70.        
  71.                
  72.         TH0=(65535-50000)/256;
  73.         TL0=(65536-50000)%256;               
  74. }
  75. void hc595(uchar x,uchar y)                        //595串行输入
  76. {
  77.         int a,b;
  78.         for(a=0;a<8;a++)
  79.         {
  80.                 x<<=1;
  81.                 SDI=CY;
  82.                 SFTCLK=0;
  83.                 _nop_();       
  84.                 SFTCLK=1;
  85.         }
  86.         for(b=0;b<8;b++)
  87.         {
  88.                 y<<=1;
  89.                 SDI=CY;
  90.                 SFTCLK=0;
  91.                 _nop_();       
  92.                 SFTCLK=1;
  93.         }
  94.         LCHCLK=0;
  95.         _nop_();
  96.         LCHCLK=1;               
  97. }
  98. void cx()interrupt 0                                         //P32查询
  99. {       
  100.         ET0=0;
  101.         if(i==0)
  102.         {
  103.                 i=29;
  104.         }
  105.         i--;       
  106. }
  107. void fw()interrupt 2                                         //P33继续测电压
  108. {
  109.         i=k;
  110.         ET0=1;
  111. }         
  112. void display()interrupt 3                                 //数码管显示
  113. {
  114.         float m;
  115.         int n;
  116.         if(relay==1)
  117.         m=(t[i]*5.0)/256.0;                               
  118.         else
  119.         m=(t[i]*5.0)/256.0*10;                   //将数字电压换算成模拟电压
  120.         if(i>1)
  121.         {
  122.         if(m<5)                                                //继电器切换量程
  123.         relay=1;
  124.         }
  125.         n=m*100;                                    //用来显示两位小数
  126.         if(n/1000!=0)               
  127.         hc595(smgwei[0],smgduan[n/1000]);                  //十位       
  128.         hc595(smgwei[1],smgduan[n/100%10]|0x80);//个位加小数点
  129.         hc595(smgwei[2],smgduan[n/10%10]);                 //十分位
  130.         hc595(smgwei[3],smgduan[n%10]);                     //百分位
  131.         k=i;
  132.         if(m>20)                                                                 //LED报警
  133.         led=1;
  134.         else
  135.         led=0;

  136. }
  137. void main()
  138. {
  139.         EA=1;                                                                 //初始化
  140.         TMOD=0x01;
  141.         TH0=(65535-50000)/256;
  142.         TL0=(65536-50000)%256;                                 //T0定时时间为50ms        ,选择方式1
  143.         ET0=1;
  144.           TR0=1;
  145.         TH1=(65535-5000)/256;
  146.         TL1=(65536-5000)%256;                                //T1定时时间为5ms,选择方式0
  147.         ET1=1;
  148.           TR1=1;
  149.         IT0=1;
  150.         EX0=1;
  151.         IT1=1;
  152.         EX1=1;
  153.         led=0;
  154.         relay=0;
  155.         while(1);       
  156. }
基于52单片机的自动切换量程的数字电压表
设计一个数字电压表,要求:
(1)要求测量0~20V的模拟电压,能显示两位小数。(5v和20v两档量程)
(2)可自动切换量程。
(3)超过20V时指示灯闪烁。
(4)储存电压值以供查询。

proteus仿真中测试了可以实现从20v到5v量程的切换,但是却不能从5v切换到20v,增加电压值,当电压值达到5v时,显示数值为4.98,继续增加电压值,数值仍然为4.98.而且按下s1按键不能查询以前的电压值。单片机课设,过几天就要交了,麻烦各位了。 自动切换量程的数字电压表

更多回帖

发帖
×
20
完善资料,
赚取积分