Witam! //pierwszy post na forum, pierwsze poważne starcie z AVR
Skonstruowałem następujący układ do pomiaru temperatury z dokładnością do jedności (st. Celsiusza):
- ATMEGA8
- Sensor DS18B20
- Podwójny wyświetlacz siedmiosegmentowy; ot z rodziny takich: http://www.goldmine-elec-products.com/images/G17024B.jpg
Wszystko działa dobrze (o tym za moment). Wyświetlacz jest poprawnie multipleksowany (obie cyfry wyświetlają się dobrze), sensor pobiera poprawną temperaturę.
Wyświetlacz LED jest multipleksowany timerem o częstych przerwaniach (kilkadziesiąt Hz). Temperatura jest aktualizowana z sensora w timerze o długim czasie trwania (przerwanie co kilka sekund).
Problem:
W momencie, gdy uC wpada w przerwanie, które aktualizuje temperaturę, wyświetlacz przestaje się multipleksować (wyświetla jedną cyfrę). Trwa to ~0.5s. I wygląda brzydko (!), a potem wraca do normy na kolejny cykl. Jeśli jednak tylko rzucić okiem np. na YouTube, wiele filmów przedstawia taki sam układ, który działa "płynnie" (aktualizacja temperatury nie niszczy multipleksacji).
Gdzie tkwi mój błąd (leży pewnie w założeniach timerów wyświetlacza oraz sensora, lecz nie mogę go odnaleźć)?
Kod głównego pliku programu (jak już wspomniałem - wyświetlacz oraz sensor działają poprawnie - problem tkwi w synchronizacji obydwu procesów):
Dziękuję za pomoc!
Pozdrawiam!
Skonstruowałem następujący układ do pomiaru temperatury z dokładnością do jedności (st. Celsiusza):
- ATMEGA8
- Sensor DS18B20
- Podwójny wyświetlacz siedmiosegmentowy; ot z rodziny takich: http://www.goldmine-elec-products.com/images/G17024B.jpg
Wszystko działa dobrze (o tym za moment). Wyświetlacz jest poprawnie multipleksowany (obie cyfry wyświetlają się dobrze), sensor pobiera poprawną temperaturę.
Wyświetlacz LED jest multipleksowany timerem o częstych przerwaniach (kilkadziesiąt Hz). Temperatura jest aktualizowana z sensora w timerze o długim czasie trwania (przerwanie co kilka sekund).
Problem:
W momencie, gdy uC wpada w przerwanie, które aktualizuje temperaturę, wyświetlacz przestaje się multipleksować (wyświetla jedną cyfrę). Trwa to ~0.5s. I wygląda brzydko (!), a potem wraca do normy na kolejny cykl. Jeśli jednak tylko rzucić okiem np. na YouTube, wiele filmów przedstawia taki sam układ, który działa "płynnie" (aktualizacja temperatury nie niszczy multipleksacji).
Gdzie tkwi mój błąd (leży pewnie w założeniach timerów wyświetlacza oraz sensora, lecz nie mogę go odnaleźć)?
Kod głównego pliku programu (jak już wspomniałem - wyświetlacz oraz sensor działają poprawnie - problem tkwi w synchronizacji obydwu procesów):
#include <stdlib.h>
#include <avr/io.h>
#include <stdio.h>
#include <avr/interrupt.h>
#include <compat/ina90.h>
#include "dualDisplay.h"
#include "ds18b20.h"
char temp[20] = "00";
// SENSOR TIMER EVENT
ISR(TIMER1_COMPA_vect)
{
therm_read_temperature(temp);
}
// LED MULTIPLEX TIMER EVENT
ISR(TIMER0_OVF_vect)
{
showDigit(-1);
if(PORTB == _BV(0)) {
showDigit((int)(atoi(temp)/10));
PORTB |= _BV(1);
PORTB &= ~_BV(0);
}
else {
showDigit((int)(atoi(temp)%10));
PORTB |= _BV(0);
PORTB &= ~_BV(1);
}
}
void sensorTimerOn()
{
TCCR1B |= (1 << CS12) | (1 << CS10);
}
void ledMultiplexTimerOn()
{
TCCR0 |= (1 << CS01);
TCNT0 = 0x00;
}
int main()
{
DDRD |= 0xff; //LCD
DDRB |= (_BV(0) | _BV(1)); // LED DISPLAY
therm_read_temperature(temp); // FIRST READING
sensorTimerOn();
ledMultiplexTimerOn();
TIMSK = (1 << TOIE0) | (1 << OCIE1A); // ENABLE TIMERS
sei();
for(;;) {}
return 0;
}Dziękuję za pomoc!
Pozdrawiam!