麻烦可不可以帮我看下这个程序问题在哪?急~~~~~~

2019-07-16 05:44发布

#include "reg52.h"
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int

//温度ds18b20 的引脚
sbit ds=P3^0;
//湿度   模数转换adc0809 的引脚
sbit ST=P3^1;   //定义START引脚
sbit OE=P3^3;   //定义OE引脚                 
sbit EOC=P3^2;  //定义EOC引脚
sbit CLK=P3^4;  //定义CLOCK引脚          
//显示数据  lcd1602 的引脚
sbit rs = P3^7;
sbit rw = P3^6;
sbit eq = P3^5;

uchar lcd_temperature[]="tem          C";        //温度数组
uchar lcd_humidity[] = "hum       %";        //湿度数组

//温度定义变量
uint shu;//测量到的温度的整数部分
uchar xiaoshu1;//小数第一位
uchar xiaoshu2;//小数第一位
bit  fg;        //温度正负标志         

//湿度定义变量
int getdata,temp;           //getdata-- adc0809 输出的数据,temp--转换为湿度的数据
void dsInit()
{//对于11.0592MHz时钟, unsigned int型的i, 作一个i++操作的时间大于?us
        ds = 0;
        delay1(100); //拉低约800us, 符合协议要求的480us以上
    ds = 1;    //产生一个上升沿, 进入等待应答状态
        delay1(1);
}
void dsWait()
{
    while(ds);
    while(~ds);  //检测到应答脉冲
        delay1(1);
}
//向DS18B20读取一位数据
//读一位, 让DS18B20一小周期低电平, 然后两小周期高电平,
//之后DS18B20则会输出持续一段时间的一位数据
bit readBit()
{
    uint i;
    bit b;
    ds = 0;
           i++; //延时约8us, 符合协议要求至少保持1us
    ds = 1;
    delay1(1); //延时约16us, 符合协议要求的至少延时15us以上
    b = ds;
    delay1(7);  //延时约64us, 符合读时隙不低于60us要求
    return b;
}
//读取一字节数据, 通过调用readBit()来实现
uchar readByte()
{
    uchar i;
    uchar j, dat;
    dat = 0;
    for(i=0; i<8; i++)
           {
        j = readBit();//最先读出的是最低位数据
        dat = (j << 7) | (dat >> 1);
    }
    return dat;       
}

//向DS18B20写入一字节数据
void writeByte(uchar dat)
{
        uchar j;
    uchar b;
    for(j = 0; j < 8; j++)
    {
                b = dat & 0x01;
        dat >>= 1;//写"1", 将DQ拉低15us后, 在15us~60us内将DQ拉高, 即完成写1
        if(b)
        {
                        ds = 0;
                        delay1(1);          // 符号要求15~60us内         
            ds = 1;  
                        delay1(7);          //符合写时隙不低于60us要求
        }
      else  //写"0", 将DQ拉低60us~120us
            ds = 0;
                        delay1(7);
            ds = 1;
                        delay1(1);
    }          
}
//向DS18B20发送温度转换命令
void sendChangeCmd()
{
        dsInit();    //初始化DS18B20, 无论什么命令, 首先都要发起初始化
    dsWait();   //等待DS18B20应答
    delay1(1);    //延时1ms, 因为DS18B20会拉低DQ 60~240us作为应答信号
    writeByte(0xcc); //写入跳过序列号命令字 Skip Rom
    writeByte(0x44); //写入温度转换命令字 Convert T
}
//向DS18B20发送读取数据命令
void sendReadCmd()
{
    dsInit();
    dsWait();
    delay1(1);
    writeByte(0xcc); //写入跳过序列号命令字 Skip Rom
    writeByte(0xbe); //写入读取数据令字 Read Scratchpad
}
//获取当前温度值并显示温度
void getTmpValue()
{
           uchar templ,temph,i;
        uchar tem;
        sendReadCmd();
        templ = readByte();  //读取低位温度   
        temph = readByte();   //读取高位温度           
        if(temph > 0x7f)      //最高位为1时温度是负
        {    //补码转换,取反加一
                 tem = ~((temph*256)|templ)+1;
                 templ = tem & 0x00ff;
                 temph = tem & 0xff00;
                 fg=0;      //读取温度为负时fg=0
    }
        else
                   fg=1;
        shu = templ/16+(temph&0x07)*16;      //整数部分
        xiaoshu1 = (templ&0x0f)*10/16; //小数第一位
        xiaoshu2 = (templ&0x0f)*100/16%10;//小数第二位

    if(fg==1)   //温度为正时显示的数据
    {   
                  lcd_temperature[6]=' ';       //输出十位数
        }
    else  //温度为负时显示的数据
    {   
                   lcd_temperature[6]='-';     
    }       //负号          

        lcd_temperature[7] = 0x30|(shu/10);//计数的十位显示
        lcd_temperature[8] = 0x30|(shu%10); //计数的个位显示
        lcd_temperature[9] = '.'; //计数的小数点显示
        lcd_temperature[10] = 0x30|xiaoshu1;//计数的小数点后一位显示
        lcd_temperature[11] = 0x30|xiaoshu2;//计数的小数点后二位显示
       
        lcd_wcmd(0x80);
        for(i=0; i<14; i++)//显示字母
        {               
                lcd_wdat(lcd_temperature[i]);
        }
   
}
void timer0_init()   //中断服务程序初始化
{
        TCON = 0x10;
        TMOD=0x01;
        TH0=(65536-20)/256;
        TL0=(65536-20)%256;
        EA=1;
        ET0=1;
        TR0=1;
}
void gethumidity()
{
        uchar i;
        OE=0; //刚开始禁止将转换结果输出
        ST=0;       
        ST=1;
        ST=0;          //启动AD转换开始
        while(EOC==0);   //等待转换结束
        OE=1;          //允许转换结果输出
        getdata=P2;    //将转换结果赋值给变量getdata
        OE=0;          //禁止转换结果输出

        temp=getdata*1.0/255*100;  //将得到的数据进行处理
        if(temp/100 == 0)
                lcd_humidity[6]=' ';  //取得百位数
        else       
                lcd_humidity[6]=(temp/100)|0x30;   //取得百位数

        lcd_humidity[7]=(temp/10%10)|0x30;   //取得十位数
        lcd_humidity[8]=(temp%10)|0x30;      //取得个位数

        lcd_wcmd(0x80+0x40);
        for(i=0; i<11; i++)//显示字母
        {               
                lcd_wdat(lcd_humidity[i]);
        }       
       
}
void timer0() interrupt 1   //给AD0809提供25KHZ的时钟脉冲
{

        TH0=(65536-20)/256;
        TL0=(65536-20)%256;
        CLK=~CLK;
}
//测试LCD忙状态  返回result
bit lcd_bz()
{
        bit result;
        rs = 0;
        rw = 1;
        eq = 1;
        _nop_();        _nop_();        _nop_();        _nop_();
        result = (bit)(P1&0x80);
        eq = 0;
        return result;
}
//写指令数据到LCD
void lcd_wcmd(uchar cmd)
{
        rs = 0;
        rw = 0;
        eq = 1;
        P1 = cmd;
        delay(1);
        eq = 0;
}
//写入显示数据到LCD
void lcd_wdat(uchar dat)
{
        while(lcd_bz());
        rs = 1;
        rw = 0;
        eq = 1;
        P1 = dat;
        delay(10);
        eq = 0;
}
//LCD初始化
void lcd_init()
{
        lcd_wcmd(0x38);//显示模式设置,5*7点阵,8位数据接口
        lcd_wcmd(0x0c);//显示开及光标设置不显示
        lcd_wcmd(0x06);//显示光标移动设置
        lcd_wcmd(0x01);//显示清屏
}
void main()
{       
        lcd_init();         //LCD1602初始化
        timer0_init();        //中断服务程序初始化  
        while(1)
        {       
                //启动温度转换
                EA = 0;                //总中断影响温度显示
              sendChangeCmd();
                   getTmpValue();
                EA = 1;
                //启动湿度转换
                gethumidity();
        }
}
帮忙keil运行这个程序看看啊,我找不到错误在哪,急死了,摆脱哪位高手了!!!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
2条回答
weixiao8776
1楼-- · 2019-07-16 10:53
怎么找不到你的delay1()子函数?还有程序中的void getTmpValue()需要调用lcd_wcmd(0x80),lcd_wcmd(0x80)在void getTmpValue()的下面,所以调用不成功。调用只能是下面的函数调用上面的函数,反过来是不成功的。
weixiao8776
2楼-- · 2019-07-16 12:12
怎么找不到你的delay1()子函数?还有程序中的void getTmpValue()需要调用lcd_wcmd(0x80),lcd_wcmd(0x80)在void getTmpValue()的下面,所以调用不成功。调用只能是下面的函数调用上面的函数,反过来是不成功的。

一周热门 更多>