📄 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 + -