Jestem w trakcie tworzenia softu dla mojego urządzonka (sterownik wentylatorow komputera bardziej zaawansowana wersja
Próbowałem uruchomić wyświetlacz zgodnie z kursem z EDW 12/2005 lecz niestety nie działa. Wyświetlacz jest na pewno sprawny, ponieważ aby sprawdzić czy urządzenie działa napisałem program w BASCOMIE sprawdzający wszystkie moje założenia.
Oto program:
Plik główny:
Kod: Zaznacz cały
#include <avr\io.h>
#include <inttypes.h>
#include <avr\pgmspace.h>
#include "hardware.h"
#include "lcd_komendy.h"
#include "makra.h"
//--------------------------------------------------
// Generowanie opóźnień
#define delay250ns() {asm volatile("nop"::);}
#define delayus8(t)\
{asm volatile( \
"delayus8_loop%=: \n\t"\
"nop \n\t"\
"dec %[ticks] \n\t"\
"brne delayus8_loop%= \n\t"\
: :[ticks]"r"(t) );}
// DEC - 1 cykl, BRNE 2 cykle, + 1xnop. Zegar 4MHz
void delay100us8(uint8_t t)
{
while(t>0)
{
delayus8(100);
--t;
}
}
// Koniec opóźnień
//--------------------------------------------------
#define LCD_EPULSE() \
{PORT(LCD_EPORT) |= 1<<LCD_E; \
delay250ns(); \
PORT(LCD_EPORT) &= ~(1<<LCD_E);}
void LCDsendHalf(uint8_t data)
{
data = (data & 0x0F) << LCD_D4;
//data |= 0xF0;
//data &= 0x0F;
//data <<= LCD_D4;
PORT(LCD_DPORT) =
(PORT(LCD_DPORT) & ~(0x0F<<LCD_D4)) | data;
//PORT(LCD_DPORT) &= ~(0x0F<<LCD_D4);
//PORT(LCD_DPORT) |= data;
LCD_EPULSE();
}
void LCDsend(uint8_t data)
{
// Starsza część
LCDsendHalf(data>>4);
// Młodsza część
LCDsendHalf(data);
delayus8(120);
}
// Funkcje interfejsu
void LCDcommand(uint8_t command)
{
PORT(LCD_RSPORT) &= ~(1<<LCD_RS);
LCDsend(command);
}
void LCDdata(uint8_t data)
{
PORT(LCD_RSPORT) |= 1<<LCD_RS;
LCDsend(data);
}
void LCDcls(void)
{
LCDcommand(LCDC_CLS);
delay100us8(48);
}
void LCDhome(void)
{
LCDcommand(LCDC_HOME);
delay100us8(48);
}
void LCDinit(void)
{
delay100us8(150);
PORT(LCD_RSPORT) &= ~(1<<LCD_RS);
LCDsendHalf(LCDC_FUNC|LCDC_FUNC8b);
delay100us8(41);
LCDsendHalf(LCDC_FUNC|LCDC_FUNC8b);
delay100us8(2);
LCDsendHalf(LCDC_FUNC|LCDC_FUNC4b);
delay100us8(2);
// Teraz jest już 4b. Koniec korzystania z sendHalf
LCDcommand(LCDC_FUNC|LCDC_FUNC4b|LCDC_FUNC2L|LCDC_FUNC5x7);
LCDcommand(LCDC_ON);
LCDcls();
LCDcommand(LCDC_MODE|LCDC_MODER);
LCDcommand(LCDC_ON|LCDC_ONDISPLAY|LCDC_ONCURSOR);
}
void LCDstr_P(prog_char* str)
{
char znak;
while( 0 != (znak = pgm_read_byte(str++)) )
LCDdata(znak);
}
// Koniec obsługi wyświetlacza
//--------------------------------------------------
//prog_char g_napispgm[] = "Lancuch z FLASHa"; // globalna
// START
int main(void)
{
//----------------------------------------------
// Inicjacja - uwaga: uproszczona, może wymagać
// zmian przy zmianie przyporządkowania portów
DDR(LCD_DPORT) = 1<<LCD_E | 1<<LCD_RS | 1<<LCD_D4 | 1<<LCD_D5 | 1<<LCD_D6 |1<<LCD_D7;
LCDinit();
// Koniec inicjacji
//----------------------------------------------
// \/ Bez tego, czasami zerowanie z poziomu programatora
// \/ powoduje śmieci na wyświetlaczu.
LCDcls();
LCDstr_P(/*(prog_char*)*/PSTR("Witaj!"));
LCDcommand(LCDC_DDA|64);
LCDstr_P((prog_char*)PSTR("Lancuch z FLASHa"));
//LCDstr_P(g_napispgm);
return 0;
}
Kod: Zaznacz cały
#ifndef HARDWARE_H_
#define HARDWARE_H_
// USTAWIENIA PORTÓW
// LCD
#define LCD_RS 1
#define LCD_RSPORT D
#define LCD_E 0
#define LCD_EPORT D
#define LCD_DPORT D
#define LCD_D4 5
#define LCD_D5 3
#define LCD_D6 4
#define LCD_D7 2
// SW
#define SW1_SW1 0
#define SW1_SW1PORT B
#define SW_SW2 7
#define SW_SW3 6
#define SW_SWPORT D
// PWM OUT
#define PWM_PWMPORT C
#define PWM_PWM1 5
#define PWM_PWM2 4
#define PWM_PWM3 3
#define PWM_PWM4 2
// RPM
#define RPM_RPMPORT C
#define RPM_RMP1 1
#define RPM_RMP2 0
// 1WIRE
#define DS18B20_1WIREPORT B
#define DS18B20_1WIRE 2
#endif /* HARDWARE_H_ */
Kod: Zaznacz cały
#ifndef MAKRA_H_
#define MAKRA_H_
// Makra upraszczające dostęp do portów
// *** Port
#define PORT(x) XPORT(x)
#define XPORT(x) (PORT##x)
// *** Pin
#define PIN(x) XPIN(x)
#define XPIN(x) (PIN##x)
// *** DDR
#define DDR(x) XDDR(x)
#define XDDR(x) (DDR##x)
#endif /* MAKRA_H_ */
Kod: Zaznacz cały
#ifndef LCD_KOMENDY_H_
#define LCD_KOMENDY_H_
// Komendy sterujące wyświetlaczem
#define LCDC_CLS 0x01
#define LCDC_HOME 0x02
#define LCDC_MODE 0x04
#define LCDC_MODER 0x02
#define LCDC_MODEL 0
#define LCDC_MODEMOVE 0x01
#define LCDC_ON 0x08
#define LCDC_ONDISPLAY 0x04
#define LCDC_ONCURSOR 0x02
#define LCDC_ONBLINK 0x01
#define LCDC_SHIFT 0x10
#define LCDC_SHIFTDISP 0x08
#define LCDC_SHIFTR 0x04
#define LCDC_SHIFTL 0
#define LCDC_FUNC 0x20
#define LCDC_FUNC8b 0x10
#define LCDC_FUNC4b 0
#define LCDC_FUNC2L 0x08
#define LCDC_FUNC1L 0
#define LCDC_FUNC5x10 0x4
#define LCDC_FUNC5x7 0
#define LCDC_CGA 0x40
#define LCDC_DDA 0x80
#endif
Na wyświetlaczu pojawiają mi się krzaczki tylko w pierwszej linii.
Na początku popełniłem błąd bo atmega8 pracowała na 12MHz wiec zmieniłem jej zegar na wewnętrzny 4Mhz aby opóźnienia się zgadzały lecz to nie pomogło.
Próbowałem uruchomić też inne dostępne biblioteki do obsługi lcd. Albo nie działało, albo się nie kompilowało albo były krzaczki.
Proszę o pomoc
[ Dodano: 2009-05-16, 22:00 ]
nikt nie jest w stanie mi pomoc rozwiązać ten problem?