|
#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: ;
}
*/
|
|