Witam! Zrobiłem sobie termostat i wszystko ładnie po podłączałem oraz oprogramowałem. Jest jednak jeden problem: chce sobie zrobić podmenu (ustawianie histerezy). Na początek tworzenia w/w podmenu chciałem sprawdzić, czy są wciśnięta oba przyciski, a nastepnie wyczyścić wyświetlacz i wypisać aktualną temperaturę. Problem jest jednak taki, że wszystko działa, gdy przekaźnik jest wyłączony (sterowanie przez BD649, bramka przez 10k na pin uC; wg. noty prąd pobierany przez przekaźnik niecałe 50mA), natomiast gdy przy włączonym przekaźniku spróbujemy wyczyścić wyśw. i wejść do podmenu to wszystko sie sypie z nieznanego mi bliżej powodu.
Zamieszczam kod. Może ma ktoś jakiś pomysł?
Procedury wyświetlacza i temrometru są od autora kursu C na diodzie - abxyz
Zamieszczam kod. Może ma ktoś jakiś pomysł?
Procedury wyświetlacza i temrometru są od autora kursu C na diodzie - abxyz
/*
Plik "main.c"
*/
#include <stdio.h>
#include <avr/io.h>
#include <util/delay.h>
#include "hd44780.h"
#include "ds18b20.h"
#define SET_PRZ PORTB |= _BV(PB7)
#define CLR_PRZ PORTB &= ~_BV(PB7)
/* Zmienna przechowuje aktualną wartość temperatury */
double temp;
/* W tablicy będą formowane komunikaty tekstowe
wysyłane do wyświetlacza */
char str[7];
char str2[7];
double ust = 23;
double hist= 0;
char tem[6]="Temp:";
char zad[8]="Zadana:";
char test[8]="podmenu";
int z;
void klawiatura (void)
{
if (!(PIND & _BV(PD5))) //
{
_delay_ms(70);
if (!(PIND & _BV(PD6))) //
{
LCD_CLEAR;
LCD_LOCATE(0,0);
/* Wysyła komunikat do wyświetlacza */
lcd_puts(str);
_delay_ms(100);
}
ust=ust+1;
_delay_ms(150);
}
else if (!(PIND & _BV(PD6))) //
{
if (!(PIND & _BV(PD5))) //
{
LCD_CLEAR;
LCD_LOCATE(0,0);
/* Wysyła komunikat do wyświetlacza */
lcd_puts(str);
_delay_ms(1000);
}
ust=ust-1;
_delay_ms(150);
}
else
{
LCD_CLEAR;
/* Formułuje komunikat w tablicy 'str' */
sprintf(str,"%4.1f\xdf""C", temp);
sprintf(str2,"%4.1f\xdf""C", ust);
LCD_LOCATE(0,0);
/* Wysyła komunikat do wyświetlacza */
lcd_puts(tem);
LCD_LOCATE(9,0);
lcd_puts(str);
LCD_LOCATE(0,1);
lcd_puts(zad);
LCD_LOCATE(9,1);
lcd_puts(str2);
}
for (z=0; z<10 ;z++) // pauza po przyciśnięciu klawisza
{ asm ("nop") ;}
}
void start (void)
{
/* Czyści ekran */
LCD_CLEAR;
LCD_LOCATE(0,0);
/* Wysyła komunikat do wyświetlacza */
lcd_puts(tem);
LCD_LOCATE(0,1);
lcd_puts(zad);
}
void histereza (void)
{
LCD_CLEAR;
LCD_LOCATE(0,0);
/* Wysyła komunikat do wyświetlacza */
lcd_puts(str);
_delay_ms(1000);
}
int main(void)
{
DDRD = 0x60;
PORTD = 0x60;
DDRB |= _BV(PB7);
/* W tablicy zapisywane będą dane odczytane z układu ds18b20 */
unsigned char ds18b20_pad[9];
/* Funkcja inicjalizuje wyświetlacz */
lcd_init();
/* Włącza wyświetlanie */
LCD_DISPLAY(LCDDISPLAY);
while(1)
{
/* Funkcja 'ds18b20_ConvertT' wysyła do układu ds18b20
polecenie pomiaru */
if(ds18b20_ConvertT())
{
/* Odczyt z układu ds18b20, dane zapisywane są w tablicy ds18b20_pad.
Dwie pierwsze pozycje w tablicy to kolejno mniej znaczący bajt i bardziej
znaczący bajt wartość zmierzonej temperatury */
ds18b20_Read(ds18b20_pad);
/* Składa dwa bajty wyniku pomiaru w całość. Cztery pierwsze bity mniej
znaczącego bajtu to część ułamkowa wartości temperatury, więc całość
dzielona jest przez 16 */
temp = ((ds18b20_pad[1] << 8) + ds18b20_pad[0]) / 16.0 ;
if(temp<ust-hist){
CLR_PRZ;
}
else if(temp>ust+hist){
SET_PRZ;
}
klawiatura();
}
}
}
