Dumma LCD, HJÄLP!

Lysdioder, Optiska sensorer, Fiberoptik, Displayer, Lasrar, Optiska kopplare
net4all
Inlägg: 538
Blev medlem: 7 februari 2007, 12:06:34

Inlägg av net4all »

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
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> 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...
net4all
Inlägg: 538
Blev medlem: 7 februari 2007, 12:06:34

Inlägg av net4all »

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:

Kod: Markera allt

CMCON, CM0 = 1; CMCON, CM1 = 1; CMCON, CM2 = 1;
Gjorde ingen skillnad, testade en egen:

Kod: Markera allt

CMCON.0=1; CMCON.1=1; CMCON.2=1;
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:

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
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.
Användarvisningsbild
björn
EF Sponsor
Inlägg: 2570
Blev medlem: 29 mars 2004, 23:09:55

Inlägg av björn »

Får du inga kompileringfel när du använder *egna* definitioner? Tycker att något av alternativen borde kompilatorn skrika om...
Användarvisningsbild
Icecap
Inlägg: 26647
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Jag har skippat CC5X sedan länge men dessa #pragma-definitioner ger mig nervös mage.

Jag hade (och gör ofta) såhär:
#define RS PORTB.5
#define Enable PORTB.1
osv.

Vad är det fel med:
CMCON = 0x07; ?????

Spola alla dessa CMCON.x = 1;
net4all
Inlägg: 538
Blev medlem: 7 februari 2007, 12:06:34

Inlägg av net4all »

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
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Inget jag har bara inte testat! Måste testas.

Right, det var därför jag föreslog det för många inlägg sen.
Kolla ca 15 inlägg tillbaka i tråden...
net4all
Inlägg: 538
Blev medlem: 7 februari 2007, 12:06:34

Inlägg av net4all »

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?
Användarvisningsbild
Icecap
Inlägg: 26647
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Kollade lite på källkoden och herregud.... vad håller du på med?

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();
}
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

#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;
  }
Användarvisningsbild
Micke_s
EF Sponsor
Inlägg: 6741
Blev medlem: 15 december 2005, 21:31:34
Ort: Malmö

Inlägg av Micke_s »

NOP:ar är fint :?
Den instruktionen som slösar mest energi, gör inget i full hastighet :P
net4all
Inlägg: 538
Blev medlem: 7 februari 2007, 12:06:34

Inlägg av net4all »

Det såg mycket enklare ut får man ju erkänna...

Men här då?

Kod: Markera allt

#define LCD_Data PORTA 
#define LCD_Enable PORTB.F1 
#define LCD_RS PORTB.F5 
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?
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Hur kan jag testa om comparatorerna är av? Mer än att läsa i registret?

Kolla assemblerkoden i LST filen. Det är igentligen bara det enda
säkra sättet...
Användarvisningsbild
Icecap
Inlägg: 26647
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Fx är i MikroC då bitsen i sig inte kan anges direkt.

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;
  }
#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'!
net4all
Inlägg: 538
Blev medlem: 7 februari 2007, 12:06:34

Inlägg av net4all »

Ok, ska kolla LST filen.

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 
Testar om dom nya värdena är samma som dom tidigare??
Användarvisningsbild
Icecap
Inlägg: 26647
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

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.
Skriv svar