微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 1602仿真可以显示 实际只显示一行,可以帮我看看程序有错吗?

1602仿真可以显示 实际只显示一行,可以帮我看看程序有错吗?

时间:10-02 整理:3721RD 点击:
1602仿真可以显示  实际只显示一行,可以帮我看看程序有错吗?

  1. #include<reg52.h>
  2. #include<stdlib.h>
  3. #include<intrins.h>
  4. #include<eeprom52.h>
  5. #define uchar unsigned char
  6. #define uint unsigned int
  7. #define Imax 14000    //此处为晶振为11.0592时的取值,
  8. #define Imin 8000    //如用其它频率的晶振时,
  9. #define Inum1 1450    //要改变相应的取值。
  10. #define Inum2 700
  11. #define Inum3 3000

  12. sbit DQ=P2^1;//ds18b20与单片机连接口
  13. sbit RS=P2^5;
  14. sbit RW=P2^6;
  15. sbit EN=P2^7;
  16. sbit K1=P2^2;
  17. sbit K2=P2^3;
  18. sbit K3=P2^4;                  //按键定义
  19. sbit PWM=P2^0;                  //PWM输出
  20. unsigned char Im[4]={0x00,0x00,0x00,0x00};
  21. unsigned long m,Tc;
  22. unsigned char IrOK;          //定义红外工作变量
  23. uchar mode;
  24. uint TH,TL;                          //上下限变量
  25. uchar baif,suiji;
  26. uchar code zhuanhuan[4]={0,3,5,10};//转换数组
  27. void   jisuan();          //声明计算函数
  28. char f,dang,count,count1,a_a;  //档位


  29. unsigned char code duan[]={"0123456789abcdef- "};
  30. unsigned char code str1[]={"L:00.0C  H:00.0C"};
  31. unsigned char code str2[]={"M:0 D:0  T:    C"};

  32. uchar data disdata[5];
  33. uint tvalue;//温度值
  34. uchar tflag;//温度正负标志
  35. void write_eeprom()                           //内部eeprom写函数
  36. {

  37.         SectorErase(0x2000);                   //清空
  38.         SectorErase(0x2c00);
  39.         SectorErase(0x2e00);
  40.         byte_write(0x2c00,TH/256);       
  41.         byte_write(0x2c01,TH%256);
  42.         byte_write(0x2c02,TL/256);
  43.         byte_write(0x2c03,TL%256);           //将上下限数据保存到eeprom
  44.         byte_write(0x2c04,dang);       
  45.         byte_write(0x2c05,mode);               
  46.         byte_write(0x2060,0x01);

  47. }         

  48. /******************把数据从单片机内部eeprom中读出来*****************/
  49. void read_eeprom()                                                                                                                                  
  50. {

  51.     mode = byte_read(0x2c05);
  52.         dang = byte_read(0x2c04);
  53.         TH = byte_read(0x2c00)*256+byte_read(0x2c01);
  54.         TL = byte_read(0x2c02)*256+byte_read(0x2c03);
  55.         a_a = byte_read(0x2060);
  56.          
  57. }               

  58. /**************开机自检eeprom初始化*****************/
  59. void init_eeprom()
  60. {
  61.         a_a = byte_read(0x2060);
  62.         if(a_a != 1)                //新的单片机初始单片机内问eeprom
  63.         {
  64.        
  65.                 a_a = 1;
  66.                 write_eeprom();           //保存数据
  67.         }       
  68. }                 


  69. /*************************lcd1602程序**************************/
  70. void delay1ms(unsigned int ms)//延时1毫秒(不够精确的)
  71. {unsigned int i,j;
  72.    for(i=0;i<ms;i++)
  73.     for(j=0;j<100;j++);
  74. }


  75. void wr_com(unsigned char com)//写指令//
  76. {  delay1ms(10);
  77.    RS=0;
  78.    RW=0;
  79.    EN=0;
  80.    P0=com;
  81.    delay1ms(1);
  82.    EN=1;
  83.    delay1ms(1);
  84.    EN=0;
  85.   }

  86. void wr_dat(unsigned char dat)//写数据//
  87. {  delay1ms(10);
  88.    RS=1;
  89.    RW=0;
  90.    EN=0;
  91.    P0=dat;
  92.    delay1ms(1);
  93.    EN=1;
  94.    delay1ms(1);
  95.    EN=0;
  96. }

  97. void lcd_init()//初始化设置//
  98. {delay1ms(15);
  99.   wr_com(0x38);delay1ms(5);
  100.   wr_com(0x38);delay1ms(5);
  101.    wr_com(0x08);delay1ms(5);
  102.     wr_com(0x01);delay1ms(5);
  103.      wr_com(0x06);delay1ms(5);
  104.       wr_com(0x0c);delay1ms(5);
  105. }


  106. void display(unsigned char *p)//显示//
  107. {
  108. while(*p!='\0')
  109. {
  110. wr_dat(*p);
  111. p++;
  112. delay1ms(2);
  113. }
  114. }

  115.   init_play()//初始化显示
  116.   { lcd_init();
  117.     wr_com(0x80);
  118.          display(str1);
  119.          delay1ms(1);
  120.          wr_com(0xc0);
  121.          display(str2);
  122.    }

  123. /******************************ds1820程序***************************************/
  124. void delay(unsigned int i)//延时1微秒
  125. {
  126.         while(i--);
  127. }

  128. void ds1820rst()/*ds1820复位*/
  129. {  unsigned char x=0;
  130.          DQ = 1;          //DQ复位
  131.          delay(4);  //延时
  132.          DQ = 0;          //DQ拉低
  133.          delay(100); //精确延时大于480us
  134.          DQ = 1;          //拉高
  135.          delay(40);         
  136.    }  
  137.   
  138.    uchar ds1820rd()/*读数据*/
  139.   { unsigned char i=0;
  140.          unsigned char dat = 0;
  141.          for (i=8;i>0;i--)
  142.          {   DQ = 0; //给脉冲信号
  143.                   dat>>=1;
  144.                   DQ = 1; //给脉冲信号
  145.                   if(DQ)
  146.                   dat|=0x80;
  147.                   delay(10);
  148.          }
  149.         return(dat);
  150.   }

  151.   void ds1820wr(uchar wdata)/*写数据*/
  152.   {unsigned char i=0;
  153.     for (i=8; i>0; i--)
  154.    { DQ = 0;
  155.      DQ = wdata&0x01;
  156.      delay(10);
  157.      DQ = 1;
  158.      wdata>>=1;
  159.    }
  160. }
  161.   


  162.   read_temp()/*读取温度值并转换*/
  163. {uchar a,b;
  164.   ds1820rst();   
  165.   ds1820wr(0xcc);//*跳过读序列号*/
  166.   ds1820wr(0x44);//*启动温度转换*/
  167.   ds1820rst();   
  168.   ds1820wr(0xcc);//*跳过读序列号*/
  169.   ds1820wr(0xbe);//*读取温度*/
  170.   a=ds1820rd();
  171.   b=ds1820rd();
  172.   tvalue=b;
  173.   tvalue<<=8;
  174.   tvalue=tvalue|a;
  175.   if(tvalue<0x0fff)
  176.   tflag=0;
  177.   else
  178.   {
  179.     tvalue=~tvalue+1;
  180.        
  181.         tflag=1;
  182.   }
  183.   
  184.   tvalue=tvalue*(0.625);//温度值扩大10倍,精确到1位小数  
  185.   return(tvalue);
  186. }
  187. /*******************************************************************/
  188.   
  189.    void ds1820disp()//温度值显示
  190.         { uchar flagdat;
  191.          
  192.      disdata[1]=tvalue%1000/100+0x30;//十位数
  193.      disdata[2]=tvalue%100/10+0x30;//个位数
  194.      disdata[3]=tvalue%10+0x30;//小数位
  195.    
  196.      if(tflag==0)
  197.             flagdat=0x20;//正温度不显示符号
  198.      else
  199.        flagdat=0x2d;//负温度显示负号:-

  200.    

  201.            wr_com(0xc2);
  202.            wr_dat(duan[mode]);
  203.            wr_com(0xcb);
  204.            wr_dat(disdata[1]);//显示十位        
  205.            wr_com(0xcc);
  206.            wr_dat(disdata[2]);//显示个位        
  207.            wr_com(0xcd);
  208.            wr_dat(0x2e);//显示小数点        
  209.            wr_com(0xce);
  210.            wr_dat(disdata[3]);//显示小数位

  211.             wr_com(0x80+0x02);
  212.                 wr_dat(duan[TL%1000/100]);
  213.                 wr_com(0x80+0x03);
  214.                 wr_dat(duan[TL%100/10]);
  215.                 wr_com(0x80+0x05);
  216.                 wr_dat(duan[TL%10]);
  217.                 wr_com(0x80+0x0b);
  218.                 wr_dat(duan[TH%1000/100]);
  219.                 wr_com(0x80+0x0c);
  220.                 wr_dat(duan[TH%100/10]);
  221.                 wr_com(0x80+0x0e);
  222.                 wr_dat(duan[TH%10]);
  223.                 wr_com(0xc6);
  224.             wr_dat(duan[dang]);
  225.    }
  226.    
  227. void key()                                                          //按键函数
  228. {
  229.   if(K1==0||(Im[2]==0x47&&IrOK==1))          //按键1按下或者遥控器上的按键按下
  230.   {
  231.                  delay(5);                                                  //延时去抖

  232.                         if(K1==0||(Im[2]==0x47&&IrOK==1)) //再次判断按键按下
  233.                 {
  234.                         //BUZZ=0;
  235.                         //delay(20);
  236.                         //BUZZ=1;                                                  //按键音
  237.                  mode++;                                                  //模式加
  238.                  if(mode>3)                                                  //模式加到大于3
  239.                  mode=0;                                                  //模式清零
  240.                  Im[2]=0;
  241.                  IrOK=0;                                                  //变量清零
  242.                  write_eeprom();                                  //写入eeprom数据
  243.                  while(!K1);                                          //按键释放
  244.                 }
  245.   }
  246.   if(K2==0||(Im[2]==0x40&&IrOK==1))
  247.   {
  248.    delay(5);

  249.     if(K2==0||(Im[2]==0x40&&IrOK==1))
  250.         {       
  251.                 //BUZZ=0;
  252.                 //delay(20);
  253.                 //BUZZ=1;
  254.          if(mode==0)                                        //模式等于0时
  255.          {
  256.           TH++;                                                        //上限加
  257.           if(TH>999)                                        //上限加到大于99.9度
  258.                  
  259.           TH=TL+1;                                                //上限等于下限加一
  260.          }
  261.          else if(mode==1)                                //模式等于1时
  262.          {
  263.           TL++;                                                        //下限加
  264.           if(TL>=TH)                                        //下限加到大于等于上限
  265.           TL=TH-1;                                                //下限等于上限减一
  266.          }
  267.           else if(mode==3)                                //模式等于3时
  268.          {
  269.           dang++;                                                //档位加一
  270.           if(dang>3)                                        //档位大于3时
  271.           dang=0;                                                //档位清零
  272.          }
  273.          Im[2]=0;
  274.          IrOK=0;                                                //红外变量清零
  275.          write_eeprom();                                //写入eeprom数据
  276.          while(!K2);                                        //按键释放
  277.         }
  278.         }
  279.          if(K3==0||(Im[2]==0x19&&IrOK==1))
  280.   {
  281.    delay(5);
  282.           if(K3==0||(Im[2]==0x19&&IrOK==1))
  283.         {
  284.                 //BUZZ=0;
  285.                 //delay(20);
  286.                 //BUZZ=1;
  287.          if(mode==0)
  288.          {
  289.           TH--;
  290.           if(TH<=TL)
  291.           TH=TL+1;
  292.          }
  293.          else if(mode==1)
  294.          {
  295.           TL--;
  296.           if(TL>=TH)
  297.           TL=TH-1;
  298.          }
  299.           else if(mode==3)
  300.          {
  301.            dang--;
  302.           if(dang<0)
  303.           dang=3;
  304.          }
  305.          //Im[2]=0;
  306.          //IrOK=0;
  307.           write_eeprom();
  308.          while(!K3);
  309.         }
  310.   }

  311. }

  312. void jisuan()                                                          //计算函数

  313. {
  314.   if(mode==0||mode==1||mode==2) //模式0、1、2并且热释电有信号时
  315.   {
  316.     if(tvalue<=TL)                                                 //温度小于下限时
  317.         PWM=1;                                                                 //关闭输出,占空比0%
  318.         else if(tvalue>=TH)                                         //温度大于等于上限
  319.         PWM=0;                                                                 //打开输出,占空比100%
  320.         else                                                                  //其他状态时
  321.         {
  322.           baif=(((tvalue-TL)*50)/(TH-TL));   //占空比控制变量计算得到
  323. //计算方法:当前温度减去下限值乘以5再除以上限减下限
  324.           if(count1>baif) //根据变量判断占空比大小
  325.           PWM=0;                  //关闭风扇
  326.           else
  327.           PWM=1;                  //打开风扇
  328.         }
  329.   }
  330.   else if(mode==3)                                           //模式3时
  331.   {
  332.     if(count1>=(zhuanhuan[dang]*5))           //根据档位计算出占空比
  333.         PWM=1;
  334.         else
  335.         PWM=0;
  336.   }

  337. }
  338. /********************主程序***********************************/
  339. void main()
  340. {
  341.                                             //定义变量
  342.   unsigned int i=0,j=0;
  343.   EA=1;                                                          //打开中断总开关
  344.   EX1=1;                                                  //打开外部中断1
  345.   IT1=1;                                                  //下降沿有效
  346.   TMOD=0x11;                                          //定时器工作方式

  347.   TR0=0;                                                  //关闭T0
  348.   TH0=0;
  349.   TL0=0;                                                  //初值0  
  350.   ET1=1;                                                  //T1允许中断

  351.   TR1=1;                                                  //T1打开中断
  352.   TH1=0xfc;
  353.   TL1=0x18;                                                  //T1初值1ms
  354.   mode=0;                                                  //初始模式0
  355.   TH=300;
  356.   TL=200;                                                  //上下限初始值
  357.   init_eeprom();                                  //初始化eeprom

  358.   read_eeprom();                                  //读取eeprom数据
  359.           
  360.   init_play();                     //初始化显示       
  361. while(1)                                                  //进入循环
  362.         {            
  363.                 jisuan();                                  //计算函数
  364. /*                count++;                                  //变量加
  365.                 if(count>200)                          //加到大于200
  366.                 {
  367.                         count=0;                          //清零
  368.                         TR1=0;                          //关闭定时器T1
  369. //                        read_temp();//读取温度
  370.                        
  371.                         TR1=1;                                  //打开定时器T1
  372.                 } */
  373.                 read_temp();//读取温度
  374.                 ds1820disp();       
  375.                 jisuan();                                  //计算函数
  376.                                            //显示函数  */
  377.               key();                                          //按键函数
  378.                 jisuan();                                  //计算函数
  379.                         }

  380.    
  381. }
  382. void timer1() interrupt 3                  //定时器T1工作函数
  383. {
  384. TH1=0xfc;
  385. TL1=0x18;                                                  //重新赋初值

  386.   count1++;                                                  //加
  387.   if(count1>50)
  388.   {
  389.           count1=0;

  390.   }
  391. }
  392. void intersvr1(void) interrupt 2                 //红外工作函数
  393. {
  394. TR0=1;
  395. Tc=TH0*256+TL0;//提取中断时间间隔时长
  396. TH0=0;
  397. TL0=0;         //定时中断重新置零
  398. if((Tc>Imin)&&(Tc<Imax))
  399. {
  400.         m=0;
  401.         f=1;

  402.         return;
  403. }       //找到启始码
  404. if(f==1)
  405. {
  406.     if(Tc>Inum1&&Tc<Inum3)
  407.     {
  408.            Im[m/8]=Im[m/8]>>1|0x80; m++;
  409.     }
  410.     if(Tc>Inum2&&Tc<Inum1)
  411.     {
  412.       Im[m/8]=Im[m/8]>>1; m++; //取码
  413.            }
  414.            if(m==32)
  415.     {
  416.       m=0;  
  417.       f=0;
  418.        
  419.       if(Im[2]==~Im[3])
  420.       {
  421.            IrOK=1;
  422.                           TR0=0;
  423.            }
  424.       else
  425.           {
  426.            IrOK=0;   //取码完成后判断读码是否正确

  427.            }
  428.     }
  429.                //准备读下一码
  430. }


  431. }

复制代码




P0口有接上拉电阻吗

有接   程序有没有问题?

程序似乎没问题,试试在写液晶最后的EN=0再加一个delay1ms(10);,如果可以的话,最好加一段查液晶是否忙的程序

是否是亮度调节的问题           

我重新焊接过一个电路板了  现在可以用了应该是电路焊接问题 像仿真那样 解决了

电路焊接问题 我解决了 谢谢了

解决了 应该是电路焊接的问题  谢谢大家了

多谢共享,参考参考

好的  要是用洞洞板搞的话 飞线什么的要多加留意

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top