搜索
bottom↓
回复: 19

很高兴,终于调出来了

[复制链接]

出0入0汤圆

发表于 2011-10-22 22:37:17 | 显示全部楼层 |阅读模式
本人是个单片机菜鸟,什么都不会,这是我改的一个程序,与大家分享!!!!;注意是用ds18b20设计的温度报警程序;写的有点撇!!!!!!!
请大家别见笑,

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2011-10-22 22:41:14 | 显示全部楼层
程序源码请贴出来啊

出0入0汤圆

 楼主| 发表于 2011-10-22 22:42:21 | 显示全部楼层
我刚才上传了呀怎么没了

出0入0汤圆

 楼主| 发表于 2011-10-22 22:42:33 | 显示全部楼层
我刚才上传了呀怎么没了

出0入0汤圆

 楼主| 发表于 2011-10-22 22:43:18 | 显示全部楼层
再传一遍

出0入0汤圆

 楼主| 发表于 2011-10-22 22:45:30 | 显示全部楼层
温度传感器ourdev_687582IYAYV9.rar(文件大小:44K) (原文件名:temperture detection 2.rar)

出0入0汤圆

 楼主| 发表于 2011-10-22 22:45:58 | 显示全部楼层
还请高手指点

出0入0汤圆

发表于 2011-10-24 09:58:19 | 显示全部楼层
没有层次感 看起了非常吃力 你重新编辑下 不然估计没人会看

出0入0汤圆

发表于 2011-10-24 10:14:50 | 显示全部楼层
看看我的 注意层次感 这样看起来是不是很明了  
我也是菜鸟 才学几个月 高手是不屑于发这样的帖子的
//**********************************************************************************
//初始化DS18B20
//让DS18B20一段相对长时间低电平, 然后一段相对非常短时间高电平, 即可启动
void dsreset(void)        
{  //对于11.0592MHz时钟, unsigned int型的i, 作一个i++操作的时间大于?us
    uint i;
    ds=0;
    i=103;    //拉低约800us, 符合协议要求的480us以上
    while(i>0)i--;
    ds=1;    //产生一个上升沿, 进入等待应答状态
    i=4;
    while(i>0)i--;
}
//**********************************************************************************

//**********************************************************************************
//向DS18B20读取一位数据
//读一位, 让DS18B20一小周期低电平, 然后两小周期高电平,
//之后DS18B20则会输出持续一段时间的一位数据
bit tempreadbit(void)
{  
    uint i;
    bit dat;
    ds=0;
    i++;      //i++起延迟作用  延时约8us, 符合协议要求至少保持1us
    ds=1;
    i++;i++;  //延时约16us, 符合协议要求的至少延时15us以上
    dat=ds;
    i=8;
    while(i>0)i--; //延时约64us, 符合读时隙不低于60us要求
    return(dat);
}
//**********************************************************************************

//**********************************************************************************
//读取一字节数据, 通过调用tempreadbit()来实现
uchar tempread(void)      
{
    uchar i,j,dat;
    dat=0;
    for(i=1;i<=8;i++)
    {
        j=tempreadbit();
        dat=(j<<7)|(dat>>1);  //读出的数据最低位在最前面,这样刚好一个字节在dat里   
    }
    return(dat);
}
//**********************************************************************************

//**********************************************************************************
//向DS18B20写入一字节数据
void tempwritebyte(uchar dat)   
{
    uint  i;
    uchar j;
    bit testb;
    for(j=1;j<=8;j++)
    {
        testb=dat&0x01;
        dat=dat>>1;
        if(testb)    //写"1", 将ds拉低15us后, 在15us~60us内将ds拉高, 即完成写1
        {
            ds=0;
            i++;i++;  //拉低约16us, 符号要求15~60us内
            ds=1;
            i=8;while(i>0)i--;  //延时约64us, 符合写时隙不低于60us要求
        }
        else      //写"0", 将ds拉低60us~120us
        {
            ds=0;  
            i=8;while(i>0)i--;  //拉低约64us, 符号要求      
            ds=1;
            i++;i++; //整个写0时隙过程已经超过60us, 这里就不用像写1那样, 再延时64us了   
        }   
    }
}
//**********************************************************************************

//**********************************************************************************
//向DS18B20发送温度转换命令
void tempchange(void)   
{
    dsreset();   //初始化DS18B20, 无论什么命令, 首先都要发起初始化
    delay(1);    //延时1ms, 因为DS18B20会拉低ds 60~240us作为应答信号
    tempwritebyte(0xcc);   //写跳过读ROM指令
    tempwritebyte(0x44);   //写温度转换指令
}
//**********************************************************************************

//**********************************************************************************
//向DS18B20发送读取数据命令  获取当前温度值
uint tmp()  
{
    float tt;
    uchar low,high;
    dsreset();
    delay(1);
    tempwritebyte(0xcc); //写入跳过序列号命令字 Skip Rom
    tempwritebyte(0xbe); //写入读取数据令字 Read Scratchpad
    //连续读取两个字节数据
    low =tempread();   //读低8位
    high=tempread();   //读高8位
    temp=high;   //高8位赋予temp
    temp<<=8;    //将高低两个字节合成一个整形变量 temp为16位 高8位左移8位 低8位补0
    temp=temp|low;  //高低8位相或=temp为16位=高8位+低8位
    tt=temp*0.0625;  //DS18B20的默认分辨率12位, 精确度为0.0625度, 即读回数据的最低位代表0.0625度   
// temp = tt * 100 + (temp > 0 ? 0.5 : -0.5); //大于0加0.5, 小于0减0.5  
    temp=tt*100;  //将它放大100倍, 使显示时可显示小数点后两位(t=11.0625,计算得temp = 1106, 即11.06 度)
    return temp; //temp是整型
}
//**********************************************************************************

出0入0汤圆

发表于 2011-10-24 15:13:15 | 显示全部楼层
8楼已经学会了将程序模块化,不错的小伙子。

出0入0汤圆

 楼主| 发表于 2011-10-26 12:52:24 | 显示全部楼层
多谢指点

出0入0汤圆

 楼主| 发表于 2011-10-26 12:54:12 | 显示全部楼层
我们这学期刚开课,我什么都不会!!!!!!!,以后多多指教

出0入0汤圆

 楼主| 发表于 2011-10-29 23:45:49 | 显示全部楼层
出来冒个泡

出0入0汤圆

 楼主| 发表于 2011-10-29 23:47:30 | 显示全部楼层
各位大哥谁有关于温度传感器的程序

出0入0汤圆

发表于 2011-10-29 23:51:59 | 显示全部楼层
楼主不错啊

出0入0汤圆

发表于 2011-11-1 01:37:28 | 显示全部楼层
回复【13楼】liudaolunhui 晓鹏
           各位大哥谁有关于温度传感器的程序
-----------------------------------------------------------------------

送给你一个我修改的程序,这个程序花了我大量精力和很多心思去注释的,希望大家共同进步!

/******************************************************
原程序从中国电子开发网WWW.OURDEV.CN中某高手修改而来,经过本人改动,已经完全可以正常显示温度
日期:2011.10.07
版本号:20111007.0349

P2.0-个位 //位选
P2.1-十位 //位选
P2.2-百位 //位选
P2.3-千位 //位选
P0.0-->P0.7:  a-->dp //段选a-g,dp
P1.2-温感器DS18B20的信号端
*********************************************************/
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char

sbit DQ=P1^2; //定义DS18B20端口DQ
sbit DIN=P0^7; //小数点
sbit gewei=P2^0;   //个位位选
sbit shiwei=P2^1;  //十位位选
sbit baiwei=P2^2;  //百位位选
sbit qianwei=P2^3; //千位位选

unsigned char code table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff,0xfe,0xf7,0xbf};//共阳极数码管段码,为0-9,空白和上标-,下标_,中间-
unsigned char code ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09}; //专门给小数查表用的,原理请见下面部分说明。
/*
本人注:DS18B20的小数位数是由4位二进制数表示,单位为0.0625度,这样,0-15表示了从,0-15*0.0625度,再根据需要(四舍五入)保留1位小数,就成那样了。
如:
0000(0x00)就是0*0.0625=0.0度,在ditab[16]中就是第1个位置0x00;
0001(0x01)就是1*0.0625=0.1度,在ditab[16]中就是第2个位置0x01(四舍五入保留1位小数);
0010(0x02)就是2*0.0625=0.1度,在ditab[16]中就是第3个位置0x01(四舍五入保留1位小数);
0011(0x03)就是3*0.0625=0.2度,在ditab[16]中就是第4个位置0x02(四舍五入保留1位小数);
0100(0x04)就是4*0.0625=0.3度,在ditab[16]中就是第5个位置0x03(四舍五入保留1位小数);
0101(0x05)就是5*0.0625=0.3度,在ditab[16]中就是第6个位置0x03(四舍五入保留1位小数);
0110(0x06)就是6*0.0625=0.4度,在ditab[16]中就是第7个位置0x04(四舍五入保留1位小数);
0111(0x07)就是7*0.0625=0.4度,在ditab[16]中就是第8个位置0x04(四舍五入保留1位小数);
1000(0x08)就是8*0.0625=0.5度,在ditab[16]中就是第9个位置0x05(四舍五入保留1位小数);
1001(0x09)就是9*0.0625=0.6度,在ditab[16]中就是第10个位置0x06(四舍五入保留1位小数);
1010(0x0a)就是10*0.0625=0.6度,在ditab[16]中就是第11个位置0x06(四舍五入保留1位小数);
1011(0x0b)就是11*0.0625=0.7度,在ditab[16]中就是第12个位置0x07(四舍五入保留1位小数);
1100(0x0c)就是12*0.0625=0.8度,在ditab[16]中就是第13个位置0x08(四舍五入保留1位小数);
1101(0x0d)就是13*0.0625=0.8度,在ditab[16]中就是第14个位置0x08(四舍五入保留1位小数);
1110(0x0e)就是14*0.0625=0.9度,在ditab[16]中就是第15个位置0x09(四舍五入保留1位小数);
1111(0x0f)就是15*0.0625=0.9度,在ditab[16]中就是第16个位置0x09(四舍五入保留1位小数);
*/

unsigned char high_byte=0,low_byte=0;//low_byte=温度值低8位;high_byte=温度值高8位.
unsigned char presence; //DS18B20初始化成功标志:=0表示成功,=1表示失败。
unsigned char zhengshu=0; //最终的温度值(整数部分),小数部分为:xiaoshu(在另一个函数里定义)

void Temp_Display(uchar a,uchar b,uchar c,uchar d); //温度显示函数,(用于18B20温感器)
void Disp_Temperature(); //计算、转换 温度函数,(用于18B20温感器)

/**********************************************************/
//DS18B20对时间要求很严,但只能长不能短
void delay_18B20(unsigned int i)//延时函数,(用于18B20温感器)
{
   while(--i);
}

/**********************************************************/
void LED_OFF()
{
        gewei=1; //个位灯灭
        shiwei=1; //十位灯灭
        baiwei=1; //百位灯灭
        qianwei=1; //千位灯灭
//        P2|=0x0f; //关闭所有显示 //0x0f=00001111,P2的其它位保持原有状态不变
}
void gewei_on()
{
        gewei=0; //个位灯亮
//        P2|=0x0e; //0x0e=00001110,先关闭个位、十位、百位,P2的其它位保持原有状态不变
//        P2&=0xfe; //0xfe=11111110,只显示小数位,P2的其它位保持原有状态不变
}
void shiwei_on()
{
        shiwei=0; //十位灯亮
//        P2|=0x0d; //0x0d=00001101,先关闭小数、十位、百位,P2的其它位保持原有状态不变
//        P2&=0xfd; //0xfd=11111101,只显示个位,P2的其它位保持原有状态不变
}
void baiwei_on()
{
        baiwei=0; //百位灯亮
//        P2|=0x0b; //0x0b=00001011,先关闭小数、个位、百位,P2的其它位保持原有状态不变
//        P2&=0xfb; //0xfb=11111011,只显示十位,P2的其它位保持原有状态不变
}
void qianwei_on()
{
        qianwei=0; //千位灯亮
//        P2|=0x07; //0x07=00000111,先关闭小数、个位、十位,P2的其它位保持原有状态不变
//        P2&=0xf7; //0xf7=11110111,只显示百位,P2的其它位保持原有状态不变
}


/*****ds18b20初始化函数*********************/
unsigned char Init_DS18B20(void)//初始化DS18B20,(用于18B20温感器)
{
        DQ=1;                                        //DQ复位
        delay_18B20(8);        //稍做延时
        DQ=0;                                        //单片机将DQ拉低
        delay_18B20(80);        //精确延时大于480us
        DQ=1;                                        //拉高总线
        delay_18B20(14);        //别的程序括号内的值为:8
        presence=DQ;                //稍做延时后,如果presence=0则初始化成功,presence=1则初始化失败
        delay_18B20(20);        //注意:初始化不成功,问题有可能出现在此行上的延时数值。 //别的程序括号内的值为:100

//        DQ = 1; //别的程序会多出本条语句

        return(presence); //返回信号,presence=0则初始化成功,presence=1则初始化失败
}

/*****ds18b20读一个字节*********************/
unsigned char ReadOneChar(void)//读一个字节,(用于18B20温感器)
{
        unsigned char i=0;
        unsigned char dat=0;

        for(i=8;i>0;i--)
        {
                _nop_(); //保证两次读操作时间间隔1us以上
                DQ=0; //给脉冲信号
                _nop_(); //保证主机拉低总线1us以上
                dat>>=1;
                DQ=1; //给脉冲信号
               
                if(DQ) //主机对总线采样的数 判断//如果DQ=1才执行下面的语句,如果=0不执行,并返回上面执行dat>>=1;这样就相当于把0读出来了。
                        dat|=0x80; //0x80=10000000
                delay_18B20(4); //等待读操作结束
        }
        return(dat);
}

/*****ds18b20写一个字节*********************/
void WriteOneChar(unsigned char dat)//写一个字节,(用于18B20温感器)
{
        unsigned char i=0;

        for(i=8;i>0;i--)
        {
                _nop_(); //保证两次写操作时间间隔1us以上
                DQ=0;
                _nop_(); //保证主机拉低总线1us以上
                DQ=dat&0x01; //假设dat=0x9b,即10011011,与0x01相与后结果为0x01,即00000001,而DQ电平只有一位取最低位为1,同理,如果最低位为0则取0。
                delay_18B20(5); //写时间间隔必须最少持续60us
                DQ=1;
                dat>>=1; //0x9b右移一位为0x4d,即01001101。照此循环8次,把dat的值从低位开始依次传送给18B20。
        }
}

/*****读取ds18b20当前温度*********************/
void Read_Temperature()//读取温度,(用于18B20温感器)
{

/*
        Init_DS18B20();
        WriteOneChar(0xCC); //跳过读序号列号的操作 //0xCC=11001100
        WriteOneChar(0x4E); //写入"写暂存器"命令,修改TH和TL和分辨率配置寄存器 //0x4E=01001110
//先写TH,再写TL,最后写配置寄存器
        WriteOneChar(0x6e); //写入想设定的温度报警上限 //0X6e=01101110
        WriteOneChar(0x00); //写入想设定的温度报警下限
        WriteOneChar(0x3f); //写配置寄存器,格式为0 R1 R0 1,1 1 1 1 //0X3f=00111111
//R1R0=00分辨率为9位,R1R0=11分辨率为12位
        delay_18B20(80); //经本人测试,本行延时好像无用,可省略不写
*/
//以上注释可省略不写,因为不写出来,DS18B20会采用默认值为12位分辨率。写出来就多此一举,还浪费时间。

        Init_DS18B20(); //初始化ds1820
        WriteOneChar(0xCC); //跳过读序列号的操作 //0xCC=11001100
        WriteOneChar(0x44); //启动温度转换
        delay_18B20(80); //经本人测试,本行延时好像无用,可省略不写

        Init_DS18B20(); //初始化ds1820
        WriteOneChar(0xCC); //跳过读序列号的操作 //0xCC=11001100
        WriteOneChar(0xBE); //读取温度寄存器(共可读9个寄存器),前两个就是温度
        delay_18B20(80); //经本人测试,本行延时好像无用,可省略不写

        low_byte=ReadOneChar(); //第1次读取到的数据是温度值低8位
        high_byte=ReadOneChar(); //第2次读取到的数据是读取温度值高8位
}


/*****温度显示函数*********************/
void Temp_Display(uchar a,uchar b,uchar c,uchar d)//显示温度,(用于18B20温感器)
{

        LED_OFF();
        P0=table[a]; //显示小数位
        gewei_on(); //个位灯亮
        delay_18B20(300);

        LED_OFF();
        P0=table; //显示个位
        DIN=0; //小数点在第二位显示
        shiwei_on(); //十位灯亮
        delay_18B20(300);
       
        LED_OFF();
        P0=table[c]; //显示十位
        baiwei_on(); //百位灯亮
        delay_18B20(300);

        LED_OFF();
        P0=table[d]; //显示百位
        qianwei_on(); //千位灯亮
        delay_18B20(300);

        LED_OFF();
}

/*****计算、转换 温度*********************///这是本人参考别人改进后加上的
void Disp_Temperature() //计算、转换 温度函数,(用于18B20温感器)
{
        unsigned char xiaoshu=0; //用来存储小数数值的变量(非位选变量)
        unsigned char ge=0,shi=0,bai=0; //位选变量

        zhengshu=(high_byte<<4)+(low_byte>>4); //把温度高8位和低8位的整数部分合成一个完整的整数,小数部分去掉。
//经过本人测试,假如现在温度是25.0625度(0000 0001 1001 0001),高8位high_byte=0000 0001,低8位low_byte=1001 0001。
//(接上句)那么high_byte左移4位变为:0001 0000,low_byte右移4位变为:0000 1001。这两者相加(即相或)=0001 1001,转换为
//(接上句)十进制就是25度。至于小数部分,另外处理,本节主要讲解温度值是如何转换来的。

        xiaoshu=ditab[low_byte&0x0f];  //去掉整数部分,保留小数;并查表得小数位的值

        ge=zhengshu%10;
        shi=zhengshu%100/10;
        bai=zhengshu/100;

        if(bai==0) //如果百位,或百位和十位均为0,则不显示,达到消隐的目的
        {
                bai=10;
                if(shi==0)
                        shi=10;
        }
        Temp_Display(xiaoshu,ge,shi,bai);
}


/*********************************************************/
void main(void)
{
        while(1)
        {
                Read_Temperature(); //读取ds18b20当前温度

                if(presence==1) //如果初始化失败,则执行下面的语句:
                        LED_OFF(); //关闭所有显示
                else
                        Disp_Temperature(); //显示温度
        }
}

出0入0汤圆

发表于 2011-11-2 09:48:57 | 显示全部楼层
不错不错,领教了~

出0入0汤圆

发表于 2011-11-2 09:51:44 | 显示全部楼层
继续加油!

出0入0汤圆

 楼主| 发表于 2012-7-5 21:54:43 | 显示全部楼层
多谢各位前辈!!!很久没来逛了

出0入0汤圆

发表于 2012-7-8 20:47:13 | 显示全部楼层
很不错,收下学习了
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-27 00:14

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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