Ponizej przedstawiam swoj kod:
lcd.h
usart.h
Problem jest taki: po odpaleniu urzadzenia pokazuja sie napisy, ktore sa w funkcji main() i one nigdy nie znikaja. Problemem jest to, ze w funkcji glowne() robi sie pomiar i co sekunde ten pomiar ma sie wyswietlac. No i ten pomiar sie wyswietla na ulamek sekundy po czym znika. Metoda prob i bledow okazalo sie, ze wylaczenie wysylania temperatury na usart USART_Transmit() powoduje zaprzestania znikania tych danych. Zmienialem polozenie tej funkcji, zmienilem Timer2 na 0, nawet wyrzucilem timer i zostawilem tylko opoznienie na delay - nic nie pomoglo. Czy ktos moglby mi podpowiedziec gdzie jest, zapewne glupi, blad? Niedlugo musze prace oddac na obrone ...
#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>
#include <avr/interrupt.h>
//#include <avr/iom16.h>
#include "lcd.h"
#include "usart.h"
#define Timer2_start TCNT2 = 0x63; TCCR2 = 0x07; //0x63 - poczatkowa 99, preskaler 1024 0x07
#define Timer2_stop TCCR2 = 0;
unsigned short int sekunda=0, napiecie, temperatura, zadana, int_byte[3]; //0-65535
unsigned char tekstA[3], tekstB[4], tekstC[3], histereza=0, x=0, Bufor;
unsigned char byte[4], y;
int read_adc(void)
{
ADMUX=0xC0; //VRef = 2,56V - ADC0 jako input
ADCSRA = 0x87; // zezwolenie na konwersje, preskaler 128
ADCSRA |= 1<<ADSC; //start pojedynczej konwersji
while(bit_is_set(ADCSRA,ADSC)){};
return ADCW;
}
unsigned char glowne(void)
{
napiecie = read_adc();
itoa(napiecie, tekstB, 10);
temperatura = 0.38*napiecie+2.2;
if(temperatura>=zadana) PORTB = 0x02;
if(temperatura<(zadana-histereza)) PORTB = 0x00;
itoa(temperatura, tekstA, 10);
lcd_xy(0,2);
if(temperatura>99) write_text(tekstA);
if(temperatura>9 & temperatura <100)
{
write_text(tekstA);
lcd_xy(0,4);
write_char(' ');
}
if(temperatura<10)
{
char i;
write_text(tekstA);
for(i=3; i<5; i++)
{
lcd_xy(0,i);
write_char(' ');
}
}
lcd_xy(1,0);
if(napiecie>999) write_text(tekstB);
if(napiecie>99 & napiecie<1000)
{
write_text(tekstB);
lcd_xy(1,3);
write_char(' ');
}
if(napiecie>9 & napiecie<100)
{
char i;
write_text(tekstB);
for(i=2; i<4; i++)
{
lcd_xy(1,i);
write_char(' ');
}
}
if(napiecie<10)
{
char i;
write_text(tekstB);
for(i=1; i<4; i++)
{
lcd_xy(1,i);
write_char(' ');
}
}
asm("nop");
return temperatura;
}
ISR(TIMER0_OVF_vect)
{
TCNT2 = 0x63;
sekunda++;
if(sekunda==100)
{
Timer2_stop;
sekunda=0;
USART_Transmit(glowne());//temperatura);
Timer2_start;
}
}
ISR(SIG_UART_RECV)
{
Bufor = UDR;
if (x<3)
{
byte[x] = Bufor;
x++;
}
byte[3] = 0;
if(x>2)
{
zadana = atoi(byte);
x = 0;
lcd_xy(0,10);
itoa(zadana, tekstC, 10);
write_text(tekstC);
}
}
int main(void) // program główny
{
// konfiguracja portów we/wy
DDRA = 0b11111110; //PortA0 jako wejscie napiecia mierzonego
DDRB = 0x02; //Nozka T1 jako wyjscie
DDRC = 0xFF;
DDRD = 0b11001110; //PORTD0 oraz 4,5 jako wejście
_delay_ms (5);
lcd_init(); //inicjalizacja LCD
USART_Init(MYUBRR);
zadana = 280;
histereza=3;
lcd_xy(0,0);
write_text("B=");
lcd_xy(0,5);
write_text("C");
lcd_xy(0,8);
write_text("Z=");
lcd_xy(0,13);
write_text("C");
lcd_xy(1,8);
write_text("H=3");
sei(); //globalne zezwolenie na przerwania
TIMSK = 0x40; //wlaczamy przerwanie T2
Timer2_start;
lcd_xy(0,10);
itoa(zadana, tekstC, 10);
write_text(tekstC);
for(;;) //petla nieskończona
{
}
return 0;
}
lcd.h
// Definicje dotyczace LCD
#define LCD PORTC //port z LCD
#define RS 0 // wybor rejestru
#define RW 2 // 1 - odczyt; 0 - zapis
#define E 3 // sygnal zezwalajacy (enable)
#define SET_E LCD |= _BV(E)
#define CLR_E LCD &= ~_BV(E)
#define SET_RS LCD |= _BV(RS)
#define CLR_RS LCD &= ~_BV(RS)
#define SET_RW LCD |= _BV(RW)
#define CLR_RW LCD &= ~_BV(RW)
//#define DDRLCD DDRC // port z podlaczanym LCD
//#define PINLCD PINC // port z podlaczanym LCD
// Wykorzystujemy tylko cztery linie przesylowe D4-D7 portu PORTLCD
// pcodedura zapisu bajtu do wyświetlacza LCD
// bez rozróżnienia instrukcja/dana
void write_to_lcd(char x)
{
SET_E; // ustaw na E stan wysoki
LCD = ((LCD & 0x0F) | (x & 0xF0)); // zapis pierwszej połówki bajtu
CLR_E; // opadające zbocze na E -> zapis do wyświetlacza
asm("nop");
SET_E; // ustaw na E stan wysoki
LCD = ((LCD & 0x0F) | ((x & 0x0F) << 4)); // zapis drugiej połowki bajtu
CLR_E; // opadające zbocze na E -> zapis do wyświetlacza
_delay_ms(1); // czekaj 1ms
}
// ***************** procedura zapisu instrukcji do wyświetlacza LCD
void write_command(char x)
{
CLR_RS; // niski stan na RS -> zapis instrukcji
write_to_lcd(x); // zapis do LCD
}
//***************** procedura zapisu danej do wyświetlacza LCD
void write_char(char x)
{
SET_RS; // wysoki stan na RS -> zapis danej
write_to_lcd(x); // zapis do LCD
}
// ***************** procedura zapisu tekstu do wyświetlacza LCD
void write_text(char * s)
{
while(*s) // do napotkania 0
{
write_char(*s); // zapisz znak wskazywany przez s na LCD
s++; // zwiększ s (przygotuj nastepny znak)
}
}
// ***************** procedura inicjalizacji wyświetlacza LCD
void lcd_init(void)
{
_delay_ms(50); // czekaj 15ms na ustabilizowanie się napięcia zasilającego
CLR_RW;
CLR_E; // E = 0
CLR_RS; // RS = 0
char i; // zmienna licznikowa
for(i = 0; i < 3; i++) // trzykrotne powtórzenie bloku instrukcji
{
SET_E; // E = 1
LCD &= 0x30; //
CLR_E; // E = 0
_delay_ms(5); // czekaj 5ms
}
SET_E; // E = 1
LCD &= 0x20; //
CLR_E; // E = 0
_delay_ms(1); // czekaj 1ms
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
}
// ***************** procedura ustawiania pozycji kursora
void lcd_xy(unsigned char w, unsigned char k)
{
write_command((w*0x40+k) | 0x80);
}
usart.h
#define FOSC 16000000UL
#define BAUD 19200UL
#define MYUBRR (FOSC/(16*BAUD))-1
unsigned char data[2], i;
void USART_Init( unsigned int ubrr )
{
UBRRH = (unsigned char)(ubrr>>8); // Set baud rate
UBRRL = (unsigned char)ubrr;
UCSRA = 0x00; //
UCSRB = 0b11011000; //(1 << RXCIE) | (1<<RXEN) | (1<<TXEN);
UCSRC = 0b10000110; // Set frame format: 8data, 1stop bit, parity=none
}
void USART_Transmit(unsigned int dana)
{
if(dana>255)
{
data[0] = 255;
data[1] = dana-255;
}
else
{
data[0] = 0;
data[1] = dana;
}
for(i=0; i<2; i++)
{
while (!(UCSRA & (1<<UDRE))); //Czekaj na pusty bufor transmisji
UDR = data[i]; // Put data into buffer, sends the data
}
}
Problem jest taki: po odpaleniu urzadzenia pokazuja sie napisy, ktore sa w funkcji main() i one nigdy nie znikaja. Problemem jest to, ze w funkcji glowne() robi sie pomiar i co sekunde ten pomiar ma sie wyswietlac. No i ten pomiar sie wyswietla na ulamek sekundy po czym znika. Metoda prob i bledow okazalo sie, ze wylaczenie wysylania temperatury na usart USART_Transmit() powoduje zaprzestania znikania tych danych. Zmienialem polozenie tej funkcji, zmienilem Timer2 na 0, nawet wyrzucilem timer i zostawilem tylko opoznienie na delay - nic nie pomoglo. Czy ktos moglby mi podpowiedziec gdzie jest, zapewne glupi, blad? Niedlugo musze prace oddac na obrone ...