找回密码
 立即注册

QQ登录

只需一步,快速开始

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

求大神帮我看看我的LCD为啥不出数,仿真,单片机程序如下

[复制链接]
跳转到指定楼层
楼主


按键实现摄氏度华氏度转换
#include "reg52.h"
#include "intrins.h"
#include "stdio.h"

//================关键字别名定义===========================
typedef unsigned char   uint8;
typedef char            int8;
typedef unsigned int    uint16;
typedef int             int16;
typedef unsigned long   uint32;
typedef long            int32;

//======================端口定义=========================
sbit key = P2^0;
sbit DS18B20_IO = P2^3;        //DS18B20通信端口
#define IO_18B20_L()    DS18B20_IO = 0
#define IO_18B20_H()    DS18B20_IO = 1
#define IO_18B20_R()    (DS18B20_IO)

#define LCD1602_DATA  P0  //定义LCD1602的数据端口
sbit LCD1602_RS = P2^6;//定义LCD1602RS
sbit LCD1602_RW = P2^5;//定义LCD1602RW
sbit LCD1602_E =  P2^4;//定义LCD1602E



uint8 buffer[16];//显示缓冲数组
int16 DS18B20_tpr;
bit HuaShiDuFlg=0;


//10微秒精确延时
void Delay10us(void)
{
   _nop_();
         _nop_();
         _nop_();
         _nop_();
         _nop_();
         _nop_();
}

//50微秒精确延时
void Delay50us(void)
{
         Delay10us();
         Delay10us();
         Delay10us();
         Delay10us();
         Delay10us();
}

//N毫秒精确延时
void DelayNms(uint16 i)
{
         uint8j;
         for(;i;i--)
    {
       j=83;         //延时精度调节
                  for(;j;j--)   Delay10us();
    }
}

/****************LCD1602写入1个字节数据*****************
*@style - 待写入数据的类型:0表示指令,1表示数据
*@dat  - 待写入的指令或数据
**********************************************************/
void LCD1602_WriteOneByte(bit style,uint8dat)
{
   LCD1602_E = 0;
   _nop_();
   _nop_();
   LCD1602_RS = style;     //写入指令或数据标志置位
   LCD1602_RW = 0;
   LCD1602_DATA = dat;     //首先送入数据
   _nop_();
   _nop_();
   LCD1602_E = 1;  //使能置1
   _nop_();
   _nop_();
   LCD1602_E = 0;
}

//LCD1602忙等待,当读取的数据最高位为0时,才可以进行读写操作
void LCD1602_WaitBusy(void)
{
   LCD1602_E = 0;
   LCD1602_DATA = 0xFF;   
   LCD1602_RS = 0;
   LCD1602_RW = 1;
   _nop_();
   _nop_();
   LCD1602_E = 1;  //使能
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   while( LCD1602_DATA & 0x80 ); //检测忙信号,如果为最高位为1则等待
   LCD1602_E = 0;
}

/***************LCD1602在指定位置显示字符串****************
*@hang - 待显示数据的行坐标:0~1
*@lie - 待显示数据的列坐标:0~15
*@pDat - 数据指针,指向待显示数据
**********************************************************/
void LCD1602_DisStr(uint8 hang,uint8lie,uint8 *pDat)                                    
{
   if(hang==0)       lie=0x80+lie;
   else if(hang==1) lie=0xc0+lie;  
   LCD1602_WaitBusy();//写入前需要读忙信号
   LCD1602_WriteOneByte(0,lie);  //发送地址

   while(*pDat)
    {
       LCD1602_WaitBusy();//写入前需要读忙信号
       LCD1602_WriteOneByte(1,*pDat);//发送数据
       pDat++; //数据指针递增
    }
}

void LCD1602_ClrScreen(void)
{
//   LCD1602_WaitBusy();//写入前需要读忙信号
//   LCD1602_WriteOneByte(0,0x01); //清屏
   LCD1602_DisStr(0,0,"               ");
   LCD1602_DisStr(1,0,"               ");
}

//LCD1602初始化,开机时需要初始化一次
void LCD1602_Init(void)
{
   LCD1602_WriteOneByte(0,0x38); //显示模式设置,16*2显示,5*7点阵
   DelayNms(5);
   LCD1602_WriteOneByte(0,0x38); //显示模式设置,16*2显示,5*7点阵
   DelayNms(5);
   LCD1602_WriteOneByte(0,0x38); //显示模式设置,16*2显示,5*7点阵
   DelayNms(5);
   LCD1602_WriteOneByte(0,0x38); //显示模式设置,16*2显示,5*7点阵
   DelayNms(5);
   LCD1602_WriteOneByte(0,0x08); //关闭显示,关闭光标
   DelayNms(5);
   LCD1602_WriteOneByte(0,0x01); //清屏
   DelayNms(5);
   LCD1602_WriteOneByte(0,0x06); //设置显示光标地址递增
   DelayNms(5);
   LCD1602_WriteOneByte(0,0x0C); //开显示
}

//DS18B20初始化
void DS18B20_init(void)
{
   uint8 i;
   
         IO_18B20_H();    // DQ复位
         _nop_();_nop_();     // 稍做延时
         IO_18B20_L();    // 单片机将DQ拉低至少480us以初始化器件
   for(i=0;i<10;i++)  Delay50us();
         IO_18B20_H();    // 释放总线
   // 主机释放总线后15~60us(实测30us左右),器件将总线拉低60~240us(这叫存在脉冲,实测100us左右)后再释放总线
   // 这里延时300us,确保器件已经释放总线
   for(i=0;i<6;i++)  Delay50us();
}

//写一个字节
void DS18B20_WriteOneByte(uint8 dat)
{
         uint8i;

         for(i=0;i<8; i++)
         {
                  IO_18B20_L();   // 启动写时序
       if(dat&0x01)    // 1时要在15us内释放总线;写0至少要拉低60us总线,然后再释放
       {
           _nop_();_nop_();
           IO_18B20_H();
       }
       Delay50us();Delay10us();
       IO_18B20_H();
       _nop_();  // 写周期间隔时间最小为1us
                  dat>>= 1;
         }
}

//读一个字节
uint8 DS18B20_ReadOneByte(void)
{
         uint8i;
         uint8dat=0;

         for(i=0;i<8; i++)
         {
                  IO_18B20_L();// 启动读时序,低电平至少保持1us
                  dat>>=1;
       _nop_();
                  IO_18B20_H();// 释放总线,在15us内读数据
       _nop_();_nop_();
                  if(IO_18B20_R())  dat |= 0x80;
                  Delay10us();Delay10us();Delay10us();Delay10us();
         }
   
         returndat;
}

//读取温度,结果支持负温度值
void DS18B20_GetTpr(int16 *pTemper)
{
         staticuint8 step=0;
   static uint8 i=0;
   uint8 LByte;
         uint8HByte;
         int16dat;
   
   if(step==0)
    {
       DS18B20_init();
       DS18B20_WriteOneByte(0xCC); // 跳过读序列号的操作
       DS18B20_WriteOneByte(0x44); // 启动温度转换
       step=1;
       i=0;
    }
   else if(step==1) // 延时500ms左右去取温度值
    {
       i++;
       if(i>=50)
       {
           i=0;
           step=2;
       }
    }
   else if(step==2)
    {
       DS18B20_init();
       DS18B20_WriteOneByte(0xCC);    // 跳过读序列号的操作
       DS18B20_WriteOneByte(0xBE);    // 读取温度寄存器等(共可读9个寄存器) 前两个就是温度
       LByte = DS18B20_ReadOneByte(); // 先读温度的低字节
       HByte = DS18B20_ReadOneByte(); // 再读温度的高字节
       dat   = ((uint16)HByte<<8) |LByte; // 合成数据
       // 分辨率为0.0625,结果 = dat*0.0625 = dat*5/80,结果范围为-55 ~ 125
       *pTemper = dat*5/8; // 换算温度,放大10
       step=0;
    }
}


void KeyScan(void)
{
   static uint8 KeyCnt=0;

   if(key==0)
    {
       if(KeyCnt<0xff)  KeyCnt++;
       if(KeyCnt==10)
       {
           HuaShiDuFlg=!HuaShiDuFlg;
       }
    }
   else  KeyCnt=0;
}

void LcdDisplay(void)
{
   float buf;
   
   if(HuaShiDuFlg==0) // 显示摄氏度
    {
       sprintf(buffer,"T:%05.1f C",DS18B20_tpr/10.0);
       LCD1602_DisStr(0,0,buffer);
    }
   else   // 显示华氏度, 华氏度 = 摄氏度*1.8+32
    {
       buf  = DS18B20_tpr*0.18+32; // 因为温度是乘了10保留了1个小数位在里面,所以这里要先除10,算下来就是乘0.18
       sprintf(buffer,"T:%05.1f F",buf);
       LCD1602_DisStr(0,0,buffer);
    }
}

void main(void)
{
   LCD1602_Init();
         
         while(1)
         {
       DS18B20_GetTpr(&DS18B20_tpr);
       KeyScan();
       LcdDisplay();
       DelayNms(10);
         }
}


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

使用道具 举报

沙发
ID:761750 发表于 2020-5-26 16:49 | 只看该作者
不是不显示,是不出数
回复

使用道具 举报

板凳
ID:584814 发表于 2020-5-27 06:06 来自手机 | 只看该作者
抄程序很累吧 ?直接搭个实景就知道问题所在了,纸上谈兵总会丢三落四。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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