📄 ds18b20_avr.c
字号:
#i nclude "define.h"
#i nclude "uart.h"
#i nclude <avr/interrupt.h>
#define uchar unsigned char
#define BIT(x) 1<<x
#define ds18b20_dq PB0
#define set_ds18b20_dq_ddr() DDRB|=1<<ds18b20_dq
#define set_ds18b20_dq() PORTB|=1<<ds18b20_dq
#define clr_ds18b20_dq() PORTB&=~(1<<ds18b20_dq)
#define clr_ds18b20_dq_ddr() DDRB&=~(1<<ds18b20_dq)
#define in_ds18b20_dq() PINB&(1<<ds18b20_dq)
#define ds18b20_read_rom 0x33
#define ds18b20_match_rom 0x55
#define ds18b20_skip_rom 0xcc
#define ds18b20_search_rom 0xf0
#define ds18b20_alarm_search_rom 0xec
#define ds18b20_write_ram 0x4e
#define ds18b20_read_ram 0xbe
#define ds18b20_copy_ram 0x48
#define ds18b20_convert_tem 0x44
#define ds18b20_eecall_eeprom 0xb8
#define ds18b20_read_power_supply 0xb4
uint8 temperature_high,temperature_low;
uint8 display_buffer[5];
volatile uint8 Time_tick0,Flag = 0;
volatile uint8 data4;
volatile uint8 transBuffer[5];
volatile uint8 trKeyBuffer[2];
volatile dataFlag = 0,keyFlag = 0; //有数据,有按键标志位
volatile uchar s1,s2,s,a; //PD2,PD3
//volatile uint8 transBufferTest[5] = {0x0a,0x01+1,0x02+1,0x01+1,0x00+1};
volatile uint8 transBufferTest[5] = {0x0a,0x03+1,0x01+1,0x00+1,0x07+1};
void UART_init(void) //11.0592MHz频率,设置波特率9.6k,8位数据位,无校验,接收发送使能,1位停止位
{
UCSRB=0x00;
UBRRH= 0;
UBRRL =7; /*在异步情况下设置波特率*/
UCSRA = 0x00;
UCSRC =(1<<URSEL)|0x06; //0x06 8位数据,1位停止位,无校验
UCSRB= (1<<RXCIE)|(1<<RXEN)|(1<<TXEN); //发送接收使能,使用查询方式,故没有使能中断
}
/*****************************************************************************
**函数名: UART_sentbyte
**
**功能描述: 出口发送数据查询方式发送接收字符
**
**入口参数:要发送的数据
**
*****************************************************************************/
void UART_sentbyte(uint8 c) //
{
while(!(UCSRA&(1<<UDRE)));//等待发送缓冲区为空
UDR=c;
}
/****************************************************************************
* 名称:ISendBuf()
* 功能:将缓冲区的数据发送回主机,并等待发送完毕。
* 入口参数:数据指针
* 出口参数:无
****************************************************************************/
void UART_SendData(uint8 *ptr)
{
while (*ptr)
{
UART_sentbyte(*ptr++);
}
UART_sentbyte(0x0D);
UART_sentbyte(0x0A); //结尾发送回车换行
}
void reset_ds18b20(void)
{
clr_ds18b20_dq();
_delay_us(198);//100us
_delay_us(198);//100us
_delay_us(198);//100us
_delay_us(198);//100us
set_ds18b20_dq();
_delay_us(38);//20us
}
void ack_ds18b20(void)
{
unsigned int i = 0;
while(in_ds18b20_dq())
{
i++;
_delay_us(1);
if(i>65500) break;
}
i = 0;
while(!(in_ds18b20_dq()))
{
i++;
_delay_us(1);
if(i>65500) break;
}
_delay_us(38);//20us
}
uchar read_ds18b20(void)
{
uchar data=0;
uchar i=0;
for(i=0;i<8;i++)
{
data>>=1;
clr_ds18b20_dq();
_delay_us(1);//1us
set_ds18b20_dq();
_delay_us(2);//2us
if(in_ds18b20_dq()) data|=0x80;
_delay_us(118);//60us
}
return(data);
}
void write_ds18b20(uchar data)
{
uchar i=0;
for(i=0;i<8;i++)
{
if(data&0x01){
clr_ds18b20_dq();
_delay_us(14);//8us
set_ds18b20_dq();
_delay_us(108);//55us
}
else
{
clr_ds18b20_dq();
_delay_us(108);//55us
set_ds18b20_dq();
_delay_us(14);//8us
}
data>>=1;
}
}
void convert_ds18b20(void)
{
reset_ds18b20();
ack_ds18b20();
_delay_ms(1);
write_ds18b20(ds18b20_skip_rom);
write_ds18b20(ds18b20_convert_tem);
}
//*************************************************
void Modify_ds18b20(void)
{
reset_ds18b20();
ack_ds18b20();
_delay_ms(1);
write_ds18b20(ds18b20_skip_rom);
write_ds18b20(ds18b20_write_ram);
_delay_ms(1);
write_ds18b20(0x00);
write_ds18b20(0x00);
write_ds18b20(0x66);
}
void read_temperature(void)
{
uchar low=0;
uchar high=0;
reset_ds18b20();
ack_ds18b20();
_delay_ms(1);
write_ds18b20(ds18b20_skip_rom);
write_ds18b20(ds18b20_read_ram);
low=read_ds18b20();
high=read_ds18b20();
//low -= 0x08;
if(high!=0xff)
{
temperature_low=low;
temperature_high=high;
}
else if(low!=0xff)
{
temperature_low=low;
temperature_high=high;
}
convert_ds18b20();
}
SIGNAL(SIG_OVERFLOW0)
{
cli(); //关中断
TCNT0=184;
Time_tick0++;
if((Time_tick0==11)&&(!Flag))
{
Time_tick0 = 0;
PORTC = 0x00;
Flag = ~Flag;
//UART_SendData("dataFlag is ");
//UART_sentbyte(0x30+dataFlag);
//UART_sentbyte(0x0a);
//UART_sentbyte(0x0d);
}
else if((Time_tick0==20)&&(Flag))
{
Time_tick0 = 0;
if(keyFlag)
{
PORTC = trKeyBuffer[2-keyFlag];
keyFlag--;
dataFlag = 0;
UART_SendData("Key transfer... ********");
UART_sentbyte(48+trKeyBuffer[3-keyFlag]);
}
else if(dataFlag<5)
{
PORTC = transBuffer[dataFlag];
dataFlag++;
UART_SendData("Data Transfer...");
}
Flag = ~Flag;
//UART_SendData("Data Transfer...");
}
sei();
}
void OSTickInit(void)
{
TCCR0 = 0;
TCCR0 |= (1<<CS02)|(1<<CS00); /* 1024预分频 */
TIMSK |= (1<<TOIE0); /* T0溢出中断允许 */
//TCNT0=112; /* 置计数起始值 (256-CPU_OSC/1024/OS_TICKS_PER_SEC) */
TCNT0 = 184;//定时10ms
//定时2ms
}
void EXt_Init(void)
{
MCUCR=(1<<ISC11)|(1<<ISC01); /*设置为上升沿触发中断1*/
/*
ISCx1:0=00 INTx引脚为低电平时产生中断请求
ISCx1:0=01 INTx引脚上任意的逻辑电平变化都将引发中断
ISCx1:0=10 INTx引脚的下降沿产生中断请求
ISCx1:0=11 INTx引脚的上升沿产生中断请求
*/
GIFR=(1<<INTF1)|(1<<INTF0);//写1清除标志位,在使能中断前最好先把对应
// 的标志位清除,以免误触发
GICR=(1<<INT1)|(1<<INT0); //使能三个外部中断
}
SIGNAL(SIG_INTERRUPT1) //key1的设置程序
{
s1 = (~s1)&0x01;
s = ((~(s1^(s2>>1)))<<2)&0x04;
trKeyBuffer[1] = s1|s2|s;
keyFlag = 2;
UART_sentbyte(s1+48);
UART_sentbyte(s+48);
UART_sentbyte(0x0a);
UART_sentbyte(0x0d);
//PORTB&= ~(PORTB&BIT(PB1));
//PORTB|=BIT(PB1);
if(PORTB&BIT(PB1))
PORTB &= 0b11111101;
else
PORTB |= 0b00000010;
}
SIGNAL(SIG_INTERRUPT0) //key2的设置程序
{
s2 = (~s2)&0x02;
//s = (~(s1^(s2>>1)))<<2;
s = ((~(s1^(s2>>1)))<<2)&0x04;
trKeyBuffer[1] = s1|s2|s;
keyFlag = 2;
UART_sentbyte(s2+48);
UART_sentbyte(s+48);
UART_sentbyte(0x0a);
UART_sentbyte(0x0d);
if(PORTB&BIT(PB1))
PORTB &= 0b11111101;
else
PORTB |= 0b00000010;
}
//**************************************main********************************************
void main(void)
{
unsigned int temp = 0;
uchar temp8 = 0;
uchar data=0;
DDRC=0x00;
PORTC=0xff;
DDRD=0x00;
PORTD=0xff;
DDRB|=BIT(PB1);
OSTickInit();
clr_ds18b20_dq();
set_ds18b20_dq_ddr();
Modify_ds18b20();
EXt_Init();
UART_init();
display_buffer[4]='\0';
_delay_ms(100);
//if(!(PIND&0x08))
//{
DDRC = 0xff;
transBuffer[0] = 0b1010;//导言
trKeyBuffer[0] = 0b1100; //键按的导言
sei();
while(1)
{
convert_ds18b20();
//s = s1|s2;
_delay_ms(198);
_delay_ms(198);
_delay_ms(198);
_delay_ms(198);
_delay_ms(198);
_delay_ms(198);
_delay_ms(198);
_delay_ms(198);
_delay_ms(198);
_delay_ms(198);
_delay_ms(198);
_delay_ms(198);
_delay_ms(198);
_delay_ms(198);
_delay_ms(198);
_delay_ms(198);
_delay_ms(198);
_delay_ms(198);
_delay_ms(198);
_delay_ms(198);
_delay_ms(198);
_delay_ms(198);
read_temperature();
temp = temperature_high<<8|temperature_low;
temp-=32;
temperature_high = temp>>8;
temperature_low = temp&0xff;
temp8 = (temperature_high&0x03)<<4|((temperature_low&0xf0)>>4);
if(temp8<40&&temp8>10)
{
temp8-=10;
temperature_high = (temp8&0b00010000)>>4|0b00000010;
temperature_low = ((temp8&0x0f)<<4)|(temperature_low&0x0f);
while(dataFlag!=5);
//if(dataFlag == 5) //因为中断中传送完后dataFlag = 5
{
transBuffer[1] = (((temperature_high&0x03)<<1)|(temperature_low>>7))+1;
transBuffer[2] = ((temperature_low&0b01110000)>>4)+1;
transBuffer[3] = ((temperature_low&0b00001110)>>1)+1;
transBuffer[4] = (((temperature_low&0b00000001)<<2)|0x03);
// UART_SendData("In the main now the dataFlag is ");
// UART_sentbyte(0x30+dataFlag);
// UART_sentbyte(0x0a);
// UART_sentbyte(0x0d);
dataFlag = 0; //数据准备好,5Byte
//UART_SendData("Data is ready");
}
//UART_SendData("....................................ConvTemp finished");
//UART_sentbyte(48+s);
temp=temperature_high<<4;
temp+=temperature_low>>4;
display_buffer[0]=0+48;
data=temp/100;
display_buffer[1]=data+48;
temp%=100;
data=temp/10;
display_buffer[2]=48+data;
data=temp%10;
display_buffer[3]=48+data;
if(0==dataFlag)
UART_SendData(display_buffer);
UART_sentbyte(trKeyBuffer[1]+48);
/*
UART_SendData("DS18B20 Test:");
UART_SendData("DS18B20 begin:");
_delay_ms(100);
_delay_ms(100);
_delay_ms(100);
_delay_ms(100);
_delay_ms(100);
_delay_ms(100);
_delay_ms(100);
convert_ds18b20();
_delay_ms(198);
_delay_ms(198);
_delay_ms(198);
_delay_ms(198);
_delay_ms(198);
_delay_ms(198);
_delay_ms(198);
_delay_ms(198);
read_temperature();
UART_SendData("DS18B20 over:");
temp=temperature_high<<4;
temp+=temperature_low>>4;
temp1=temperature_low&0x0f;
if(temp>0x80)//负
{
display_buffer[0]=48;
temp=~temp;
data=temp/100;
display_buffer[1]=0x5f;//-
temp%=100;
data=temp/10;
display_buffer[2]=48+data;
data=temp%10;
display_buffer[3]=data+48;
}
else
{
display_buffer[0]=0+48;
data=temp/100;
display_buffer[1]=data+48;
temp%=100;
data=temp/10;
display_buffer[2]=48+data;
data=temp%10;
display_buffer[3]=48+data;
}
UART_SendData(display_buffer);
display_buffer[0]=temp1/10+48;
display_buffer[1]=temp1%10+48;
display_buffer[2]=48;
UART_SendData(display_buffer);
// }*/
}
}//if
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -