Witam wszystkich i na początku proszę o wyrozumiałość bo to mój pierwszy post na elektrodzie.
Zbudowałem układ do pomiary temperatury z wykorzystaniem atmegi8 i czujnika temperatury ds1820. Wynik wyświetlany jest na 4 wyświetlaczach 7-segmentowych. Program napisałem w języku C (obsługę 1-wire zaczerpnąłem z mikrokontrolery.net) Wszystko działa jak należy z wyjątkiem wyświetlania.
W programie przy odczytywaniu i zapisie bitów z na linii DQ wyłączane są przerwania obsługujące wyświetlanie co powoduje widoczne miganie wyświetlaczy. Nie potrafię sobie z tym poradzić proszę więc o wskazówki do ww problemu oraz konstruktywne uwagi do kodu.
Zbudowałem układ do pomiary temperatury z wykorzystaniem atmegi8 i czujnika temperatury ds1820. Wynik wyświetlany jest na 4 wyświetlaczach 7-segmentowych. Program napisałem w języku C (obsługę 1-wire zaczerpnąłem z mikrokontrolery.net) Wszystko działa jak należy z wyjątkiem wyświetlania.
W programie przy odczytywaniu i zapisie bitów z na linii DQ wyłączane są przerwania obsługujące wyświetlanie co powoduje widoczne miganie wyświetlaczy. Nie potrafię sobie z tym poradzić proszę więc o wskazówki do ww problemu oraz konstruktywne uwagi do kodu.
#include <avr/io.h>
#include <avr/delay.h>
#include <avr/interrupt.h>
#define DQ 5
#define SET_DQ DDRD &= ~_BV(DQ)
#define CLR_DQ DDRD |= _BV(DQ)
#define IN_DQ PIND & _BV(DQ)
char cyfry[10] = {192,249,164,176,153,146,130,248,128,144};
unsigned char t0, t1, t2, t3;
short int dl=0;
unsigned char msb, lsb;
void Inicjalizacja_portow(void)
{
DDRB = 0xFF;
PORTB = 0xFF;
DDRC = 0xFF;
PORTC = 0xFF;
}
void Inicjalizacja_timer2(void)
{
TIMSK = _BV(TOIE2); // wł±cz obsługę przerwań T/C0
//TIMSK =0x41;
TCNT2 = 0; // warto¶ć pocz±tkowa T/C0
TCCR2 = 0x02; // preskaler 8
sei(); //wł±cz globaln± obsługę przerwań
}
void delay(unsigned char t)
{
do{asm("nop");}while(--t);
}
//******************************************************************************
//****************** one wire **************************************************
//******************************************************************************
void ow_reset(void) // procedura reset
{
CLR_DQ; // stan niski na linii 1wire
delay(255); //
delay(119); // opóźnienie ok 480us
//delay(1);
SET_DQ;// stan wysoki na linii 1wire
delay(255); //
delay(119); // opóźnienie ok 480 us
}
// procedura zapisu bitu na linię 1wire
void ow_write_bit(char b)
{
cli(); // zablokowanie przerwań
CLR_DQ; // stan niski na linii 1wire
delay(7); //7 opóźnienie 10us
if(b) SET_DQ; // jeśli parametr jest niezerowy to ustaw stan wysoki na linii
delay(80); //80 opóźnienie 100us
SET_DQ; // stan wysoki na linii 1wire
sei(); // odblokowanie pzrerwań
}
char ow_read_bit(void)
{
cli();
CLR_DQ;
delay(1);
SET_DQ;
delay(11);//11
if(IN_DQ) return 1; else return 0;
sei();
}
unsigned char ow_read_byte(void)
{
unsigned char i;
unsigned char value = 0;
for (i=0;i<8;i++)
{
if(ow_read_bit()) value|=0x01<<i;
delay(6);
}
return(value);
}
void ow_write_byte(char val)
{
unsigned char i;
unsigned char temp;
for (i=0; i<8; i++)
{
temp = val >> i;
temp &= 0x01;
ow_write_bit(temp);
}
delay(5);
}
void komunikacja(void)
{
ow_reset(); //inicjalizacja przez Master ł±czno¶ci z ds1820
ow_write_byte(0xCC); //pomiń sprawdzanie adresu (przeskocz ROM)
ow_write_byte(0x44); //inicjalizacja pomioru temperatury
_delay_ms(250); //przy zasilaniu tylko DQ 500ms
//_delay_ms(250); //przy zasilaniu VDD czas do zakończenia
//_delay_ms(250); //cyklu pomiarowego
ow_reset(); //ponowna inicjalizacja
ow_write_byte(0xCC); //pomiń sprawdzanie adresu (przeskocz ROM)
ow_write_byte(0xBE); //odczyt pamięci podręcznej
lsb = ow_read_byte();
msb = ow_read_byte();
}
void przeliczanie(void)
{
if (msb > 0)
{
lsb=~lsb;
lsb++;
t0=3;
t1=(lsb/2)/10;
t2=(lsb/2)%10;
if(lsb%2==0)
t3=0;
else
t3=5;
}
else
{
t0=(lsb/2)/100;
if(lsb<200)
t1=(lsb/2)/10;
if(lsb>=200)
t1=(lsb/200);
t2=(lsb/2)%10;
if(lsb%2==0)
t3=0;
else
t3=5;
}
}
SIGNAL (SIG_OVERFLOW2)
//ISR (TIMER2_OVF_vect) // to samo nowszy zapis
{
dl++;
if(dl<=5)
{
PORTC |= _BV(1);
PORTC |= _BV(2);
PORTC |= _BV(3);
PORTB = cyfry[t3];
PORTC = ~_BV(0);
}
if ((dl>=5)&&(dl<=10))
{
PORTC |= _BV(0);
PORTC |= _BV(2);
PORTC |= _BV(3);
PORTB = (cyfry[t2]) & 0x7f; // & 0x7f - dodanie kropki
PORTC &= ~_BV(1);
}
if((dl>=10)&&(dl<=15))
{
PORTC |= _BV(1);
PORTC |= _BV(0);
PORTC |= _BV(3);
PORTB = cyfry[t1];
PORTC &= ~_BV(2);
}
if((dl>=15)&&(dl<=20)&&(t0!=0))
{
PORTC |= _BV(1);
PORTC |= _BV(2);
PORTC |= _BV(0);
if (msb > 0)
PORTB = 0xBF;
else
PORTB = cyfry[t0];
PORTC &= ~_BV(3);
}
if( (dl==15) && (t0==0) )
dl=0;
else if (dl==20) dl=0;
}
int main(void)
{
Inicjalizacja_portow();
Inicjalizacja_timer2();
while(1)
{
komunikacja();
przeliczanie();
}
return 0;
}