📄 ds18b20.c
字号:
/*============================================================
File Name :timer.c
说明 :
1. 每10ms,定时器/计数器0发生溢出中断
2. 每1秒,LED及7-Segment-1计一次数
使用中断中的变量count作为条件,判断主循环,控制PA0引脚的LED 080505
=============================================================*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define BLUE 0 //pa2 examine led
#define BlueOn() PORTA&=~(1<<BLUE)
#define BlueOff() PORTA|=(1<<BLUE)
//#define DQ_18B20 (1<<2) // PD3
//#define DQ_TO_0() (DDRD |= DQ_18B20) // PD3='0'
//#define DQ_TO_1() (DDRD &= ~DQ_18B20) // PD3='float'
//#define DQ_status() (PIND & DQ_18B20) // read PD3 pin
#define DS18B20_1() PORTA |= ( 1 << 3 )
#define DS18B20_0() PORTA &= ~( 1 << 3 )
#define DS18B20_R() PINA & ( 1 << 2 )
volatile static unsigned char count=0;
volatile static unsigned char temp=0;
volatile unsigned char interrupt_count=0;
void initialize_timer(void);
unsigned char Ds18b20_start();
void ds18_send( unsigned char i );//向DS写1个字节函数
/****************************************************************************/
void Led_Flash(void)
{
_delay_ms( 20000);
BlueOn(); //点亮LED
_delay_ms(20000);
BlueOff(); //熄灭LED
}
//*****************************************************
unsigned char ds18_readChar()
{
unsigned char i = 0, j = 8;
// DDRA = 0xfb;
for( ; j>0; j-- )
{
DS18B20_0(); //总线拉低,启动‘写时间’
_delay_us( 2 ); //大于us
DS18B20_1(); //准备启动下一个‘写时间’
_delay_us( 4 ); //大于us
if( DS18B20_R() ) i |= 0x80;
i >>= 1;
_delay_us( 68 ); //延时至少60us,使写入有效
}
return( i );
}
//*****************************************************
unsigned int Read_ds18b20()
{
unsigned char th,tl;
if( !(Ds18b20_start()) ) return( 0 );//初始化函数,失败返回0
ds18_send( 0xcc ); //发跳过序列号检测指令
ds18_send( 0x44 ); //发启动温度转换指令
_delay_ms( 260 ); //延时等待转换完成
Ds18b20_start(); //初始化
ds18_send( 0xcc ); //发跳过序列号检测指令
ds18_send( 0xbe ); //发读取温度数据命令
tl = ds18_readChar(); //先读低8位温度数据
/*-------------------------------------------*/
cli();
while( !(UCSR1A & ( 1 << UDRE1) ) );
UDR1 = tl;
sei();
/*-------------------------------------------*/
th = ds18_readChar(); //再读高8位温度数据
Ds18b20_start(); //不需其他数据,初始化DS结束
return((( unsigned int )th << 8) | tl );
}
//*****************************************************
void Iint_DS15B20( void )
{
if( Ds18b20_start() == 0 )
{
ds18_send( 0xcc ); //初始化ds18b20
ds18_send( 0x4e ); //复位
ds18_send( 0x64 ); //调过rom匹配
ds18_send( 0x8a ); //设置温度上限100,下限-10
}
}
//*****************************************************
void ds18_send( unsigned char i )//向DS写1个字节函数
{
unsigned char j = 8; //读取一个字节8位
// DDRA = 0xff;
for( ; j>0; j-- )
{
DS18B20_0(); //总线拉低,启动‘写时间’
_delay_us( 2 ); //大于us
if( i&1 ){ DS18B20_1(); }
else{ DS18B20_0(); }
i >>= 1;
_delay_us( 65 ); //延时至少60us,使写入有效
DS18B20_1(); //准备启动下一个‘写时间’
_delay_us( 2 ); //大于us
}
}
/****************************************************************************/
unsigned char Ds18b20_start()
{
unsigned char flag = 0; //初始化成功或失败标志
DS18B20_0(); //总线产生下降沿,初始化开始
_delay_ms( 800 ); //总线保持低电平480-960us之间
DS18B20_1(); //总线拉高,准备接收DS的应答脉冲
_delay_us( 75 ); //读应答,典型值75us左右
flag = DS18B20_R();
while( !DS18B20_R());//等待复位成功
return( flag );
}
//*****************************************************
void Serial_Initialize(void)
{
/*-------------------------------------------*/
UCSR1B = 0;
UBRR1H = 0;
UBRR1L = 11;
UCSR1A = (1<<UDRE0);
UCSR1C = (0<<UPM11)|(0<<UPM10);
UCSR1C = (0<<USBS0) | (1<<UCSZ11) | (1<<UCSZ10);//8bit 1stop
UCSR1B = (1<<RXEN0) | (1<<TXEN0); // then, (re)enable UART_1
UCSR1B|= (1<<RXCIE0);
}
/****************************************************************************/
void initialize_timer(void)
{
TCNT0=0x070; // {(0xff-0x70)+1}*1024*(1/14.7456MHz)=10ms
TCCR0=0x07; // 定时器0 prescaler=1024
TIMSK=0x01; // OCIE0=1,定时器0溢出标志
sei(); // 使能全局中断
}
/****************************************************************************/
SIGNAL(SIG_OVERFLOW0)
{
//temp = ~temp;
interrupt_count--;
if(!interrupt_count){
interrupt_count=100;
count++;
if(count>9)
count=0;
PORTD=(count<<4);
}
TCNT0=0x70;
}
/****************************************************************************/
int main(void)
{
PORTA = 0xff;
DDRA = 0xfb;
Serial_Initialize();
initialize_timer();
Iint_DS15B20();
_delay_ms( 260 ); //延时等待转换完成
//Ds18b20_start();
interrupt_count=100;
DDRD=0xf0;
while(1)
{
if( count == 8 )
{
Led_Flash();
Read_ds18b20();
}
}
}
/****************************************************************************/
/****************************************************************************/
/*-------------------------------------------*/
/*
cli();
while( !(UCSR0A & ( 1 << UDRE0) ) );
UDR0 = ShouldDteData;
sei();
*/
/*-------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -