|
#include <reg51.h>
#include <stdio.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit SW1 =P3^5;
sbit SW2 =P3^6;
sbit SW3 =P3^7;
sbit DIN =P1^0;
sbit CS =P1^1;
sbit CLK =P1^2;
sbit DQ =P1^3;
sbit led =P1^7;
void delay(uint i1);
void DelayMS(uint x); //子程序说明
uchar key(void); //键扫描子程序
void keycl(void);
uchar Init_DS18B20(void); //初始化DS18B20
uchar ReadOneByte(void); //读一个字节
void WriteOneByte(uchar dat); //写一个字节
void Read_Temperature(void); //读取温度
void Temperature_trans(); //温度数值处理
void write_7219(uchar add,uchar date); //向MAX7219写入地址和数据
void init_7219(); //MAX7219初始化
void disp_7219(uchar dig,uchar date); //MAX7219指定位,显示某一数值
/*********MAX7219驱动共阴极数码管**********/
// 8段数码管顺序:dp,a,b,c,d,e,f,g
// 最高位为小数点位,依次a----g
// 注意更新段码表
uchar code DSY_CODE[]={0x7e,0x30,0x6d,0x79,0x33,0x5b,0x5f,0x70,0x7f,0x7b, //段码,数字0-9的段码
0xfe,0xb0,0xed,0xf9,0xb3,0xdb,0xdf,0xf0,0xff,0xfb, //段码,数字0.-9.的段码
0x00,0x01,0x4e,0x63}; //段码,不亮,“-”,字符c,温度o的段码
uchar data temp_data[2]={0x00,0x00};
uchar code ditab[]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};//小数部分显示数值
uchar led_buf[8]; //8个显示字符变量
uchar list_flag=0,ng=0;
void main(void)
{
// Write your code here
uchar i,c;
uint d1,d2,d3;
init_7219(); //MAX7219初始化
Init_DS18B20(); //开机先初始化DS18B20,温度转换一次
WriteOneByte(0xCC); //跳过读序号列号的操作
WriteOneByte(0x44); //启动温度转换
while (1)
{
c=key();
if(c!=0) keycl();
Read_Temperature();
Temperature_trans();
//下面程序为8个显示单元配置显示的数值
/****************温度数据处理方法************************/
//二进制高字节的低半字节和低字节的高半字节组成一字节,这个
//字节的二进制转换为十进制后,就是温度值的百、十、个位值,而剩
//下的低字节的低半字节转化成十进制后,就是温度值的小数部分
/********************************************************/
d3=temp_data[0]&0x0f; //低8位的低4位为温度值的小数部分
led_buf[4]=ditab[d3]; //查表得小数部分显示值
d1=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4); //合成温度整数部分数值
d2=d1/100; d1=d1%100;
if(d2==0) {d2=20; led_buf[1]=d2;}
led_buf[1]=d2;
d2=d1/10; d1=d1%10;
if(d2==0&&led_buf[1]==20) {d2=20; led_buf[2]=d2;}
led_buf[2]=d2;
led_buf[3]=d1+10;
led_buf[0]=20;
if(ng==1) {led_buf[0]=21;}
if(list_flag==1) {led=0;}
else {
disp_7219(1,DSY_CODE[led_buf[0]]);
disp_7219(2,DSY_CODE[led_buf[1]]);
disp_7219(3,DSY_CODE[led_buf[2]]);
disp_7219(4,DSY_CODE[led_buf[3]]);
disp_7219(5,DSY_CODE[led_buf[4]]);
disp_7219(7,DSY_CODE[23]);
disp_7219(8,DSY_CODE[22]);
}
}
;
}
void delay(uint i1)
{ unsigned int i;
for(i=0;i<i1;i++) ;
}
void DelayMS(uint x)
{
uchar i;
while(x--) for(i=0;i<120;i++);
}
uchar Init_DS18B20(void) //初始化DS18B20
{
uchar status;
DQ=1; //DQ复位
delay(2);
DQ=0; //将DQ拉为低电平
delay(60); //精准延时,大于480ms,小于960ms
DQ=1; //拉高总线
delay(2);
status=DQ; //如果为0,初始化成功,如果为1,初始化失败
delay(60);
DQ=1;
return(status);
}
uchar ReadOneByte(void) //读一个字节
{
uchar i=0;
uchar dat=0;
for(i=8;i>0;i--)
{
DQ=1; _nop_();_nop_();
dat>>=1;
DQ=0;_nop_();_nop_();_nop_();_nop_(); //4 us
DQ=1;_nop_();_nop_();_nop_();_nop_(); //4 us
if(DQ) dat|=0x80;
delay(5);
}
DQ=1;
return(dat);
}
void WriteOneByte(uchar dat) //写一个字节
{
uchar i=0;
for(i=8;i>0;i--)
{
DQ=1; _nop_();_nop_();
DQ=0; _nop_();_nop_();_nop_();_nop_();
DQ=dat&0x01;
delay(5);
DQ=1;
dat>>=1;
}
DQ=1;
delay(1);
}
void Read_Temperature(void) //读取温度
{
if(Init_DS18B20()==1)
{
list_flag=1; //DS18B20不正常
}
else
{
list_flag=0;
delay(50);
WriteOneByte(0xCC); //跳过读序号列号的操作
WriteOneByte(0x44); //启动温度抓换
Init_DS18B20();
delay(1);
WriteOneByte(0xCC);
WriteOneByte(0xBE); //读取温度寄存器
temp_data[0]=ReadOneByte() ; //温度值低8位
temp_data[1]=ReadOneByte() ; //温度值高8位
// temp_data[1]=0xff;
// temp_data[0]=0xf0;
}
}
void Temperature_trans() //温度数值处理
{
ng=0;
if((temp_data[1]&0xF8)==0XF8) //温度为负值的处理方式
{
temp_data[1]=~temp_data[1];
temp_data[0]=~temp_data[0]+1;
if(temp_data[0]==0x00) {temp_data[1]++;}
ng=1;
}
}
void write_7219(uchar add,uchar date) //向MAX7219写入地址和数据,add为地址,date为写入的数据
{
uchar i;
CS=0;
for(i=0;i<8;i++) //先发送地址,高位在前,地位在后的顺序发送
{
CLK=0;
DIN=add&0x80;
add<<=1;
CLK=1; //时钟上升沿写入一位数据
delay(1);
}
for(i=0;i<8;i++) //再发送地址,高位在前,地位在后的顺序发送
{
CLK=0;
DIN=date&0x80;
date<<=1;
CLK=1;
delay(1);
}
CS=1;
}
void init_7219() //MAX7219初始化
{
write_7219(0x0c,0x01); //0x0c为关断模式寄存器,送0x01表示显示器处于工作状态
write_7219(0x0a,0x0f); //0x0a为亮度调节寄存器,送0x0f表示数码管显示亮度为最亮
write_7219(0x09,0x00); //0x09为译码模式选择寄存器,送0x00表示为非译码状态
write_7219(0x0b,0x07); //0x0b为关扫描限制寄存器,送0x07表示可将8个LED数码管动态扫描
}
void disp_7219(uchar dig,uchar date) //MAX7219指定位,显示某一数值
{
write_7219(dig,date);
}
uchar key(void) //键扫描程序,如果有键按下,返回值c=1,2,3;无键按下返回c=0;
{uchar c;
c=0;
if((SW1&SW2&SW3)==1) return c;
DelayMS(100); //防止键盘抖动
if((SW1&SW2&SW3)==1) return c;
if(SW1==0) c=1;
if(SW2==0) c=2;
if(SW3==0) c=3;
while ((SW1&SW2&SW3)==0) ;
DelayMS(100); //防止键盘抖动
return c;
}
/* void keycl(void)
{ uchar c;
led_buf[0]=22; led_buf[1]=21;led_buf[2]=21;led_buf[3]=21;
kloop:
c=key();
if(c==1) { led_buf[0]=22; led_buf[1]=21;led_buf[2]=21;led_buf[3]=1; goto kexit;}
if(c==2) { led_buf[0]=22; led_buf[1]=21;led_buf[2]=21;led_buf[3]=2;
adt0=440.0; adt1=3.0;
}
if(c==3) { led_buf[0]=22; led_buf[1]=21;led_buf[2]=21;led_buf[3]=3;
adt0=660.0; adt1=3.0;
}
four_led_display();
goto kloop;
kexit: ;
}
*/
|
|