* Program demonstrujacy dzialanie termometru DS1820;
This program measure a temperature from DS1820 and shows it at LCD.
Piny/Pins:
PD1 - RS
PD2 - E
PD3 - D4
PD4 - D5
PD5 - D6
PD6 - D7
*/
#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>
#define _AVR_DELAY_H_ 1
#define F_CPU 10000000UL
#define DDR_DB4 DDRD
#define PORT_DB4 PORTD
#define DB4 PD3
#define DDR_DB5 DDRD
#define PORT_DB5 PORTD
#define DB5 PD4
#define DDR_DB6 DDRD
#define PORT_DB6 PORTD
#define DB6 PD5
#define DDR_DB7 DDRD
#define PORT_DB7 PORTD
#define DB7 PD6
#define DDR_RS DDRD
#define PORT_RS PORTD
#define RS PD1
#define DDR_E DDRD
#define PORT_E PORTD
#define E PD2
#define SET_B1 PORT_B1 |= _BV(B1)
#define CLR_B1 PORT_B1 &= ~_BV(B1)
#define SET_B2 PORT_B2 |= _BV(B2)
#define CLR_B2 PORT_B2 &= ~_BV(B2)
#define SET_B3 PORT_B3 |= _BV(B3)
#define CLR_B3 PORT_B3 &= ~_BV(B3)
#define SET_B4 PORT_B4 |= _BV(B4)
#define CLR_B4 PORT_B4 &= ~_BV(B4)
#define SET_DB4 PORT_DB4 |= _BV(DB4)
#define CLR_DB4 PORT_DB4 &= ~_BV(DB4)
#define SET_DB5 PORT_DB5 |= _BV(DB5)
#define CLR_DB5 PORT_DB5 &= ~_BV(DB5)
#define SET_DB6 PORT_DB6 |= _BV(DB6)
#define CLR_DB6 PORT_DB6 &= ~_BV(DB6)
#define SET_DB7 PORT_DB7 |= _BV(DB7)
#define CLR_DB7 PORT_DB7 &= ~_BV(DB7)
#define SET_E PORT_E |= _BV(E)
#define CLR_E PORT_E &= ~_BV(E)
#define SET_RS PORT_RS |= _BV(RS)
#define CLR_RS PORT_RS &= ~_BV(RS)
#define LCD_X 16
#define LCD_Y 2
unsigned char temperature;
unsigned char temperatura=1;
union {
int tds;
char nds[2];
}ds;
char buf[6];
void out_nibble(char x)
{
CLR_DB4;
CLR_DB5;
CLR_DB6;
CLR_DB7;
if(x & _BV(0)) SET_DB4;
if(x & _BV(1)) SET_DB5;
if(x & _BV(2)) SET_DB6;
if(x & _BV(3)) SET_DB7;
}
void write_to_lcd(char x)
{
SET_E;
out_nibble(x >> 4);
CLR_E;
SET_E;
out_nibble(x);
CLR_E;
_delay_ms(8);
}
void delay(int useconds)
{
int s;
useconds = useconds;
for (s=0; s<useconds;s++);
}
void write_command(char x)
{
CLR_RS;
write_to_lcd(x);
}
void write_char(char x)
{
SET_RS;
write_to_lcd(x);
}
void write_text(char * s)
{
while(*s)
{
write_char(*s);
s++;
}
}
void lcd_init(void)
{
DDR_DB4 |= _BV(DB4);
DDR_DB5 |= _BV(DB5);
DDR_DB6 |= _BV(DB6);
DDR_DB7 |= _BV(DB7);
DDR_E |= _BV(E);
DDR_RS |= _BV(RS);
_delay_ms(120);
CLR_E;
CLR_RS;
char i;
for(i = 0; i < 3; i++)
{
SET_E;
out_nibble(0x03);
CLR_E;
_delay_ms(5);
}
SET_E;
out_nibble(0x02);
CLR_E;
_delay_ms(8);
write_command(0x28); // interfejs 4-bity, 2-linie, znak 5x7
write_command(0x08); // wyłącz LCD, kursor i miganie
write_command(0x01); // czyść LCD
write_command(0x06); // bez przesuwania w prawo
write_command(0x0C); // włącz LCD, bez kursora i mrugania
}
void LCD_xy(uint8_t x, uint8_t y)
{
switch(y)
{
case 1: y=0x40; break;
case 2: y=0x14; break;
}
write_command(0x80+y+x);
}
void lcdxy(uint8_t x, uint8_t y)
{
switch(y)
{
case 1: y=0x40; break;
case 2: y=0x14; break;
}
write_command(0x80+y+x);
}
void LCD_clr(void)
{
write_command(0x01);
_delay_ms(8);
LCD_xy(0,0);
}
//==========================================================================================//
void dl(char x)
{
TCCR0=0x02;
OCR0=x;
while(1)
{
if(TCNT0>=OCR0)
break;
}
TCCR0=0;
TCNT0=0;
}
unsigned char ow_reset__(void) // reset lini one wire
{
unsigned char presence=1;
DDRA |= _BV(0); //DQ = 0; //pull DQ line
dl(240);
dl(240);
DDRA &= ~_BV(0); //DQ = 1; // allow line to //powrót lini 1w do trybu wejścia
dl(60);// wait for presence pulse(pochodzący od DS-a) //czekamy na ustab. lini
if(bit_is_clear(PINA,0)) presence=0; //odczytujemy co wystawił na linię DS
dl(200);// wait for end
dl(100);
return(presence); // presence signal
} // 0=presence, 1 = no part
unsigned char test(void) // test na oecnosc DALLASA
{
//LCD_xy(0,0); write_text(" TESTUJEMY ");
//_delay_ms(200);
//_delay_ms(200);
if (ow_reset__()==1)
{
LCD_xy(0,1); write_text("BRAK CZUJNIKA");
_delay_ms(200);
_delay_ms(200);
}
_delay_ms(200);
_delay_ms(200);
return 0;
}
//===========================================================================================//
//===========================================================================================//
unsigned char ow_reset(void) // reset lini one wire
{
unsigned char presence=1;
DDRA |= _BV(0); //DQ = 0; //pull DQ line
dl(240);
dl(240);
DDRA &= ~_BV(0); //DQ = 1; //powrót lini 1w do trybu wejścia
dl(64);// wait for presence pulse(pochodzący od DS-a) //czekamy na ustab. lini
if(bit_is_clear(PINA,0)) presence=0; //odczytujemy co wystawił na linię DS
dl(255);// wait for end
return(presence); // presence signal
} // 0=presence, 1 = no part
///---------------------------------------------------------
// READ_BIT - reads a bit from the one-wire bus. The delay
// required for a read is 15us, so the DELAY routine won't work.
// We put our own delay function in this routine in the form of a
// for() loop.
unsigned char read_bit(void)
{
unsigned char presence=0;
DDRA |= _BV(0); //DQ = 0; // pull DQ low to start timeslot
dl(2);
DDRA &= ~_BV(0); //DQ = 1; // then return high
dl(14); // delay 15us from start of timeslot
if(bit_is_clear(PINA,0)) presence=0;
if(bit_is_set(PINA,0)) presence=1;
return(presence); // return value of DQ line
}
///---------------------------------------------------------
void write_bit(char bitval) //WRITE_BIT - writes a bit to the one-wire bus, passed in bitval.
{
DDRA |= _BV(0); //DQ = 0; // pull DQ low to start timeslot
dl(2);
if(bitval==1) DDRA &= ~_BV(0); //DQ =1; // return DQ high if write 1
dl(104); // hold value for remainder of timeslot - delay 104us
DDRA &= ~_BV(0);//DQ = 1;
}
///---------------------------------------------------------
unsigned char read_byte(void) // READ_BYTE - reads a byte from the one-wire bus
{
unsigned char i;
unsigned char value = 0;
for (i=0;i<8;i++)
{
if(read_bit()) value|=0x01<<i; // reads byte in, one byte at a time and then
dl(120); // ??shifts it left wait for rest of timeslot 120us
}
return(value);
}
///---------------------------------------------------------
void write_byte(char val) // WRITE_BYTE - writes a byte to the one-wire bus.
{
unsigned char i;
unsigned char temp;
for (i=0; i<8; i++) // writes byte, one bit at a time
{
temp = val>>i; // shifts val right 'i' spaces
temp &= 0x01; // copy that bit to temp
write_bit(temp); // write bit in temp into
}
dl(104);
}
//---------------------------------------------------------
void Read_Temperature(void)
{
//char tmp[10];
char temp_lsbyte; //temp_msbyte;
//int k;
test();
write_byte(0xCC); //Skip ROM
write_byte(0x44); // Start Conversion
dl(120);
ow_reset();
write_byte(0xCC); // Skip ROM
write_byte(0xBE); // Read Scratch Pad
ds.nds[0]=read_byte();
ds.nds[1]=read_byte();
LCD_xy(0,1);
itoa(ds.tds/2,buf,10);//temper. całkowita
write_text("Temp: ");
write_text(buf);
write_text(".\0");
itoa(abs((ds.tds*10/16)%10),buf,10); //części dziesiętne
write_text(buf);
write_text(" C");
/*void Read_Temperature(void)
{
char get[10];
char temp_lsb,temp_msb;
int k;
char temp_f,temp_c;
ow_reset();
write_byte(0xCC); //Skip ROM
write_byte(0x44); // Start Conversion
delay(5);
ow_reset();
write_byte(0xCC); // Skip ROM
write_byte(0xBE); // Read Scratch Pad
for (k=0;k<9;k++){get[k]=read_byte();}
printf("\n ScratchPAD DATA = %X%X%X%X%X\n",get[8],get[7],get[6],get[5],get[4],get[3],get[2],get[1],get[0]);
temp_msb = get[1]; // Sign byte + lsbit
temp_lsb = get[0]; // Temp data plus lsb
if (temp_msb <= 0x80){temp_lsb = (temp_lsb/2);} // shift to get whole degree
temp_msb = temp_msb & 0x80; // mask all but the sign bit
if (temp_msb >= 0x80) {temp_lsb = (~temp_lsb)+1;} // twos complement
if (temp_msb >= 0x80) {temp_lsb = (temp_lsb/2);}// shift to get whole degree
if (temp_msb >= 0x80) {temp_lsb = ((-1)*temp_lsb);} // add sign bit
printf( "\nTempC= %d degrees C\n", (int)temp_lsb ); // print temp. C
temp_c = temp_lsb; // ready for conversion to Fahrenheit
temp_f = (((int)temp_c)* 9)/5 + 32;
printf( "\nTempF= %d degrees F\n", (int)temp_f ); // print temp. F
}*/
/*
lcdxy(0,0);
// for (k=0;k<9;k++){tmp[k]=read_byte();}
read_byte();
//printf("DAT=%X%X%X%X%X",tmp[8],tmp[7],tmp[6],tmp[5],tmp[4],tmp[3],tmp[2],tmp[1],tmp[0]);
itoa(tmp[8],buf,10);//temper. całkowita
LCD_xy(0,0); write_text(buf);
itoa(tmp[7],buf,10);//temper. całkowita
LCD_xy(2,0); write_text(buf);
itoa(tmp[6],buf,10);//temper. całkowita
LCD_xy(4,0); write_text(buf);
itoa(tmp[5],buf,10);//temper. całkowita
LCD_xy(6,0); write_text(buf);
itoa(tmp[4],buf,10);//temper. całkowita
LCD_xy(8,0); write_text(buf);
itoa(tmp[3],buf,10);//temper. całkowita
LCD_xy(10,0); write_text(buf);
itoa(tmp[2],buf,10);//temper. całkowita
LCD_xy(12,0); write_text(buf);
itoa(tmp[1],buf,10);//temper. całkowita
LCD_xy(14,0); write_text(buf);
itoa(tmp[0],buf,10);//temper. całkowita
LCD_xy(16,0); write_text(buf);
*/
/*
temp_msbyte = tmp[1]; // Sign byte + lsbit
temp_lsbyte = tmp[0]; // Temp data plus lsb
if (temp_msbyte <= 0x80){temp_lsbyte = (temp_lsbyte/2);} // shift to tmp whole degree
temp_msbyte = temp_msbyte & 0x80; // mask all but the sign bit
if (temp_msbyte >= 0x80) {temp_lsbyte = (~temp_lsbyte)+1;} // twos complement
if (temp_msbyte >= 0x80) {temp_lsbyte = (temp_lsbyte/2);}// shift to tmp whole degree
if (temp_msbyte >= 0x80) {temp_lsbyte = ((-1)*temp_lsbyte);} // add sign bit
*/
//printf( "TempC=%d C", (int)temp_lsbyte ); // print temp. C
temperature=temp_lsbyte;
}
//===========================================================================================//
//===========================================================================================//
int main (void)
{
dl(64);
dl(25);
lcd_init();
LCD_clr();
DDRB=0x00;
PORTB=0x00;
write_byte(0xCC);
while(1)
{
Read_Temperature();
_delay_ms(155);
_delay_ms(155);
_delay_ms(155);
_delay_ms(155);
}
}