|
- /*一、主要功能:
- (1)1路温度采集电路.
- (2)采集测温范围为-55~+120 ℃.
- (3)温度精度在0.1 ℃;误差±0.2℃以内.
- (4)显示模块,采用4个LED数码管显示.
- (5)按键3个,设置、加、减.
- (6)报警设置1-99度.低于下限报警,高于上限报警。
- */
- #include<reg51.h>
- #include<intrins.h>
- #define uint unsigned int
- #define uchar unsigned char
- //-----------------------
- sbit S1=P1^0; //设置 上下限
- sbit S2=P1^1; //加
- sbit S3=P1^2; //减
- sbit SEG1=P2^0; //段码位1
- sbit SEG2=P2^2; //段码位2
- sbit SEG3=P2^4; //段码位3
- sbit SEG4=P2^6; //段码位4
- sbit DQ1=P1^7; //传感器1
- sbit LED1=P3^0; //报警显示灯
- sbit BUZ=P3^1; //蜂鸣器
- uchar DQ1_SET[2]; //DQ1上下限设置 DQ1_SET[0] 下限 DQ1_SET[1] 上限;
- uchar Temp; //温度报警
- uchar count; //蜂鸣器定时用
- uchar mode; //mode=1正常显示 mode=2 设置下限模式 mode=3设置上限
- //////////////////////////////DS18B20////////////////////////////////////////////////
- uchar ng; //负号标志
- uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x58,0x00};//共阴数码码表
- /* 0 1 2 3 4 5 6 7 8 9 C 无*/
- uchar code df_Table[]=
- {
- 0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9
- }; //温度小数位对照表
- uchar CurrentT = 0; //当前读取的温度整数部分
- uchar Temp_Value[]={0x00,0x00}; //从DS18B20读取的温度值
- uchar Display_Digit[]={0,0,0,0};//待显示的各温度数位
- bit DS18B20_IS_OK = 1; //传感器正常
- ////////////////////////////////DS18B20///////////////////////////////////////////////
- //************************************************************************/
- // 函数: LCD_Delay()
- // 描述: 延时t ms函数
- // 参数: t
- // 返回: 无
- // 备注: 12MHZ t=1延时时间约1ms
- //************************************************************************/
- void Delay_ms(unsigned int t)
- {
- unsigned int i,j;
- for(i=0;i<t;i++)
- for(j=0;j<120;j++)
- ;
- }
- //************************************************************************/
- // 函数: LCD_Delay()
- // 描述: 延时x us函数
- // 参数: t
- // 返回: 无
- // 备注: 12MHZ 延时时间约us
- //************************************************************************/
- void Delay(uint x)
- {
- while(--x);
- }
- //************************************************************************/
- // 函数: Init_DS18B20()
- // 描述: 初始化DS18B20
- // 参数: t
- // 返回: 无
- // 备注: 12MHZ
- //************************************************************************/
- //初始化DS18B20
- /*DS18B20的复位脉冲 主机通过拉低单总线至少480us以产生复位脉冲
- 然后主机释放单总线并进入接收模式 此时单总线电平被拉高
- DS18B20检测到上升沿后 延时15~60us,拉低总线60~240us产生应答脉冲 */
- uchar Init_DS18B20(void)
- {
- uchar status;
- DQ1 = 1; //DS18B20置高电平
- Delay(8); //延时
- DQ1 = 0; //DS18B20置低电平
- Delay(90); //延时480us以上
- DQ1 = 1; //DS18B20置高电平
- Delay(8); //延时
- status = DQ1;//读状态
- Delay(100); //延时
- DQ1 = 1; //DS18B20置高电平
- return status;//返回状态
- }
- //************************************************************************/
- // 函数: Init_DS18B20()
- // 描述: 读一个字节
- // 参数: t
- // 返回: 无
- // 备注: 12MHZ
- //************************************************************************/
- /*写时隙 主机在写1时隙向DS18B20写入1,在写0时隙向DS18B20写入0
- 所有写时隙至少需要60us,且在两次写时隙之间至少需要1us的恢复时间
- 两种写时隙均以主机拉低总线开始
- 产生写1时隙:主机拉低总线后,必须在15us内释放总线,由上拉电阻拉回至高电平
- 产生写0时隙:主机拉低总线后,必须整个时隙保持低电平 */
- uchar ReadOneByte()
- {
- uchar i,dat=0;
- DQ1 = 1;//DS18B20置高电平
- _nop_();//延时
- for(i=0;i<8;i++)
- {
- DQ1 = 0;//DS18B20置低电平
- dat >>= 1;//右移数据
- DQ1 = 1;//DS18B20置高电平
- _nop_();//延时
- _nop_();//延时
- if(DQ1)
- dat |= 0X80;
- Delay(30);//延时
- DQ1 = 1;//DS18B20置高电平
- }
- return (dat);
- }
- //************************************************************************/
- // 函数: WriteOneByte(uchar dat)
- // 描述: 写一个字节
- // 参数: t
- // 返回: 无
- // 备注: 12MHZ
- //************************************************************************/
- /*所有读时隙至少60us 且两次独立的读时隙之间至少需要1us的恢复时间
- 每次读时隙由主机发起,拉低总线至少1us。
- 若传1,则保持总线高电平;若发送0,则拉低总线
- 传0时DS18B20在该时隙结束时释放总线,再拉回高电平状态,主机必须在读时隙开始后的15us内释放总线,并保持采样总线状态 */
- void WriteOneByte(uchar dat)
- {
- uchar i;
- for(i=0;i<8;i++)
- { DQ1 = 0; //DS18B20置低电平
- DQ1 = dat& 0x01;
- Delay(5); //延时
- DQ1 = 1; //DS18B20置高电平
- dat >>= 1; //右移数据
- }
- }
- //************************************************************************/
- // 函数: Read_Temperature()
- // 描述: 读温度值
- // 参数: t
- // 返回: 无
- // 备注: 12MHZ
- //************************************************************************/
- void Read_Temperature()
- { EA=0; //关中断
- if(Init_DS18B20()==1)
- DS18B20_IS_OK=0;
- else
- {
- WriteOneByte(0xcc); //跳过序列号
- WriteOneByte(0x44); //启动温度转换
- Init_DS18B20();
- WriteOneByte(0xcc);//跳过序列号
- WriteOneByte(0xbe);//读取温度寄存器
- Temp_Value[0] = ReadOneByte(); //温度低8位
- Temp_Value[1] = ReadOneByte();//温度高8位
- DS18B20_IS_OK=1;
- }
- EA=1; // 开中断
- }
- //************************************************************************/
- // 函数: Display_Temperature()
- // 描述: 处理温度值
- // 参数: t
- // 返回: 无
- // 备注: 12MHZ
- //************************************************************************/
- void Display_Temperature()
- {
- uchar t = 150; //,延时
- ng = 0; //与负值标志
- if((Temp_Value[1]&0xf8)==0xf8) //温度为负?
- {
- Temp_Value[1] = ~Temp_Value[1];
- Temp_Value[0] = ~Temp_Value[0]+1;
- if(Temp_Value[0]==0x00)
- Temp_Value[1]++;
- ng = 1; //负温度标志
- }
- else{ng = 0;}
- Display_Digit[0] = df_Table[Temp_Value[0]&0x0f]; //查表得温度小数部分
- CurrentT = ((Temp_Value[0]&0xf0)>>4) | ((Temp_Value[1]&0x07)<<4); //温度整数部分
- Display_Digit[3] = CurrentT/100; //百
- Display_Digit[2] = CurrentT%100/10; //十
- Display_Digit[1] = CurrentT%10; //个
- Temp=CurrentT ; //报警温度
- if(ng == 1){Temp=0;}//当温度为负时,报警判断温度寄存器为0
- }
- //************************************************************************/
- // 函数: DIS_SEG(void)
- // 描述: 在LED上显示数据
- // 参数: t
- // 返回: 无
- // 备注: 12MHZ
- //************************************************************************/
- void DIS_SEG(void)
- {
- if(ng==1){P0=0x40;}else{P0=tab[Display_Digit[3]];} // 数码管显示负数 或正的百位
- SEG1=0; //片选数码管
- Delay_ms(3); //延时2ms
- SEG1=1; //关闭数码管
- P0=tab[Display_Digit[2]]; //温度十位
- SEG2=0; //片选数码管
- Delay_ms(3); //延时2ms
- SEG2=1; //关闭数码管
- P0=(tab[Display_Digit[1]]+0x80); //温度个位和小数点
- SEG3=0; //片选数码管
- Delay_ms(3); //延时2ms
- SEG3=1; //关闭数码管
- P0=tab[Display_Digit[0]]; //小数位
- SEG4=0; //片选数码管
- Delay_ms(3); //延时2ms
- SEG4=1; //关闭数码管
- }
- //************************************************************************/
- // 函数: DIS_SET_SEG(void)
- // 描述: 在LED上显示数据
- // 参数: t
- // 返回: 无
- // 备注: 12MHZ
- //************************************************************************/
- void DIS_SET_SEG(void)
- {
- P0=tab[Display_Digit[3]];// 数码管显示负数 或正的百位
- SEG1=0; //片选数码管
- Delay_ms(3); //延时2ms
- SEG1=1; //关闭数码管
- P0=tab[Display_Digit[2]];//温度十位
- SEG2=0; //片选数码管
- Delay_ms(3); //延时2ms
- SEG2=1; //关闭数码管
- P0=tab[Display_Digit[1]];//温度个位
- SEG3=0; //片选数码管
- Delay_ms(3); //延时2ms
- SEG3=1; //关闭数码管
- P0=tab[Display_Digit[0]];//小数位
- SEG4=0; //片选数码管
- Delay_ms(3); //延时2ms
- SEG4=1; //关闭数码管
- }
- //************************************************************************/
- // 函数: DIS_UP(void)
- // 描述: 下限设置显示
- // 参数: t
- // 返回: 无
- // 备注: 12MHZ
- //************************************************************************/
- void DIS_UP(void)
- {
- Display_Digit[3]=DQ1_SET[0]%100/10; //处理显示温度
- Display_Digit[2]=DQ1_SET[0]%10;
- Display_Digit[1] =11; //显示空白
- Display_Digit[0] =11; //显示空白
- }
- //************************************************************************/
- // 函数: DIS_DOWN(void)
- // 描述: 上限设置显示
- // 参数: t
- // 返回: 无
- // 备注: 12MHZ
- //************************************************************************/
- void DIS_DOWN(void)
- {
- Display_Digit[3] = 11; //显示空白
- Display_Digit[2] = 11; //显示空白
- Display_Digit[1]=DQ1_SET[1]%100/10; //处理显示温度
- Display_Digit[0]=DQ1_SET[1]%10;
- }
- //----------------------------键盘扫描-------------------------------------------
- //************************************************************************/
- // 函数: void S2_ADD(void)
- // 描述: 加按键操作函数
- // 参数: t
- // 返回: 无
- // 备注: 12MHZ
- //************************************************************************/
- void S2_ADD(void)
- { if(mode==2) //下限模式
- {
- DQ1_SET[0]++; if(DQ1_SET[0]>99){DQ1_SET[0]=99;} //加下限 和限值下限最大值
- }
- if(mode==3)//上限模式
- {
- DQ1_SET[1]++; if(DQ1_SET[1]>99){DQ1_SET[1]=99;} //加上限 和限值下限最大值
- }
- }
- //************************************************************************/
- // 函数: S3_SUB(void)
- // 描述: 减按键操作
- // 参数: t
- // 返回: 无
- // 备注: 12MHZ
- //************************************************************************/
- void S3_SUB(void)
- { if(mode==2) //下限模式
- {
- DQ1_SET[0]--; if(DQ1_SET[0]<1){DQ1_SET[0]=1;} //加下限 和限值下限最大值
- }
- if(mode==3)//上限模式
- {
- DQ1_SET[1]--; if(DQ1_SET[1]<1){DQ1_SET[1]=1;} //加上限 和限值下限最大值
- }
- }
- //************************************************************************/
- // 函数: KEY_SCAN(void)
- // 描述: 键盘扫描
- // 参数: t
- // 返回: 无
- // 备注: 12MHZ
- //************************************************************************/
- void KEY_SCAN(void)
- { if(S1==0)
- {
- Delay_ms(10); //延时去抖动
- mode++;
- if(mode>3){mode=1;} //在1 2 3中切换
- while(!S1){;} //等待按键释放
- }
- if(S2==0)
- {
- Delay_ms(10); //延时去抖动
- S2_ADD();
- while(!S2){;} //等待按键释放
- }
- if(S3==0)
- {
- Delay_ms(10); //延时去抖动
- S3_SUB();
- while(!S3){;} //等待按键释放
- }
- // 通道切换
- }
- //----------------------------键盘扫描-------------------------------------------
- //************************************************************************/
- // 函数: init(void)
- // 描述: 初始化定时器蜂鸣器报警用
- // 参数: t
- // 返回: 无
- // 备注: 12MHZ
- //************************************************************************/
- void init(void) //定时器初始化
- {
- TMOD=0x01;
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- EA=1; //开中断
- ET0=1; //
- TR0=0; //
- BUZ=1; //关蜂鸣器
- }
- //************************************************************************/
- // 函数: main(void)
- // 描述: 主程序
- // 参数: t
- // 返回: 无
- // 备注:
- //************************************************************************/
- void main(void)
- { uchar i;
- //--------超温初始---------------
- DQ1_SET[0]=10; //DQ1下限10
- DQ1_SET[1]=90; //DQ1上限90
- //-----------------------
- init(); //初始化蜂鸣器
-
- Read_Temperature(); //初始化DQ1
- Delay_ms(1000); //延时1s
- Read_Temperature(); //读温度
- //------------------------------------
- Read_Temperature(); //读温度
- if(DS18B20_IS_OK)
- Display_Temperature(); //显示温度处理
- //------------------------------------
- mode=1; //mode=1 正常模式
- while(1)
- { if(mode==1){//模式1
- //--------------键盘扫描-------------------------
- KEY_SCAN();
- //------------在SEG上显示温度--------------------
- DIS_SEG();
- //--------------------温度-----------------------
- i++;
- if(i>88) //避免频繁采集温度
- { Read_Temperature(); //读温度
- if(DS18B20_IS_OK){Display_Temperature();} //温度数据处理
- i=0;
- }
- //-----------------------超温报警-----------------------------
- while(1)
- {
- if(Temp<DQ1_SET[0]){LED1=0;TR0=1;break;}else{ if(Temp>DQ1_SET[1]){LED1=0;TR0=1;break;}else{LED1=1;BUZ=1;TR0=0;}}
- break; //下限报警 //上限报警
- }
-
- //-----------------------超温报警-----------------------------
- }
- if(mode==2) //下限设置
- {
- KEY_SCAN(); //键盘扫描
- DIS_UP(); //显示数据处理
- DIS_SET_SEG(); //设置模式下SEG显示方式
- }
- if(mode==3) //上限设置
- {
- KEY_SCAN(); //键盘扫描
- DIS_DOWN(); //显示数据处理
- DIS_SET_SEG(); //设置模式下SEG显示方式
- //--------------------通道显示------------------------
- }
- }
- }
- void timer0() interrupt 1 using 1 //蜂鸣器报警声音
- {
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- count++;
- if(count==10) //约10*50000us 取反1次0.5s
- {
- count=0; //清除计数
- BUZ=~BUZ; //蜂鸣器取反
- }
- }
复制代码
|
评分
-
查看全部评分
|