📄 18b20_multicultural_temperature.txt
字号:
#include <mega64.h>
#include <stdlib.h>
#include <delay.h>
#define DQ_pin 0
#define DQ_H() PORTF|=(1<<DQ_pin)
#define DQ_L() PORTF&=~(1<<DQ_pin)
#define DQ_O() DDRF|=(1<<DQ_pin)
#define DQ_I() DDRF&=~(1<<DQ_pin)
#define Read_DQ() PINF&(1<<DQ_pin)
#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7
//FE是一个固有变量,在AVR的头文件里面有定义,它是特定的寄存器的位。这里FE的值是4。
#define FRAMING_ERROR (1<<FE) //USART I/O数据寄存器-UDR,Bit 4 – FE: 帧错误
#define PARITY_ERROR (1<<UPE) //Bit 2 – UPE: USART奇偶校验错误
#define DATA_OVERRUN (1<<OVR) //*Bit 3 – DOR:数据溢出
#define DATA_REGISTER_EMPTY (1<<UDRE) //5 – UDRE: USART数据寄存器空
#define RX_COMPLETE (1<<RXC) //*Bit 7 – RXC: USART接收结束
// USART0 Receiver buffer
#define RX_BUFFER_SIZE0 8
char rx_buffer0[RX_BUFFER_SIZE0];
#if RX_BUFFER_SIZE0<256
unsigned char rx_wr_index0,rx_rd_index0,rx_counter0;
#else
unsigned int rx_wr_index0,rx_rd_index0,rx_counter0;
#endif
// This flag is set on USART0 Receiver buffer overflow
bit rx_buffer_overflow0;
// USART0 Receiver interrupt service routine USARTO 接收中断服务程序
interrupt [USART0_RXC] void usart0_rx_isr(void)
{
char status,data;
status=UCSR0A;
data=UDR0; /* read the received data */
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
rx_buffer0[rx_wr_index0]=data;
if (++rx_wr_index0 == RX_BUFFER_SIZE0) rx_wr_index0=0;
if (++rx_counter0 == RX_BUFFER_SIZE0)
{
rx_counter0=0;
rx_buffer_overflow0=1;
};
};
}
////
unsigned int rxBufferCount0(void) //返回rx_counter缓存接收的计数
{
return rx_counter0;
}
void clearRxBuffer0(void)
{
#asm("cli");
rx_rd_index0 = 0;
rx_wr_index0 = 0;
rx_counter0 = 0;
#asm("sei");
}
////
#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART0 Receiver buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void) //得到数据data
{
char data;
while (rx_counter0==0);
data=rx_buffer0[rx_rd_index0]; //
if (++rx_rd_index0 == RX_BUFFER_SIZE0) rx_rd_index0=0;
#asm("cli") //开中断
--rx_counter0;
#asm("sei") //禁止所有中断
return data;
}
#pragma used-
#endif
// USART0 Transmitter buffer
#define TX_BUFFER_SIZE0 64
char tx_buffer0[TX_BUFFER_SIZE0];
#if TX_BUFFER_SIZE0<256
unsigned char tx_wr_index0,tx_rd_index0,tx_counter0;
#else
unsigned int tx_wr_index0,tx_rd_index0,tx_counter0;
#endif
// USART0 Transmitter interrupt service routine
interrupt [USART0_TXC] void usart0_tx_isr(void)
{
if (tx_counter0)
{
--tx_counter0;
UDR0=tx_buffer0[tx_rd_index0];
if (++tx_rd_index0 == TX_BUFFER_SIZE0) tx_rd_index0=0;
};
}
#ifndef _DEBUG_TERMINAL_IO_
// Write a character to the USART0 Transmitter buffer
#define _ALTERNATE_PUTCHAR_
#pragma used+
void putchar(char c)
{
while (tx_counter0 == TX_BUFFER_SIZE0);
#asm("cli")
if (tx_counter0 || ((UCSR0A & DATA_REGISTER_EMPTY)==0))
{
tx_buffer0[tx_wr_index0]=c;
if (++tx_wr_index0 == TX_BUFFER_SIZE0) tx_wr_index0=0;
++tx_counter0;
}
else
UDR0=c;
#asm("sei")
}
#pragma used-
#endif
// USART1 Receiver buffer
#define RX_BUFFER_SIZE1 8
char rx_buffer1[RX_BUFFER_SIZE1];
#if RX_BUFFER_SIZE1<256
unsigned char rx_wr_index1,rx_rd_index1,rx_counter1;
#else
unsigned int rx_wr_index1,rx_rd_index1,rx_counter1;
#endif
// This flag is set on USART1 Receiver buffer overflow
bit rx_buffer_overflow1;
// USART1 Receiver interrupt service routine
interrupt [USART1_RXC] void usart1_rx_isr(void)
{
char status,data;
status=UCSR1A;
data=UDR1;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
rx_buffer1[rx_wr_index1]=data;
if (++rx_wr_index1 == RX_BUFFER_SIZE1) rx_wr_index1=0;
if (++rx_counter1 == RX_BUFFER_SIZE1)
{
rx_counter1=0;
rx_buffer_overflow1=1;
};
};
}
// Get a character from the USART1 Receiver buffer
#pragma used+
char getchar1(void)
{
char data;
while (rx_counter1==0);
data=rx_buffer1[rx_rd_index1];
if (++rx_rd_index1 == RX_BUFFER_SIZE1) rx_rd_index1=0;
#asm("cli")
--rx_counter1;
#asm("sei")
return data;
}
#pragma used-
// USART1 Transmitter buffer
#define TX_BUFFER_SIZE1 64
char tx_buffer1[TX_BUFFER_SIZE1];
#if TX_BUFFER_SIZE1<256
unsigned char tx_wr_index1,tx_rd_index1,tx_counter1;
#else
unsigned int tx_wr_index1,tx_rd_index1,tx_counter1;
#endif
// USART1 Transmitter interrupt service routine
interrupt [USART1_TXC] void usart1_tx_isr(void)
{
if (tx_counter1)
{
--tx_counter1;
UDR1=tx_buffer1[tx_rd_index1];
if (++tx_rd_index1 == TX_BUFFER_SIZE1) tx_rd_index1=0;
};
}
// Write a character to the USART1 Transmitter buffer
#pragma used+ //使用#pragma used+/#pragma used-之间的代码,生成putchar()函数,代替原系统的putchar()函数.
void putchar1(char c)
{
while (tx_counter1 == TX_BUFFER_SIZE1);
#asm("cli")
if (tx_counter1 || ((UCSR1A & DATA_REGISTER_EMPTY)==0))
{
tx_buffer1[tx_wr_index1]=c;
if (++tx_wr_index1 == TX_BUFFER_SIZE1) tx_wr_index1=0;
++tx_counter1;
}
else
UDR1=c;
#asm("sei")
}
#pragma used-
void uartPutchars(unsigned char *c, unsigned int length) // 输出单位的数据
{
unsigned int n;
for (n = 0; n < length; n++)
putchar(*(c++));
}
void PrintString(char *Str) //输出数组
{
unsigned char i;
i=0;
while(Str[i]!=0)
{
putchar(Str[i]);
i++;
}
}
void uartPutchars1(unsigned char *c, unsigned int length)
{
unsigned int n;
for (n = 0; n < length; n++)
putchar1(*(c++));
}
void PrintString1(char *Str)
{
unsigned char i;
i=0;
while(Str[i]!=0)
{
putchar1(Str[i]);
i++;
}
}
static unsigned int ToBeSend[8]={0},tflag[8];
static unsigned char ROM1[8][8]={
0x28,0x7B,0xFC,0x33,0x01,0x00,0x00,0x92,
0x28,0x56,0xD6,0x20,0x01,0x00,0x00,0x9B,
0x28,0x1B,0x51,0x21,0x01,0x00,0x00,0xB1,
0x28,0x41,0xC9,0x20,0x01,0x00,0x00,0x56,
0x28,0x66,0xFD,0x20,0x01,0x00,0x00,0xFE,
0x28,0x9A,0xE8,0x20,0x01,0x00,0x00,0x5F,
0x28,0xDB,0x37,0x34,0x01,0x00,0x00,0x1A,
0x28,0x81,0xC5,0x20,0x01,0x00,0x00,0xE8};//16
void init_1820(void)
{
DQ_H(); //DQ为高
DQ_O(); //输出模式
DQ_L(); //DQ低
delay_us(190);
delay_us(190);
delay_us(110); //480us以上,复位延时
DQ_H(); //DQ为高
DQ_I(); //输入模式
delay_us(60); //15~60us,DS1820的等待时间
delay_us(120);
delay_us(120);
delay_us(120);
delay_us(60);
DQ_H(); //DQ为高
DQ_O(); //输出模式
}
/******向DS1820写一个字节****************/
void write_1820(unsigned char x)
{
unsigned char m;
for(m=0;m<8;m++) //从低位开始连续把X的第m位发送出去
{
DQ_L(); //DQ为低,开始发送
if(x&(1<<m)) //如果第m位是1
{
delay_us(1);
DQ_H(); //DQ为高
}
else
DQ_L(); //否则DQ为低
delay_us(60); //信号保持60~120us
DQ_H(); //发送完后DQ为高
delay_us(1); //两次发送间隙要大于1us
}
}
/***********从DS1820读一个字节**************************/
unsigned char read_1820(void)
{
unsigned char tmp=0,k,n;
for(n=0;n<8;n++)
{
DQ_L(); //DQ为低
delay_us(2); //间隙要大于1us
DQ_H(); //DQ为高
DQ_I(); //输入模式
k=Read_DQ(); //读数据,从低位开始
if(k) //如果k=1(即PIND6为1)
tmp|=(1<<n); //temp的第n位与1求或
else
tmp&=~(1<<n); //temp的第n位与0求与
delay_us(60); //60~120us
DQ_O(); //输出模式
delay_us(1); //两次接收间隙要大于1us
}
return (tmp);
}
/**********1820转换温度************************/
void DS1820Convert(void)
{
init_1820(); //复位18b20
write_1820(0xCC); // Skip ROM(不发出地址码)
write_1820(0x44); //发出开始转换命令
}
/**********获取1820的rom序列**********************/
/*unsigned char read_ROM(void)
{
unsigned char j;
init_1820();
delay_us(1);
write_1820(0x33);
for(j=0;j<8;j++){ROM1[j]=read_1820();}
return 1;
} */
/**********获取1820的温度********************/
void get_T(void)
{
unsigned char teml1,temh1,i;
unsigned char j=0;
unsigned int count2=0;
//unsigned char flag;
// flag=read_ROM();
// while(!flag);
DS1820Convert();
for(j=0;j<8;j++)
{ init_1820(); //复位18b20
write_1820(0x55);
for (i=0;i<8;i++) //发送所要查询的温感的ROMcode
{
write_1820(ROM1[j][i]);
}
delay_ms(2);
write_1820(0xBE); //发出读寄存器命令
teml1=read_1820(); //读数据,第一次是收到第一个字节
temh1=read_1820(); //第二次收到第二个字节(共会传输9个,但这里只需前2个)
/*count2=temh1;
count2<<=8;
count2=count2|teml1;
if(count2<0x0fff)
{
tflag=0;
}
else
{
count2=~count2+1;
tflag=1;
}
count2=count2*(0.625); */
count2=(temh1*256+teml1)*6.25/100; //计算具体温度,输出结果为实际值的100倍
ToBeSend[j]=count2;
if(count2<4095)
{
tflag[j]=0;
}
else
{
count2=(~count2+1);
tflag[j]=1;
}
}
}
// Declare your global variables here
void main(void)
{
// Declare your local variables here
// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;
// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;
// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;
// Port E initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTE=0x00;
DDRE=0x00;
// Port F initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=Out
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=1
PORTF=0x01;
DDRF=0x01;
// Port G initialization
// Func4=In Func3=In Func2=In Func1=In Func0=In
// State4=T State3=T State2=T State1=T State0=T
PORTG=0x00;
DDRG=0x00;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
ASSR=0x00;
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// OC1C output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
OCR1CH=0x00;
OCR1CL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// Timer/Counter 3 initialization
// Clock source: System Clock
// Clock value: Timer 3 Stopped
// Mode: Normal top=FFFFh
// Noise Canceler: Off
// Input Capture on Falling Edge
// OC3A output: Discon.
// OC3B output: Discon.
// OC3C output: Discon.
TCCR3A=0x00;
TCCR3B=0x00;
TCNT3H=0x00;
TCNT3L=0x00;
ICR3H=0x00;
ICR3L=0x00;
OCR3AH=0x00;
OCR3AL=0x00;
OCR3BH=0x00;
OCR3BL=0x00;
OCR3CH=0x00;
OCR3CL=0x00;
// USART0 initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART0 Receiver: On
// USART0 Transmitter: On
// USART0 Mode: Asynchronous
// USART0 Baud rate: 115200
UCSR0A=0x00;
UCSR0B=0xD8;
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x03;
// USART1 initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART1 Receiver: On
// USART1 Transmitter: On
// USART1 Mode: Asynchronous
// USART1 Baud rate: 115200
UCSR1A=0x00;
UCSR1B=0xD8;
UCSR1C=0x06;
UBRR1H=0x00;
UBRR1L=0x03;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
// INT3: Off
// INT4: Off
// INT5: Off
// INT6: Off
// INT7: Off
EICRA=0x00;
EICRB=0x00;
EIMSK=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
ETIMSK=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
while (1)
{
// Place your code here
char j;
char n_dat,flagdata;
static char i;
char t_value[10];
// float t_f;
get_T();
// t_f=ToBeSend;
for(i=0;i<8;i++)
{
if(tflag[i]==0)
flagdata='+';
else
flagdata='-';
n_dat=(i+0x31);
ftoa(ToBeSend[i],1,t_value);
putchar(n_dat);
putchar(' ');
putchar(' ');
putchar(flagdata);
PrintString(t_value);
putchar('`');
putchar('C');
delay_us(1000);
putchar(' ');
putchar(' ');
putchar('\n');
/*//putchar(i+0x31);
putchar('R');
for(j=0;j<8;j++)
{
putchar(ROM1[i][j]);
}
putchar('\n');
delay_us(1000);*/
delay_ms(1000);
}
};
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -