89c51+ds18b20实现温度检测及设定
文档中有原理图及程序。亲测可行
数码管采用共阳数码管
共阳数码管结构图 数码管上对应的各段
例如:1的字形码为 0xf9;0为0xc0;
矩阵式键盘的优缺点:在按键多时,占用的I/O少,但程序编写复杂。
独立式键盘的优缺点:占用的I/O多,但程序编写简单。 本次设计为独立键盘(所选单片机I/O足够用)
程序(此程序只能做到左侧两个数码管显示设定温度,右侧两个数码管显示测量的温度,并没有实现温度的控制调节功能)
单片机源程序如下:
- #include //52系列头文件
- #include //特殊寄存器头文件
- #define uchar unsigned char
- #define uint unsigned int
- #include
-
- //--定义要使用的IO口--//
-
- #define GPIO_DIG P0 //段选
- #define GPIO_PLACE P2 //位选
- sbit DSPORT=P3^7;
- unsigned char code DIG_PLACE[8] = {
- 0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位选控制 查表的方法控制
- unsigned char code DIG_CODE[17] = {
- 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8 ,
- 0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
- //0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码
- unsigned char DisplayData[5];//用来存放要显示的8位数的值
- void Delay10ms(unsigned int c); //延时10ms
- void Key_Scan();
- void DigDisplay();
- uchar Ds18b20Init(); //初始化程序
- sbit key1=P3^4; //设定温度加
- sbit key2=P3^5; //设定温度减
- void Ds18b20WriteByte(uchar dat); //写一个字节
- uchar Ds18b20ReadByte(); //读一个字节
- void Ds18b20ChangTemp(); //转换温度
- void Ds18b20ReadTempCom(); //发送读取温度命令
- int Ds18b20ReadTemp(); //读取温度命令
- int sdtemp1=30;
- int wendu; //定义临时变量
- /********************主程序*****************************************8 */
- void main(void)
- {
- while (1)
- {
- Key_Scan();
- DigDisplay();
- DisplayData[0]=DIG_CODE[sdtemp1/10];
- DisplayData[1]=DIG_CODE[sdtemp1%10];
- wendu=Ds18b20ReadTemp();
- wendu=wendu>>4;
- DisplayData[2] = DIG_CODE[wendu%100/10];
- DisplayData[3] = DIG_CODE[wendu % 10];
-
-
-
- }
- }
-
- /***************按键扫描程序*******************************************/
- void Key_Scan()
- {
- //--检测按键1--//
- if (key1== 0) //检测按键K1是否按下
- {
- Delay10ms(1); //消除抖动
- if (key1== 0) //再次检测按键是否按下
- { //DigDisplay();
- sdtemp1=sdtemp1+1;
- if(sdtemp1>99) sdtemp1=30;
- // DigDisplay();
- while (!key1 ) //检测按键是否松开
- {//Delay10ms(20);
- DigDisplay();
-
- }
-
- }
- }
-
- if (key2== 0) //检测按键K1是否按下
- { DigDisplay();
- Delay10ms(1); //消除抖动
-
- if (key2== 0) //再次检测按键是否按下
- { DigDisplay();
- sdtemp1=sdtemp1-1;
- if(sdtemp1<15) sdtemp1=15;
-
- while (!key2 ) //检测按键是否松开
- { //Delay10ms(2);
- DigDisplay();
-
- }
- }
- }
- }
- /***************************************************
- 函数名 :Delay
- 函数功能 :延时
- 输入 :无
- 输出 :无
- ***************************************************/
- void Delay10ms(unsigned int c) //误差 0us
- {
- unsigned char a, b;
-
- //--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//
- for (;c>0;c--)
- {
- for (b=38;b>0;b--)
- {
- for (a=130;a>0;a--);
- }
-
- }
- }
- /*******************************************************************************
- * 函 数 名 : DigDisplay
- * 函数功能 : 使用数码管显示
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
-
- void DigDisplay()
- {
- unsigned char i;
- unsigned int j;
-
-
- for(i=0; i<4; i++)
- {
- GPIO_PLACE = DIG_PLACE[i]; //发送位选
- GPIO_DIG = DisplayData[i]; //发送段码
-
- j = 80; //扫描间隔时间设定
- while(j--);
- GPIO_DIG = 0xFF;//消隐
- }
-
- }
- /*******************************************************************************
- * 函 数 名 : Ds18b20Init
- * 函数功能 : 初始化
- * 输 入 : 无
- * 输 出 : 初始化成功返回1,失败返回0
- *******************************************************************************/
-
- uchar Ds18b20Init()
- {
- uchar i;
- DSPORT = 0; //将总线拉低480us~960us
- i = 70;
- while(i--);//延时642us
- DSPORT = 1; //然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低
- i = 0;
- while(DSPORT) //等待DS18B20拉低总线
- {
- DigDisplay();
- // Delay1ms(1);
- i++;
- if(i>5)//等待>5MS
- {
- return 0;//初始化失败
- }
-
- }
- return 1;//初始化成功
- }
- /*******************************************************************************
- * 函 数 名 : Ds18b20WriteByte
- * 函数功能 : 向18B20写入一个字节
- * 输 入 : com
- * 输 出 : 无
- *******************************************************************************/
-
- void Ds18b20WriteByte(uchar dat)
- {
- uint i, j;
-
- for(j=0; j<8; j++)
- {
- DSPORT = 0; //每写入一位数据之前先把总线拉低1us
- i++;
- DSPORT = dat & 0x01; //然后写入一个数据,从最低位开始
- i=6;
- while(i--); //延时68us,持续时间最少60us
- DSPORT = 1; //然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值
- dat >>= 1;
- }
- }
- /*******************************************************************************
- * 函 数 名 : Ds18b20ReadByte
- * 函数功能 : 读取一个字节
- * 输 入 : com
- * 输 出 : 无
- *******************************************************************************/
-
-
- uchar Ds18b20ReadByte()
- {
- uchar byte, bi;
- uint i, j;
- for(j=8; j>0; j--)
- {
- DSPORT = 0;//先将总线拉低1us
- i++;
- DSPORT = 1;//然后释放总线
- i++;
- i++;//延时6us等待数据稳定
- bi = DSPORT; //读取数据,从最低位开始读取
- /*将byte右移移一位,然后与上左移7位后的bi,注意移动之后移掉那位补0。*/
- byte = (byte >> 1) | (bi << 7);
- i = 4; //读取完之后等待48us再接着读取下一个数
- while(i--);
- }
- return byte;
- }
- /*******************************************************************************
- * 函 数 名 : Ds18b20ChangTemp
- * 函数功能 : 让18b20开始转换温度
- * 输 入 : com
- * 输 出 : 无
- *******************************************************************************/
-
- void Ds18b20ChangTemp()
- {
- Ds18b20Init();
- DigDisplay();// Delay1ms(1);
- Ds18b20WriteByte(0xcc); //跳过ROM操作命令
- Ds18b20WriteByte(0x44); //温度转换命令
- // Delay1ms(100); //等待转换成功,而如果你是一直刷着的话,就不用这个延时了
-
- }
- /*******************************************************************************
- * 函 数 名 : Ds18b20ReadTempCom
- * 函数功能 : 发送读取温度命令
- * 输 入 : com
- * 输 出 : 无
- *******************************************************************************/
-
- void Ds18b20ReadTempCom()
- {
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
所有文档.doc
(115.5 KB, 下载次数: 33)
|