?? 18b20.c
字號:
/************************************************************************************/
/* 程序名:溫度顯示 */
/* */
/* 晶振:1.0 M CPU型號:mega8 */
/* */
/* */
/* 功能描述: 將J14和J11,J16和J18的跳帽短上,用杜邦線把J21的AD0和J9的13連上 */
/* 本實驗用AVR的SPI(即595送段碼顯示) */
/* */
/* QQ:276193028 */
/* E-mail:shenchangwei945@163.com */
/* */
/* */
/* 現代虛擬儀器儀表研究所 */
/* 2007-09-19 */
/************************************************************************************/
#include "config.h"
#define lat_on PORTB|=0x04
#define lat_off PORTB&=~0X04
const unsigned char DISP_TAB[13] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82,0xf8, 0x80, 0x90, 0xbf,0xff,0xc6};
unsigned char DISP_BUFFER[6] = {1,2,3,4,5,6};
uchar temperature_low=0; //溫度讀取寄存器,低字節
uchar temperature_high=0; //溫度讀取寄存器,高字節
/*----------------函數申明-------------------------*/
void Init_DS18B20(void);
uchar read_ds18b20(void);
void write_ds18b20(uchar data);
void read_temperature(void);
void display_temperature(void);
void spi_init(void)
{
/* 設置MOSI 和SCK 為輸出,其他為輸入 */
PORTB = (1<<PB3)|(1<<PB5);
/* 使能SPI 主機模式,設置時鐘速率為fck/16 */
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
//SPCR=0x76;//主機模式
//SPSR=0X01;//時鐘加位,Focs/2
}
void spi_send(uchar dd)
{
/* 啟動數據傳輸 */
SPDR = dd;
/* 等待傳輸結束 */
//while(!(SPSR & 0x80));
//SPDR=dd;
while((SPSR&0X80) == 0);
SPSR &= 0X7F;
//PORTB &= ~0X01;
}
/****************初始化I/O口************************************************/
void Init_R(void)
{
DDRB=0xef;
PORTB=0xFF;
DDRC = 0XFF;
PORTC=0xFF;
DDRD = 0XFF;
PORTD=0xFF;
spi_init();
}
/*-------------------------溫度傳感程序------------------------*/
void Init_DS18B20(void)//初始化ds1820
{
unsigned char x = 0;
DDRC |= 0X01;
PORTC |= 0X01; // DQO = 1; //DQ復位
_delay_us(50); // Time_Delay(8); //稍做延時
PORTC &= 0XFE; // DQO = 0; //單片機將DQ拉低
_delay_us(480); //Time_Delay(80); //精確延時 大于 480us
PORTC |= 0X01; //DQO = 1; //拉高總線
_delay_us(60);//Time_Delay(14);
DDRC &= 0XFE;
x = PINC&0X01;//DQI; //稍做延時后 如果x=0則初始化成功 x=1則初始化失敗
_delay_us(120);//Time_Delay(20);
}
/*--------------------------------------------------------*/
unsigned char read_ds18b20(void)//讀一個字節
{
unsigned char i = 0;
unsigned char dat = 0;
for (i = 8; i > 0; i--)
{
DDRC |= 0X01;
PORTC &= 0XFE; //DQO = 0; // 給脈沖信號
_delay_us(1);//1us
dat >>= 1;
PORTC |= 0X01; //DQO = 1; // 給脈沖信號
DDRC &= 0XFE;
_delay_us(2);//2us
if((PINC&0X01) == 1)
dat |= 0x80;
_delay_us(60);//Time_Delay(4);
}
return (dat);
}
/**********************************************************************************/
void write_ds18b20(unsigned char dat)//寫一個字節
{
unsigned char i = 0;
for (i = 8; i > 0; i--)
{
DDRC |= 0X01;
PORTC &= 0XFE; //DQO = 0;
PORTC = dat&0x01; //DQO = dat&0x01;
_delay_us(30);//Time_Delay(5);
PORTC |= 0X01; //DQO = 1;
dat>>=1;
}
}
void read_temperature(void)
{
float tt = 0;
uchar temp,a,b,dot;
uchar data=0;
Init_DS18B20();
write_ds18b20(0xCC); // 跳過讀序號列號的操作
write_ds18b20(0x44); // 啟動溫度轉換
Init_DS18B20();
write_ds18b20(0xCC); //跳過讀序號列號的操作
write_ds18b20(0xBE); //讀取溫度寄存器
temperature_low = read_ds18b20(); //先讀取低字節
temperature_high= read_ds18b20(); //后讀取高字節
temp=temperature_high<<4; //取高字節的低四位
temp+=temperature_low>>4; //取低字節的高四位再相加得溫度計數的整數部分數值
dot = temperature_low&0x0f; //取低字節的低四位得小數部分的相對值
if(temp>0x80)//負數
{
tt=((~(dot-1))&0x0f)*0.0625; //求相對值的原碼再*0.0625得小數部分的真實值
temp=~temp;
DISP_BUFFER[0] = 10; //Write_Data( '-' ); //bit0為負,顯示'-'
}
else
{
tt=dot*0.0625; //求相對值的原碼再*0.0625得小數部分的真實值
data=temp/100;
if(data==1)
DISP_BUFFER[0] = data;//Write_Data( flash_array[ data ] ); //bit0,如果最高位為1則顯示
else
DISP_BUFFER[0] = 11;//Write_Data( ' ' ); //bit0,如果最高位為0則消隱
}
//小數部分
tt = tt*1000; //放大一1000位
a = (uint)tt/100; //取得十分位值
b = (uint)tt%100/10; //取得百分位值
data=(temp%100)/10;
DISP_BUFFER[1] = data;//Write_Data( flash_array[data] ); //bit1顯示十位
data=temp%10;
DISP_BUFFER[2] = data;//Write_Data( flash_array[data] ); //bit2顯示個位
//Write_Data( '.' ); //bit3顯示'.'
DISP_BUFFER[3] = a;//Write_Data( flash_array[ a ] ); //bit3顯示小數位
DISP_BUFFER[4] = b;//Write_Data( flash_array[ b ] ); //bit4顯示小數位
DISP_BUFFER[5] = 12;//Write_Data( 'C' ); //bit5顯示'C'
}
/*------------------溫度顯示程序--------------------------*/
void display_temperature(void)
{
unsigned char i,temp;
temp = 0xfe;
for(i = 0;i<6;i++)
{
lat_off;
if(i == 2)
spi_send(DISP_TAB[DISP_BUFFER[i]]&0x7f);//顯示小數點
else
spi_send(DISP_TAB[DISP_BUFFER[i]]);
lat_on;
PORTD = temp;
temp<<=1;
temp|=0x01;
_delay_ms(1);
}
}
/*-----------------------------主程序-------------------------------*/
int main(void)
{
Init_R();
while(1)
{
read_temperature(); //讀取溫度
display_temperature(); //顯示溫度
}
return(0);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -