?? shiyan3.c
字號:
/***********************************************************/
//
// 讀取DS18B20序列號實驗C程序
// (每次讀取8位并用LED燈指示具體位置)
// 2008.4.15通過調試
/***********************************************************/
#include<math.h> /*數學函數庫*/
#include<absacc.h> /*絕對地址訪問函數*/
#include<intrins.h> /*內部函數*/
#include"C8051F040.h" /*C8051F040頭文件*/
#define Decoding 0x09 /*譯碼模式*/
#define Brightness 0x0A /*亮度*/
#define BoundaryScan 0x0B /*掃描界限*/
#define Brownout 0x0C /*掉電模式*/
#define DisplayTest 0x0F /*顯示測試*/
typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;
uchar LED[8]={0x04,0x02,0x01,0x80,0x40,0x20,0x10,0x08}; /*8個LED等的對應代碼*/
uint ROMnum[8];/*存放64位ROM序列號*/
//顯示部分
uchar xdata dispbuff[7];
uchar bit_int,bit_dec,bit_all; /*整數位,小數位及全部位數*/
float xdata part_dec; /*小數部分*/
ulong xdata part_int,part_dec_int; /*整數部分和小數部分取整*/
uchar num[12]={0x7E,0x30,0x6D,0x79,0x33,0x5B,0x5F,0x70,0x7f,0x7B,0x00,0xFF};
/*從0~9及全滅和全亮*/
sbit dis_LOAD=P3^2; //MAX7219 Load-Data Input: rising edge
sbit dis_DIN=P3^0; //MAX7219 Serial-Data Input: rising edge
sbit dis_CLK=P3^3; //MAX7219 Serial-Clock Input: maximum 10MHz
sbit DQ=P6^7;
//延時納秒
void delayns(void)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
//傳送1字節(8位)
void SendChar (uchar ch)
{
uchar i,temp;
dis_CLK=0;
for (i=0;i<8;i++)
{
temp=ch&0x80;
ch=ch<<1;
if(temp)
{
dis_DIN=1;
delayns();
dis_CLK=1;
delayns();
dis_CLK=0;
}
else
{
dis_DIN=0;
delayns();
dis_CLK=1;
delayns();
dis_CLK=0;
}
}
}
//向MAX7219寫入字(16位)
void WriteWord (uchar addr,uchar num)
{
dis_LOAD=0;
delayns();
SendChar(addr);
delayns();
SendChar(num);
delayns();
dis_LOAD=1;
delayns();
}
//數值顯示
void dis_result()
{
WriteWord(0x01,dispbuff[5]);
WriteWord(0x02,dispbuff[4]);
WriteWord(0x03,dispbuff[3]);
WriteWord(0x04,dispbuff[2]);
WriteWord(0x05,dispbuff[1]);
WriteWord(0x06,dispbuff[0]);
}
//利用遞歸法實現指數運算
ulong power(ulong number,uint index)reentrant
{
ulong result;
if(index==0) result=1;
else result=number*(power(number,index-1));
return(result);
}
//數值計算
void disp(float f)
{
int i,j;
part_int=(long)f;
part_dec=f-(float)part_int;
part_dec_int=(long)(part_dec*100000);/*小數部分取整*/
bit_dec=5;/*小數部分的最多位數*/
bit_int=1;/*整數部分的最少位數*/
bit_all=1;/*總顯示的最少位數*/
//計算小數位數
for(i=1;i<=5;i++)
{
if(part_dec_int%(power(10,i))==0)
bit_dec=bit_dec-1;
}
//計算整數位數
for(i=0;i<=5;i++)
{
if(part_int>=power(10,i))
bit_int=i+1;
}
//總的顯示位數最多為6
if(bit_dec+bit_int>6)
bit_dec=6-bit_int;
//總的顯示位數
bit_all=bit_int+bit_dec;
//總的顯示位數最少為2
if(bit_all<2)
bit_int=2;
bit_all=bit_int+bit_dec;
//顯示小數位
if(bit_dec>0)
{
for(i=bit_dec-1,j=5;i>=0,j>=1;i--,j--)
{
dispbuff[i]=num[(part_dec_int%(power(10,j)))/(power(10,j-1))];/*該語句實現對各位的求取*/
}
}
//顯示整數位
for(i=bit_all-1,j=bit_int;i>=bit_dec,j>=1;i--,j--)
{
dispbuff[i]=num[(part_int%(power(10,j)))/(power(10,j-1))];
}
//小數點位置
if(bit_dec>0)
dispbuff[bit_dec]=dispbuff[bit_dec]+0x80;
//位不足則高位不顯示
if(6-bit_all>0)
{
for(i=0;i<6-bit_all;i++)
{
dispbuff[bit_all+i]=num[10];
}
}
}
//延時
void Delay1us(unsigned char us)
{
while(us)
{
_nop_();_nop_();_nop_();_nop_();_nop_();
--us;
}
}
void Delay15us(void) //延時15S
{
Delay1us(15);
}
void Delay10us(void)
{
Delay1us(10);
}
//返回0,有設備連接;返回1,無設備連接
bit RstDS18B20(void)
{
uchar i;
bit RstFlag=1;
DQ=0;
for(i=0;i<40;i++) //延時480us
{
Delay15us();
}
DQ=1;
for(i=0;i<4;i++) //延時15~60us
{
Delay15us();
}
for(i=0;i<16;i++) //延時60~240us
{
Delay15us();
if(DQ==0) RstFlag=0;
}
for(i=0;i<16;i++) //240us
{
Delay15us();
}
return RstFlag;
}
void WriteDS18B20(uchar val)
{
uchar i;
DQ=1;
Delay1us(1);
for(i=0;i<8;i++)
{
DQ=0;
Delay15us();
DQ=val&0x01;
Delay15us();Delay15us();Delay15us();
DQ=1;
val=val/2;
Delay1us(1);
}
}
uchar ReadDS18B20(void)
{
uchar i,value=0;
DQ=1;
Delay1us(1);
for(i=0;i<8;i++)
{
DQ=0;
Delay1us(4);
DQ=1;
Delay10us();
value>>=1;
if(DQ==1)
{
value|=0x80;
}
Delay15us();Delay15us();Delay15us();
}
return(value);
}
uint ReadROMDS18B20(void)
{
int i;
RstDS18B20();
WriteDS18B20(0x33);
for(i=0;i<8;i++)
{
ROMnum[i]=ReadDS18B20();
}
RstDS18B20();
for(i=0;i<8;i++)
return ROMnum[i];
}
void delay(ulong t)
{
for(;t>0;t--);
}
void ConfigC8051F040()
{
int i; /*延時計數器*/
//看門狗禁止
WDTCN=0x07; /*設置看門狗超時間隔*/
WDTCN=0xDE;
WDTCN=0xAD;
//交叉開關使能配置,使得P0~P3口能輸出
SFRPAGE=0x0F;
XBR0=0x00;
XBR1=0x00;
XBR2=0x40;
XBR3=0x00;
//管腳輸出配置
SFRPAGE=0x0F;
P3MDOUT=0x0F; /*P3[3:0]推挽輸出,用以顯示部分*/
//晶振配置
SFRPAGE=0x0F;
OSCXCN=0x77; /*配置為外部石英晶振2分頻模式,且配置相應頻率的驅動電流*/
for(i=0;i<256;i++); /*等待外部晶振穩定*/
while(!(OSCXCN & 0x80));
/*查詢XTLVLD是否為1,若為1,表明外部晶振穩定,可切換到外部時鐘*/
CLKSEL=0x01; /*選擇外部晶振*/
OSCICN=0x00; /*將內部晶振關閉,也可不關閉,不關閉時MCU耗能高*/
}
//MAX7219初始化
void InitDis (void)
{
WriteWord(Brownout,0x00); /*設置電源工作模式*/
WriteWord(BoundaryScan,0x06); /*設置掃描界限*/
WriteWord(Brightness,0x05); /*設置亮度*/
WriteWord(Decoding,0x00); /*設置譯碼模式*/
WriteWord(DisplayTest,0x00); /*設置非測試模式*/
WriteWord(Brownout,0x01); /*設置電源工作模式*/
}
main()
{
int i;
ConfigC8051F040();
InitDis();
ReadROMDS18B20();
for(;;)
{
for(i=0;i<8;i++)
{
disp(ROMnum[i]);
dis_result();
WriteWord(0x07,LED[i]);
delay(100000);
delay(100000);
}
}
}
//***************************結束*******************************//
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -