文件:DS18B20.C
環境:編譯為ICC AVR6.31A,仿真為AVR Studio4.10
硬件:ATMEGA16芯片
日期:2008年8月8日
/******************************************/
#include //包含型號頭文件
#include //包含"位"操作頭文件
#include //標準輸入輸出頭文件
#include //包含自定義常量頭文件
#include "SMG.C" //包含數碼管顯示函數
/*******************************************
函數名稱: B20_init
功 能: 復位DS18B20
參 數: 無
返回值 : 無
/********************************************/
void B20_init(void)
{
DDRA|=BIT(DS18B20); //配置為輸出
PORTA&=~BIT(DS18B20); //拉低
Delayus(600); //等待600微秒
PORTA|=BIT(DS18B20); //釋放總線
Delayus(60); //等待60微秒
DDRA&=~BIT(DS18B20); //配置為輸入
while((PINA&(BIT(DS18B20)))); //等待DS18B20拉低
while(!(PINA&(BIT(DS18B20)))); //等待DS18B20釋放總線
}
/*******************************************
函數名稱: B20_readB
功 能: 讀取壹個字節的數據
參 數: 無
返回值 : retd--返回的壹個字節數據
/********************************************/
uchar B20_readB(void)
{
uchar i,retd=0;
for(i=0;i<8;i++) //位計數值
{
retd>>=1; //右移,準備接受新的數據位
DDRA|=BIT(DS18B20); //配置為輸出
PORTA&=~BIT(DS18B20); //拉低,啟動讀數據位
PORTA|=BIT(DS18B20); //釋放總線
Delayus(5); //等待5微秒
DDRA&=~BIT(DS18B20); //配置為輸入,開始讀取數據位
if(PINA&BIT(DS18B20)) //該位是否為高
{
retd|=0x80; //是就將此位置高
}
Delayus(50); //等待50微秒
}
return retd; //將讀到的壹個字節返回
}
/*******************************************
函數名稱: B20_writeB
功 能: 寫入壹個字節的數據
參 數: wrd--要寫入的數據
返回值 : 無
/********************************************/
void B20_writeB(uchar wrd)
{
uchar i;
for(i=0;i<8;i++) //位計數值
{
DDRA|=BIT(DS18B20); //配置為輸出
PORTA&=~BIT(DS18B20); //拉低,啟動寫數據位
Delayus(1); //等待1微秒
if(wrd&0x01) //此位數據是否為高
{
PORTA|=BIT(DS18B20); //是高則將單總線拉高
}
else
{
PORTA&=~BIT(DS18B20); //是低則將單總線拉低
}
Delayus(50); //等待50微秒
PORTA|=BIT(DS18B20); //釋放總線
wrd>>=1; //右移,為寫入新的數據位做準備
}
Delayus(50); //等待50微秒
}
/*******************************************
函數名稱: Read_temp
功 能: 讀取溫度值
參 數: 無
返回值 : rettemp--返回的溫度值
/********************************************/
uint Read_temp(void)
{
uchar templ,temph;
uint temp;
B20_init(); //初始化,每次寫命令都從初始化開始
B20_writeB(0xcc); //跳過ROM
B20_writeB(0x44); //啟動溫度轉換
B20_init(); //初始化,每次寫命令都從初始化開始
B20_writeB(0xcc); //跳過ROM
B20_writeB(0xbe); //讀寄存器
templ=B20_readB(); //讀溫度低字節
temph=B20_readB(); //讀溫度高字節
temp=templ+temph*256;//將溫度整理成16位變量
return temp; //返回16位變量
}
/*******************************************
函數名稱: Num_BCD
功 能: 將壹個字節的整數轉換成三位BCD碼
參 數: num--需要轉換的整數
返回值 : chr--三位BCD碼數組指針
/********************************************/
uchar* Num_BCD(uint num)
{
uchar i,chr[3];
uchar *rept;
rept=&(chr[0]); //返回指針指向BCD碼數組
for(i=0;i<3;i++)
{
chr[2-i]=num%10; //對10取余數(其實是求模,但是對於正數,取余與求模是相等的)
num/=10; //除以10,為取出下壹位做準備
}
return rept; //返回指針
}
/*******************************************
函數名稱: main
功 能: 完成溫度的讀取與顯示
參 數: 無
返回值 : 無
/********************************************/
void main(void)
{
uint t;
uchar *temppt;
uchar i,temp[3];
Board_init( ); //初始化開發板
while(1)
{
t=Read_temp(); //讀取溫度值
t*=0.625; //轉換成實際溫度的10倍
temppt=Num_BCD(t);//將實際溫度的10倍轉換成BCD碼
for(i=0;i<3;i++) //將轉換後的BCD碼存入顯示數組
{
temp[i]=*(temppt+i);
}
for(i=0;i<3;i++) //顯示溫度
{
if(i==1)
{
temp[1]+=16; //如果是各位,則加上小數點(數碼管的譯碼
}
One_smg_display(temp[i],i+1);
Delayms(5);
}
}
}
/*******************************************
文件:SMG.C
環境:編譯為ICC AVR6.25A,仿真為AVR Studio4.10
硬件:ATMEGA16芯片
日期:2006年12月10日
功能:驅動開發板上的數碼管,滾動顯示1、2、3、4、5、6
備註:參考《AVR系列單片機C語言編程與應用實例
/******************************************/
#include //包含型號頭文件
#include //包含"位"操作頭文件
#include //標準輸入輸出頭文件
#pragma data:code
const SEGMENT[26]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,
0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd, 0x87,
0xff,0xef};
/*******************************************
函數名稱: One_smg_display
功 能: 指定的數碼管顯示指定的內容
參 數: data--顯示的內容(0-15)
number--指定的數碼管(1-6)
返回值 : 無
/********************************************/
void One_smg_display(uchar data,uchar number)
{
PORTB|=0x3F; //輸出位選
PORTA|=BIT(BITLK); //更新位選
Delayus(50); //調整時序
PORTA&=~BIT(BITLK); //鎖存位選
PORTB=SEGMENT[data]; //輸出段選
PORTA|=BIT(SEGLK); //更新段選
Delayus(50); //調整時序
PORTA&=~BIT(SEGLK); //鎖存段選
number=~BIT(number-1); //調整位選(指定時是1~6,而操作的時候是0~5)
PORTB=number; //輸出位選
PORTA|=BIT(BITLK); //更新位選
Delayus(50); //調整時序
PORTA&=~BIT(BITLK); //鎖存位選
}
/*******************************************
函數名稱: All_smg_display
功 能: 6個數碼管顯示指定的內容
參 數: *pdata--顯示內容數組地址
返回值 : 無
/********************************************/
void All_smg_display(uchar *pdata)
{
uchar i;
for(i=0;i<6;i++)
{
One_smg_display(pdata[i],i+1);
Delayms(1);
}
}
/*******************************************
函數名稱: Cycle_smg_display
功 能: 6個數碼管從右向左循環滾動顯示指定的內容(循環壹次)
參 數: *pdata--顯示內容數組地址
返回值 : 無
/********************************************/
void Cycle_smg_display(uchar *pdata)
{
uchar i,j;
for(i=0;i<240;i++) //***滾動6次,每次內容顯示40個循環
{
for(j=0;j<6;j++) //掃描6個數碼管
{
One_smg_display(pdata[(i/40+j)%6],j+1);//顯示
Delayus(2000); //調整顯示時間和亮度(時間越長亮度越高,但是太長數碼管就閃了)
}
}
}