找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4931|回复: 10
收起左侧

程序加载入Proteus中仿真没反应,烧入买来的单片机开发板就可以显示,这是什么原因?

[复制链接]
ID:481409 发表于 2019-3-26 19:24 | 显示全部楼层 |阅读模式
程序加载入Proteus中仿真没反应,烧入买来的单片机开发板就可以显示,这是什么原因?

1111111.png
2222222222222222.jpg

仿真.zip

89.76 KB, 下载次数: 15

程序和仿真

回复

使用道具 举报

ID:481409 发表于 2019-3-26 22:45 | 显示全部楼层
仿真运行时,发现DS18B20一直是红色的高电平,写了一串用来显示的字符的程序加载进去运行,LCD可以正常显示,LCD应该没问题,就是DS18B20为什么一直是高电平,我改了下引脚烧进开发板,结果都可以正常读取温度,就是仿真不行,各位看看什么情况???
回复

使用道具 举报

ID:140489 发表于 2019-3-27 09:53 | 显示全部楼层
ds18b20的DQ脚接个上拉电阻试试
回复

使用道具 举报

ID:426861 发表于 2019-3-27 10:25 | 显示全部楼层
看下你的开发板上的相关电路和仿真的电路哪里有不同
回复

使用道具 举报

ID:213173 发表于 2019-3-27 10:55 | 显示全部楼层
本帖最后由 wulin 于 2019-3-27 11:32 编辑

判忙函数有点不兼容,屏蔽掉即可正常仿真。或按如下修也可以正常仿真。/*------------------------------------------------
              判忙函数
------------------------------------------------*/
bit LCD_Check_Busy(void)
{
        bit i;
        DataPort= 0xFF;
        RS_CLR;
        RW_SET;
        EN_SET;
        _nop_();
        i=(bit)(DataPort & 0x80);
        EN_CLR;
        return i;
}



回复

使用道具 举报

ID:481409 发表于 2019-3-27 11:29 | 显示全部楼层
wulin 发表于 2019-3-27 10:55
判忙函数有点不兼容,屏蔽掉即可正常仿真。

您好,我把判忙函数屏蔽了,结果可以显示,但是仿真时一直提示LCD is busy,还有原本是显示Temp +温度℃,但是现在显示的是emp+温度℃,这是怎么回事?   还有仿真时判忙函数屏蔽那做实物的时候需要屏蔽吗?还是说我的判忙函数写的有问题。  谢谢
回复

使用道具 举报

ID:213173 发表于 2019-3-27 13:53 | 显示全部楼层
爱学习的佩奇 发表于 2019-3-27 11:29
您好,我把判忙函数屏蔽了,结果可以显示,但是仿真时一直提示LCD is busy,还有原本是显示Temp +温度℃ ...

把判忙函数按如下修改即可正常仿真。
bit LCD_Check_Busy(void)
{
        bit i;
        DataPort= 0xFF;
        RS_CLR;
        RW_SET;
        EN_SET;
        _nop_();
        i=(bit)(DataPort & 0x80);
        EN_CLR;
        return i;
}
回复

使用道具 举报

ID:213173 发表于 2019-3-27 14:29 | 显示全部楼层
爱学习的佩奇 发表于 2019-3-27 11:29
您好,我把判忙函数屏蔽了,结果可以显示,但是仿真时一直提示LCD is busy,还有原本是显示Temp +温度℃ ...

也可以这样改成-55~128度测温
无标题.jpg

  1. /*-----------------------------------------------
  2.   名称:DS18b20 温度检测液晶显示
  3.   编写:shifang
  4.   日期:2009.5
  5.   修改:无
  6.   内容:
  7. ------------------------------------------------*/
  8. #include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
  9. #include<intrins.h>
  10. #include<stdio.h>
  11. #define RS_CLR RS=0
  12. #define RS_SET RS=1
  13. #define RW_CLR RW=0
  14. #define RW_SET RW=1
  15. #define EN_CLR EN=0
  16. #define EN_SET EN=1
  17. #define DataPort P0
  18. sbit RS = P2^0;   //定义端口
  19. sbit RW = P2^1;
  20. sbit EN = P2^2;
  21. sbit DQ=P1^0;//ds18b20 端口
  22. unsigned char Temp[]={'T','e','m','p',':','\0'};
  23. unsigned char TempData[]={0,0,0,'.',0,0,0x01,'C','\0'}; //存储显示值的全局变量
  24. bit ReadTempFlag;//定义读时间标志
  25. /*------------------------------------------------
  26.                     定时器初始化子程序
  27. ------------------------------------------------*/
  28. void Init_Timer0(void)
  29. {
  30.         TMOD= 0x01;          //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响                     
  31.         TH0=(65536-2000)/256;        //赋值 2ms
  32.         TL0=(65536-2000)%256;
  33.         EA=1;            //总中断打开
  34.         ET0=1;           //定时器中断打开
  35.         TR0=1;           //定时器开关打开
  36. }
  37. /*------------------------------------------------
  38.                  定时器中断子程序
  39. ------------------------------------------------*/
  40. void Timer0_isr(void) interrupt 1
  41. {
  42.         static unsigned int num;
  43.         TH0=(65536-2000)/256;                  //重新赋值 2ms
  44.         TL0=(65536-2000)%256;        
  45.         num++;
  46.         if(num==300)        //
  47.         {
  48.                 num=0;
  49.                 ReadTempFlag=1; //读标志位置1
  50.         }
  51. }
  52. /*------------------------------------------------
  53. uS延时函数,含有输入参数 unsigned char t,无返回值
  54. unsigned char 是定义无符号字符变量,其值的范围是
  55. 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
  56. 长度如下 T=tx2+5 uS
  57. ------------------------------------------------*/
  58. void DelayUs2x(unsigned char t)
  59. {   
  60.         while(--t);
  61. }
  62. /*------------------------------------------------
  63. mS延时函数,含有输入参数 unsigned char t,无返回值
  64. unsigned char 是定义无符号字符变量,其值的范围是
  65. 0~255 这里使用晶振12M,精确延时请使用汇编
  66. ------------------------------------------------*/
  67. void DelayMs(unsigned char t)
  68. {     
  69.         while(t--)
  70.         {
  71.                  //大致延时1mS
  72.                  DelayUs2x(245);
  73.                  DelayUs2x(245);
  74.         }
  75. }

  76. /*------------------------------------------------
  77.               判忙函数
  78. ------------------------------------------------*/
  79. bit LCD_Check_Busy(void)
  80. {
  81.         bit i;
  82.         DataPort= 0xFF;
  83.         RS_CLR;
  84.         RW_SET;
  85.         EN_SET;
  86.         _nop_();
  87.         i=(bit)(DataPort & 0x80);
  88.         EN_CLR;
  89.         return i;
  90. }
  91. /*------------------------------------------------
  92.               写入命令函数
  93. ------------------------------------------------*/
  94. void LCD_Write_Com(unsigned char com)
  95. {  
  96.         while(LCD_Check_Busy()); //忙则等待
  97.         RS_CLR;
  98.         RW_CLR;
  99.         EN_SET;
  100.         DataPort= com;
  101.         _nop_();
  102.         EN_CLR;
  103. }
  104. /*------------------------------------------------
  105.               写入数据函数
  106. ------------------------------------------------*/
  107. void LCD_Write_Data(unsigned char Data)
  108. {
  109.         while(LCD_Check_Busy()); //忙则等待
  110.         RS_SET;
  111.         RW_CLR;
  112.         EN_SET;
  113.         DataPort= Data;
  114.         _nop_();
  115.         EN_CLR;
  116. }

  117. /*------------------------------------------------
  118.                 清屏函数
  119. ------------------------------------------------*/
  120. void LCD_Clear(void)
  121. {
  122.         LCD_Write_Com(0x01);
  123.         DelayMs(5);
  124. }
  125. /*------------------------------------------------
  126.               写入字符串函数
  127. ------------------------------------------------*/
  128. void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
  129. {     
  130.         if (y == 0)
  131.         {     
  132.                 LCD_Write_Com(0x80 + x);     //表示第一行
  133.         }
  134.         else
  135.         {      
  136.                 LCD_Write_Com(0xC0 + x);      //表示第二行
  137.         }        
  138.         while (*s)
  139.         {     
  140.                 LCD_Write_Data( *s);     
  141.                 s ++;     
  142.         }
  143. }
  144. /*------------------------------------------------
  145.               写入字符函数
  146. ------------------------------------------------*/
  147. /*
  148. void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
  149. {     
  150. if (y == 0)
  151.          {     
  152.          LCD_Write_Com(0x80 + x);     
  153.          }   
  154. else
  155.          {     
  156.          LCD_Write_Com(0xC0 + x);     
  157.          }        
  158. LCD_Write_Data( Data);  
  159. }*/
  160. /*------------------------------------------------
  161.               初始化函数
  162. ------------------------------------------------*/
  163. void LCD_Init(void)
  164. {
  165.         LCD_Write_Com(0x38);    /*显示模式设置*/
  166.         DelayMs(5);
  167.         LCD_Write_Com(0x38);
  168.         DelayMs(5);
  169.         LCD_Write_Com(0x38);
  170.         DelayMs(5);
  171.         LCD_Write_Com(0x38);  
  172.         LCD_Write_Com(0x08);    /*显示关闭*/
  173.         LCD_Write_Com(0x01);    /*显示清屏*/
  174.         LCD_Write_Com(0x06);    /*显示光标移动设置*/
  175.         DelayMs(5);
  176.         LCD_Write_Com(0x0C);    /*显示开及光标设置*/
  177. }
  178. /*------------------------------------------------   
  179. 设定二个自定义字符,LCD1602中自定义字符的地址为0x00--0x07,
  180. 即可定义8个字符
  181. 这里我们设定把一个自定义字符放在0x00位置(000),
  182. 另一个放在0x01位子(001)
  183. ------------------------------------------------*/

  184. void Lcd_User_Chr(void)
  185. { //第一个自定义字符
  186. LCD_Write_Com(0x40); //"01 000 000"  第1行地址 (D7D6为地址设定命令形式D5D4D3为字符存放位置(0--7),D2D1D0为字符行地址(0--7))
  187. LCD_Write_Data(0x00); //"XXX 11111" 第1行数据(D7D6D5为XXX,表示为任意数(一般用000),D4D3D2D1D0为字符行数据(1-点亮,0-熄灭)
  188. LCD_Write_Com(0x41); //"01 000 001"  第2行地址
  189. LCD_Write_Data(0x04); //"XXX 10001" 第2行数据
  190. LCD_Write_Com(0x42); //"01 000 010"  第3行地址
  191. LCD_Write_Data(0x0e); //"XXX 10101" 第3行数据
  192. LCD_Write_Com(0x43); //"01 000 011"  第4行地址
  193. LCD_Write_Data(0x0e); //"XXX 10001" 第4行数据
  194. LCD_Write_Com(0x44); //"01 000 100"  第5行地址
  195. LCD_Write_Data(0x0e); //"XXX 11111" 第5行数据
  196. LCD_Write_Com(0x45); //"01 000 101"  第6行地址
  197. LCD_Write_Data(0x1f); //"XXX 01010" 第6行数据
  198. LCD_Write_Com(0x46); //"01 000 110"  第7行地址
  199. LCD_Write_Data(0x04); //"XXX 11111" 第7行数据
  200. LCD_Write_Com(0x47); //"01 000 111"  第8行地址
  201.    LCD_Write_Data(0x00); //"XXX 00000" 第8行数据
  202. //第二个自定义字符

  203. LCD_Write_Com(0x48); //"01 001 000"  第1行地址  
  204. LCD_Write_Data(0x03); //"XXX 00001" 第1行数据
  205. LCD_Write_Com(0x49); //"01 001 001"  第2行地址
  206. LCD_Write_Data(0x03); //"XXX 11011" 第2行数据
  207. LCD_Write_Com(0x4a); //"01 001 010"  第3行地址
  208. LCD_Write_Data(0x00); //"XXX 11101" 第3行数据
  209. LCD_Write_Com(0x4b); //"01 001 011"  第4行地址
  210. LCD_Write_Data(0x00); //"XXX 11001" 第4行数据
  211. LCD_Write_Com(0x4c); //"01 001 100"  第5行地址
  212. LCD_Write_Data(0x00); //"XXX 11101" 第5行数据
  213. LCD_Write_Com(0x4d); //"01 001 101"  第6行地址
  214. LCD_Write_Data(0x00); //"XXX 11011" 第6行数据
  215. LCD_Write_Com(0x4e); //"01 001 110"  第7行地址
  216. LCD_Write_Data(0x00); //"XXX 00001" 第7行数据
  217. LCD_Write_Com(0x4f); //"01 001 111"  第8行地址
  218. LCD_Write_Data(0x00); //"XXX 00000" 第8行数据
  219. }
  220. /*------------------------------------------------
  221.                     18b20初始化
  222. ------------------------------------------------*/
  223. bit Init_DS18B20(void)
  224. {
  225.          bit dat=0;
  226.          DQ = 1;    //DQ复位
  227.          DelayUs2x(5);   //稍做延时
  228.          DQ = 0;         //单片机将DQ拉低
  229.          DelayUs2x(200); //精确延时 大于 480us 小于960us
  230.          DelayUs2x(200);
  231.          DQ = 1;        //拉高总线
  232.          DelayUs2x(50); //15~60us 后 接收60-240us的存在脉冲
  233.          dat=DQ;        //如果x=0则初始化成功, x=1则初始化失败
  234.          DelayUs2x(25); //稍作延时返回
  235.          return dat;
  236. }

  237. /*------------------------------------------------
  238.                     读取一个字节
  239. ------------------------------------------------*/
  240. unsigned char ReadOneChar(void)
  241. {
  242.         unsigned char i=0;
  243.         unsigned char dat = 0;
  244.         for (i=8;i>0;i--)
  245.         {
  246.                 DQ = 0; // 给脉冲信号
  247.                 dat>>=1;
  248.                 DQ = 1; // 给脉冲信号
  249.                 if(DQ)
  250.                 dat|=0x80;
  251.                 DelayUs2x(25);
  252.         }
  253.         return(dat);
  254. }
  255. /*------------------------------------------------
  256.                     写入一个字节
  257. ------------------------------------------------*/
  258. void WriteOneChar(unsigned char dat)
  259. {
  260.         unsigned char i=0;
  261.         for (i=8; i>0; i--)
  262.         {
  263.                 DQ = 0;
  264.                 DQ = dat&0x01;
  265.                 DelayUs2x(25);
  266.                 DQ = 1;
  267.                 dat>>=1;
  268.         }
  269.         DelayUs2x(25);
  270. }

  271. /*------------------------------------------------
  272.                     读取温度
  273. ------------------------------------------------*/
  274. unsigned int ReadTemperature(void)
  275. {
  276.         unsigned char a=0;
  277.         unsigned int b=0;
  278.         unsigned int t=0;
  279.         Init_DS18B20();
  280.         WriteOneChar(0xCC); // 跳过读序号列号的操作
  281.         WriteOneChar(0x44); // 启动温度转换
  282.         DelayMs(10);
  283.         Init_DS18B20();
  284.         WriteOneChar(0xCC); //跳过读序号列号的操作
  285.         WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
  286.         a=ReadOneChar();   //低位
  287.         b=ReadOneChar();   //高位
  288.         
  289.         b<<=8;
  290.         t=a+b;
  291.         
  292.         return(t);
  293. }
  294. /*------------------------------------------------
  295.                     主函数
  296. ------------------------------------------------*/
  297. void main (void)
  298. {                  
  299.         unsigned int temp;
  300. //        float temperature;
  301.         long tempM;
  302.         unsigned char TempH,TempL;
  303.         bit negative;//负数标志
  304. //        unsigned char displaytemp[16];//定义显示区域临时存储数组
  305.         LCD_Init();           //初始化液晶
  306.         DelayMs(20);          //延时有助于稳定
  307.         LCD_Clear();          //清屏
  308.         Init_Timer0();
  309.         Lcd_User_Chr();       //写入自定义字符
  310.         
  311. //        LCD_Write_Char(13,0,0x01);//写入温度右上角点
  312. //        LCD_Write_Char(14,0,'C'); //写入字符C
  313.         
  314.         while (1)         //主循环
  315.         {
  316.                 if(ReadTempFlag==1)
  317.                 {
  318.                         ReadTempFlag=0;
  319.                         temp=ReadTemperature();

  320.                         if(temp&0x8000)
  321.                         {
  322.                                 negative=1;                //负号标志
  323.                                 temp=~temp;                //取反加1
  324.                                 temp +=1;
  325.                         }
  326.                         else negative=0;        //正数
  327. //                        temperature=(float)temp*0.0625;
  328.                         tempM=temp*0.0625*100;        //换算为10进制温度值再放大100倍
  329.                         TempH=tempM/100;                                //分解出整数值        
  330.                         TempL=tempM%100;                                //分解出小数值
  331.                         if(negative==1)
  332.                                 TempData[0]='-';//显示负号
  333.                         else if(TempH/100==0)//小于100
  334.                                 TempData[0]=' ';                                                        //百位消隐
  335.                         else
  336.                                 TempData[0]=TempH/100+'0';                         //显示百位温度
  337.         
  338.                         if((TempH/100==0)&&((TempH%100)/10==0))
  339.                                 TempData[1]=' ';                                                        //十位消隐
  340.                         else
  341.                                 TempData[1]=(TempH%100)/10+'0';                //显示十位温度
  342.                         TempData[2]=(TempH%100)%10+'0';                        //显示个位温度
  343. //                        TempData[3]='.';                                                                //显示小数点
  344.                         TempData[4]=TempL/10+'0';                                        //显示温度小数1位
  345.                         TempData[5]=TempL%10+'0';                                        //显示温度小数2位        
  346. //                        TempData[6]=0x01;
  347. //                        TempData[7]='C';                                                                //显示C

  348.                         LCD_Write_String(0,0,Temp);        //写一个字节数据               
  349.                         LCD_Write_String(6,0,TempData);        //写一个字节数据               

  350. //                        sprintf(displaytemp,"Temp  % 7.3f",temperature);//打印温度值
  351. //                        LCD_Write_String(0,0,displaytemp);//显示第二行
  352.                 }        
  353.         }
  354. }
复制代码



回复

使用道具 举报

ID:481409 发表于 2019-3-27 15:29 | 显示全部楼层
wulin 发表于 2019-3-27 10:55
判忙函数有点不兼容,屏蔽掉即可正常仿真。或按如下修也可以正常仿真。/*-------------------------------- ...

您好,我试了下好像不行。
回复

使用道具 举报

ID:213173 发表于 2019-3-27 17:14 | 显示全部楼层
爱学习的佩奇 发表于 2019-3-27 15:29
您好,我试了下好像不行。

看上面代码
回复

使用道具 举报

ID:481409 发表于 2019-3-29 10:24 | 显示全部楼层
wulin 发表于 2019-3-27 14:29
也可以这样改成-55~128度测温

好的,谢谢大神方法,已解决!!!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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