Dumma LCD, HJÄLP!
Jo..
Var ute och testade med en lysdiod på pinnarna, vet inte vad som har hänt men det här kom jag fram till:
Enable är helatiden låg.
Data pinnarna beter sig inte som dom ska, om man i programmet skriver
11111111 till data pinnarna så blir det 00x01100 x varierar , iblan 0 iblan 1.
RA4 är bortkopplad. Men RA6 beter sig ochså konstigt, ligger helatiden hög.
Har inte testat med en annan PIC för om man byter till ett program som bara tex slår på E så fungerar det.
Nuvarande kod: http://www.dybeck.eu/testlcd.c
Var ute och testade med en lysdiod på pinnarna, vet inte vad som har hänt men det här kom jag fram till:
Enable är helatiden låg.
Data pinnarna beter sig inte som dom ska, om man i programmet skriver
11111111 till data pinnarna så blir det 00x01100 x varierar , iblan 0 iblan 1.
RA4 är bortkopplad. Men RA6 beter sig ochså konstigt, ligger helatiden hög.
Har inte testat med en annan PIC för om man byter till ett program som bara tex slår på E så fungerar det.
Nuvarande kod: http://www.dybeck.eu/testlcd.c
> CM0=1; CM1=1; CM2=1; CM3=1;
Du är fortfarande säker på att det där är rätt (eller i alla fall fungerar) ?
Kan du se i LST filen vilken assembler kod som genereras ?
> om man i programmet skriver 11111111 till data pinnarna...
*Hur* skrivr du det till pinnarna ?
Hela porten på en gång eller pinne för pinne ?
Om det är pinne för pinne, så kan du ha råkat ut för
ett problem som kallas "read-modify-write". Prova att
lägga en lite delay skrivningen till varje pinne, det räcker med
1-2 nop().
Men jag skulle först kolla att komparatorerna verkligen
är avstängda...
Du är fortfarande säker på att det där är rätt (eller i alla fall fungerar) ?
Kan du se i LST filen vilken assembler kod som genereras ?
> om man i programmet skriver 11111111 till data pinnarna...
*Hur* skrivr du det till pinnarna ?
Hela porten på en gång eller pinne för pinne ?
Om det är pinne för pinne, så kan du ha råkat ut för
ett problem som kallas "read-modify-write". Prova att
lägga en lite delay skrivningen till varje pinne, det räcker med
1-2 nop().
Men jag skulle först kolla att komparatorerna verkligen
är avstängda...
Har nu testat ännu mer, lade in 3st NOP mellan skrivningarna men det blev ingen skillnad...
När det gäller comparatorerna så försökte jag med JimmyAnderssons:
Gjorde ingen skillnad, testade en egen:
men det fungerade inte heller, eller rättare sagt, det blev ingen skillnad på utdatan.
Någon som vet ett bra sätt att testa om dom är av?
Jag avänder dessa portar:
PORTA.2 och .3 är alltid höga, även innan man har initierat TRISA.
Dom andra är låga, E låg, RS låg.
EDIT: koden ligger alltid här http://www.dybeck.eu/testlcd.c för den som vill kolla.
När det gäller comparatorerna så försökte jag med JimmyAnderssons:
Kod: Markera allt
CMCON, CM0 = 1; CMCON, CM1 = 1; CMCON, CM2 = 1;
Kod: Markera allt
CMCON.0=1; CMCON.1=1; CMCON.2=1;
Någon som vet ett bra sätt att testa om dom är av?
Jag avänder dessa portar:
Kod: Markera allt
#pragma bit RS @ PORTB.5
#pragma bit E @ PORTB.1
#pragma bit D7 @ PORTA.7
#pragma bit D6 @ PORTA.6
#pragma bit D5 @ PORTB.2
#pragma bit D4 @ PORTB.0
#pragma bit D3 @ PORTA.3
#pragma bit D2 @ PORTA.2
#pragma bit D1 @ PORTA.1
#pragma bit D0 @ PORTA.0
Dom andra är låga, E låg, RS låg.
EDIT: koden ligger alltid här http://www.dybeck.eu/testlcd.c för den som vill kolla.
Björn: Nej inga som helst errors
Icecap: dom har fungerat förut, har inte testat #define i PIC samanhang, får väll testa det också!
>Vad är det fel med:
>CMCON = 0x07; ?????
Inget jag har bara inte testat! Måste testas.
Fråga: Nån som har ett färdig komplierat lcd-program för 16F628 som jag kan testa med?
EDIT: en fråga
Icecap: dom har fungerat förut, har inte testat #define i PIC samanhang, får väll testa det också!
>Vad är det fel med:
>CMCON = 0x07; ?????
Inget jag har bara inte testat! Måste testas.
Fråga: Nån som har ett färdig komplierat lcd-program för 16F628 som jag kan testa med?
EDIT: en fråga
sodjans/Icecaps förslag CMCON = 0x07; gav ingen skillnad, PORTA.2 .3 är hela tiden höga oavsätt vad man ställer i programmet.
testade att byta till #define. Kompilatorn klagar inte på det heller men det blir ingen förändring på portarna.
Hur kan jag testa om comparatorerna är av? Mer än att läsa i registret?
testade att byta till #define. Kompilatorn klagar inte på det heller men det blir ingen förändring på portarna.
Hur kan jag testa om comparatorerna är av? Mer än att läsa i registret?
Kollade lite på källkoden och herregud.... vad håller du på med?
Ska du göra det så att det kan fungera kan det vara oerhört mycket bättre att lägga ut datan:
Kod: Markera allt
void lcd_putchar( char data )
{
// must set LCD-mode before calling this function!
// RS = 1 LCD in character-mode
// RS = 0 LCD in command-mode
nop();
nop();
nop();
D7=data.7;
nop();
nop();
nop();
D6=data.6;
nop();
nop();
nop();
D5=data.5;
nop();
nop();
nop();
D4=data.4;
nop();
nop();
nop();
D3=data.3;
nop();
nop();
nop();
D2=data.2;
nop();
nop();
nop();
D1=data.1;
nop();
nop();
nop();
D0=data.0;
delay(5);
E=1;
nop();
nop();
nop();
nop();
E=0;
nop();
nop();
nop();
}
Kod: Markera allt
#define LCD_Data PORTA
#define LCD_Enable PORTB.F1
#define LCD_RS PORTB.F5
void lcd_putchar( char data )
{
// must set LCD-mode before calling this function!
// RS = 1 LCD in character-mode
// RS = 0 LCD in command-mode
LCD_Data = data;
nop();
nop();
LCD_Enable = 1;
nop();
nop();
LCD_Enable = 0;
}
Det såg mycket enklare ut får man ju erkänna...
Men här då?
Först så har jag inte hela PORTA ledig, bla RA.5 och .4 är inte användbara.
>PORTB.F1
>PORTB.F5
Varför F??
Micke_s: Slösar energi?
Men här då?
Kod: Markera allt
#define LCD_Data PORTA
#define LCD_Enable PORTB.F1
#define LCD_RS PORTB.F5
>PORTB.F1
>PORTB.F5
Varför F??
Micke_s: Slösar energi?
Fx är i MikroC då bitsen i sig inte kan anges direkt.
#pragma är nästan alltid kompiler-direktiver som inte kan anges på andra sätt, jag har ALDRIG sett att de används för att ange alias!
Använd därför '#define'!
Kod: Markera allt
#define LCD_Data PORTA
#define LCD_Enable PORTB.F1
#define LCD_RS PORTB.F5
#define LCD_Data_5 PORTB.F2
#define LCD_Data_4 PORTB.F0
void LCD_Putchar(char Data)
{
// must set LCD-mode before calling this function!
// RS = 1 LCD in character-mode
// RS = 0 LCD in command-mode
#if 1
LCD_Data = Data; // Väljs om PORTA.4-5 kan skrivas till utan problem
#else // Väljs om PORTA.4-5 ska bara orörda.
LCD_Data |= Data & 0x9F;
LCD_Data &= Data | 0x60;
#endif
LCD_Data_5 = (Data & 0x20) && 1; // Kan bli ett problem för kompilern
LCD_Data_4 = (Data & 0x10) && 1; // Kan bli ett problem för kompilern
nop();
nop();
LCD_Enable = 1;
nop();
nop();
LCD_Enable = 0;
}
Använd därför '#define'!
Ok, ska kolla LST filen.
Icecap: Jag hänger inte riktigt med här, vad gör du här??
Testar om dom nya värdena är samma som dom tidigare??
Icecap: Jag hänger inte riktigt med här, vad gör du här??
Kod: Markera allt
#if 1
LCD_Data = Data; // Väljs om PORTA.4-5 kan skrivas till utan problem
#else // Väljs om PORTA.4-5 ska bara orörda.
LCD_Data |= Data & 0x9F;
LCD_Data &= Data | 0x60;
#endif
LCD_Data_5 = (Data & 0x20) && 1; // Kan bli ett problem för kompilern
LCD_Data_4 = (Data & 0x10) && 1; // Kan bli ett problem för kompilern
Då du inte kan använda PORTA.4-5 ska '#if 1' ställas till '#if 0' vilket väljer:
Kod: Markera allt
LCD_Data |= Data & 0xCF; // PORTA bitmässig-OR med (0b11001111 AND Data), detta setter alla bit på PORTA som är '1' i Data... förutom bit 4 & 5
LCD_Data &= Data | 0x50; // Detta nollar alla på PORTA som är noll i Data.... förutom bit 4 & 5
// Ser att jag skrev fel, har ändrat värden
LCD_Data_5 = (Data & 0x20) && 1; // Kan bli ett problem för kompilern
LCD_Data_4 = (Data & 0x10) && 1; // Kan bli ett problem för kompilern
// De 2 raderna ovan kollar Data.4 & 5. (Data & 0x20) är en bitmässig AND och vid att logisk AND'a ('&&') med 1 blir värdet sant eller falsk vilket bör överföra värdet till de extra bitar.
Det kan vara aktuellt att göra:
if(Data & 0x20) LCD_Data_5 = 1;
else LCD_Data_5 = 0;
if(Data & 0x10) LCD_Data_4 = 1;
else LCD_Data_4 = 0;
då detta sätt kan vara mer effektivt.