Op de site van Pros vond ik een interessante 3-draads LCD interface.
Ik heb Pros z'n voorbeeldcode schaamteloos overgenomen en geprobeert om deze uit te breiden tot een werkend geheel.
Mijn code werkt, ik kan alle stuurcommando's sturen (1e lijn, 2e lijn, clear, blink on/off...), maar letters komen niet juist aan.
Ik gebruik onderstaande code. In comments staat achter elk lcd_putchar commando welke letter er getoond wordt op het LCD als dat commando uitgevoerd wordt.
#define COM 0
#define LCD_PORT PORTB
#define LCD_DDR DDRB
#define LCD_DATA_PIN PB1
#define LCD_CLK_PIN PB2
#define LCD_E_PIN PB0
#define TXT 1
#define lcd_delay(x) _delay_loop_1(x)
#define lcd_command(x) char2LCD3(x, COM)
#define lcd_putchar(x) char2LCD3(x, TXT)
#define F_CPU 9600000UL
#include <avr/io.h>
#include <util/delay.h>
int main(void) {
DDRB |= 0x0F;
//3 keer 0x30 sturen om lcd te starten
_delay_ms(20);
lcd_command(0x30);
_delay_ms(5);
lcd_command(0x30);
_delay_us(160);
lcd_command(0x30);
_delay_us(160);
lcd_command(0x38); //2line 8bit 5x7-dot
lcd_command(0x08); //disp off
lcd_command(0x01); //clear
_delay_ms(2);
lcd_command(0x06); //entry mode: increment, no shift
lcd_command(0x0C); //disp on
lcd_command(0x02); //cursor home
lcd_command(0x0F); //cursor blink
_delay_ms(1);
//Tekst tonen op LCD:
lcd_putchar("a"); //"`"
lcd_putchar("b"); //"b"
lcd_putchar("c"); //"d"
lcd_putchar("d"); //"f"
lcd_putchar("e"); //"h"
lcd_command(0xC0); //2e lijn
lcd_putchar("A"); //"j"
lcd_putchar("B"); //"l"
lcd_putchar("C"); //"n"
lcd_putchar("D"); //"p"
lcd_putchar("E"); //"r"
while(1){
//knipperend ledje
LCD_PORT |= 0x08;
_delay_ms(100);
LCD_PORT &= 0xF7;
_delay_ms(100);
}
}
//Functie van Pros:
void char2LCD3(unsigned char karakter, unsigned char RS)
{
unsigned char cnt;
for (cnt = 0; cnt < 8; cnt++) {
if ((karakter & 0x80) == 0x80) { // een '1'
LCD_PORT |= (1 << LCD_DATA_PIN); // LCD_DATA_PIN hoog
} else { // een '0'
LCD_PORT &= ~(1 << LCD_DATA_PIN); // LCD_DATA_PIN laag
}
lcd_delay(5);
LCD_PORT |= (1 << LCD_CLK_PIN); // Seriele klok hoog
lcd_delay(5);
LCD_PORT &= ~(1 << LCD_CLK_PIN); // Seriele klok terug laag
karakter = karakter << 1; // Bits een plaatsje naar rechts schuiven
}
if (RS == TXT) {
LCD_PORT |= (1 << LCD_DATA_PIN); // Tekst, RS moet hoog
} else {
LCD_PORT &= ~(1 << LCD_DATA_PIN); // Instructie, RS moet laag
}
lcd_delay(5);
LCD_PORT |= (1 << LCD_E_PIN); // schuifregister -> par. uitgang
lcd_delay(20);
LCD_PORT &= ~(1 << LCD_E_PIN); // par. uitgang -> LCD-module
//extra wachttijd:
_delay_us(50);
}
Ik gebruik een Attiny13 microcontroller op 9.6MHz. Clock is verbonden met PB2, Data met PB1 en Latch met PB0.
Net alsof er geschoven wordt met de letters door het alfabet, maar er worden letters overgeslagen...?
Wie ziet wat ik fout doe?
Alvast bedankt,
Stijn
Edit:
Verder prutsen toont aan dat er geen verband is tussen opgegeven karakters en wat er op het scherm komt. Enkel de hoeveelheid tekens komt overeen.
Ik heb volgende code:
lcd_putchar("0");
lcd_putchar("1");
lcd_putchar("2");
lcd_putchar("3");
lcd_putchar("4");
lcd_putchar("5");
lcd_putchar("6");
lcd_putchar("7");
Maar op het scherm komt "`bdfhjln"???
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Je moet het verschil tussen een "character" en een "string" weten...
Een karakter staat tussen quotes. Er is weinig verschil in C tussen 'A' en 65.
De functie "lcdputchar" zal wel met een karakterteken moeten worden aangeroepen. dus: lcdputchar (65); of lcdputchar ('A');
Als je een string wilt in C, moet het tussen dubbele aanhalingstekens zetten. De string HELLO komt als 48 45 4c 4c 4f 00 in opeenvolgende locaties. Maar de string "A" mag ook: 41 00 . Nu wordt niet het hele stringgebied als argument aan een functie doorgegeven, maar alleen een pointer.
Dus als op adres 0x30 je string "A" komt te staan, dus op 0x30 de "A" 41, en op 0x31 de 00, en je roept lcdputchar ("A") aan, dan krijg je het cijfer '0' op je scherm omdat lcdputchar de laagste 8 bits als te printen karakter opvat.....
P.S. (Haha! het is mooi te zien dat iedere volgende regel de 2-byte string precies 2 bytes verder in het geheugen gezet is! )
P.P.S. Zowel in je eerste posting als in de edit!
*Slaat zichzelf tegen de kop*
Inderdaad, als ik de dubbele quotes vervang door enkele dan werkt het wel. Had ik maar beter opgelet in de les C... 
Bedankt!
Op 10 december 2010 17:11:28 schreef pros:
Je zou ook kunnen letten op de warnings van de compiler. Die waarschuwt je, als je zulke foutjes maakt.
Inderdaad... Net even gecontroleerd:
../3wireLCD.c:67: warning: passing argument 1 of 'char2LCD3' makes integer from pointer without a cast
[Bericht gewijzigd door Stijn S op (52%)]
pros
Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)
Je zou ook kunnen letten op de warnings van de compiler. Die waarschuwt je, als je zulke foutjes maakt.