⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ds18b20_avr.c

📁 带串口调试的读写ds18B20程序,方便作保时候读取温度数据,拿过自动化智能控制大赛一等奖的源程序,不可多得的佳作
💻 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 + -