📄 毛璐可用程序备份.c
字号:
#include <mega16.h>
#include "delay.h"
// SPI functions
#include <spi.h>
#define data_out PORTA.0 //定义18B20所用的数据线
#define data_en DDRA.0
#define data_in PINA.0
// Declare your global variables here
unsigned char code[8]; //18b20序列号临时寄存器
//eeprom unsigned char DS_mount; //18B20个数
//eeprom unsigned char ds1820_rom_codes[MAX_DS1820][8]; //18b20的序列号
unsigned char DS_mount; //18B20个数 //正式使用时用存在EEPROM,就不用每次都初使化
unsigned char ds1820_rom_codes[8][8]; //18b20的序列号
unsigned char disp[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};
//数码管显示的编码
float w=0.0;
//*******************************************
// 74HC595驱动程序
//*******************************************
unsigned char SPI_W_R(unsigned char data) //SPI口读写程序
{
SPCR=0x50; //SPI为查询方式,系统时钟四分频
SPDR=data; //写入数据
while((SPSR>>7)==0x00); //等待数据发送完毕
return SPDR; //返回收到的数据
}
//*******************************************************************
// 温度测量
void init18b20() //初始化18B20,即复位18B20
{data_en=1;//置位输出状态
data_out=1;
data_out=0;
delay_us(490);
data_out=1;
data_en=0;
delay_us(20);
while(data_in);
data_en=1;
data_out=1;
delay_us(140);
}
void write18b20(unsigned char n) //写一个字节到18b20程序
{ unsigned char m;
for(m=0;m<8;m++)
{
data_out=0;
data_out=n&1;
delay_us(40); //15~60us
data_out=1;
n=n>>1;
}
data_out=1;
}
unsigned char read18b20() //从18b20读一个字节程序
{unsigned char temp,k,n;
temp=0;
data_en=1;
for(n=0;n<8;n++)
{
data_out=0;
data_out=1;
data_en=0;
k=(data_in); //读数据,从低位开始
if(k)
temp|=(1<<n);
else
temp&=~(1<<n);
delay_us(100); //60~120us
data_en=1;
}
return (temp);
}
unsigned int gettemperature(char codes[8]) //从相应序列号读转换温度
{unsigned char k,temh,teml;//wm0,wm1,wm2,wm3;
init18b20(); //复位18b20
write18b20(0xcc);
write18b20(0x44); // 发出转换命令
delay_ms(800);
init18b20();
write18b20(0x55); //送序列号
for(k=0;k<8;k++) {write18b20(codes[k]);delay_us(6);}
write18b20(0xbe);
teml=read18b20(); //读数据
temh=read18b20();
return (unsigned int)temh*256+(unsigned int)teml;
}
void main(void)
{bit flag; //初始化18B20时,开关开着,且没有读到一个18b20时为0
int value;
char i;
DDRB=0xff;
PORTB=0xff;
DDRC=0x00;
PORTC=0xff;
for(i=0;i<8;i++) //初始化数码管,让数码管不显示什么值
{
SPI_W_R(0xff);
PORTB.0=0;
delay_us(10);
PORTB.0=1;
}
while(PINC.1==0) //初始化18B20,把每一个18B20的序列号
{ //读入到ds1820_rom_codes[DS_mount]数组中
//后面就可以根据序列号来读18B20了
if(PINC.0==1&&flag==0)
{
init18b20();
write18b20(0x33);
for(i=0;i<8;i++){code[i]=read18b20();}
for(i=0;i<8;i++){ds1820_rom_codes[DS_mount][i]=code[i];}
DS_mount++;
flag=1;
}
if(PINC.0==0)flag=0;
}
while (1)
{
for(i=0;i<DS_mount;i++) // 按顺序读每一个18B20的值
{
value=gettemperature(ds1820_rom_codes[i]);
w=(float)value;
w/=16;
SPI_W_R(disp[(int)(w*10)%10]); //显示每一个18B20测出的温度
SPI_W_R(disp[(int)w%10]);
SPI_W_R(disp[(int)(w/10)]);
SPI_W_R(0x0ff);
SPI_W_R(disp[i]);
SPI_W_R(disp[0]);
PORTB.0=0;
delay_us(10);
PORTB.0=1;
delay_ms(1000);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -