Professional Documents
Culture Documents
7.4. Oheisrautaa. LCD
7.4. Oheisrautaa. LCD
”Useat niistä,
jotka ovat pyrkineet maailman valoksi,
ovat löytäneet itsensä lyhtypylväästä.”
- tuntematon
Sisältö
Yleistä
LCD-näytön toiminta
LCD-näytön ohjelmointi
Mitä on tiedettävä lcd-raudasta ennen ohjelmointiin ryhtymistä:
Katsotaan mitä lcd_tat.h sisältää
lcd_1.c, esimerkki
Toinen esimerkki
printf()-funktio
Merkkijono
Merkkijonon esittely
fdevopen ja sen käyttö lcd-näytön kanssa
Yleistä
1
Toiminta
Merkkinäytön ohjaus
2
44780-normin näyttö sisältää:
- lcd-moduulin
- mikro-ohjaimen, joka ohjaa itse näyttötapahtumaa
- RAM-muisti, johon tulostettavat merkit tallennetaan ja
- ROM-merkkimuistin, josta etsitään ASCII-merkkiä vastaavat ohjaussignaalit
Näytön dataväylä on 8-bittinen ja sen kautta näytölle menevät merkit ovat joko
käskyjä tai dataa. Ohjauspulssien avulla käskyt (esim. kertoo merkin paikan) menevät
käskyrekistereihin ja näytettävä data (ASCII-koodi) datarekisterin kautta
näyttömuistiin ja edelleen näyttöön.
Merkit voivat olla kirjaimia, numeroita tai erikoismerkkejä. Niitä voi tehdä itsekin.
ASCII-koodia vastaava bittikuvio löytyy merkki-ROMmista ja näytön sisäinen CPU
hoitaa sen näytöllä oikeaan riviin ja sarakkeeseen.
LCD-näytön ohjaussignaalit
LCD:n Nimitys Merkitys
pinninumero
1 Vss Power Supply, GND
2 Vcc Power Supply, +5 V
3 Vee GND tai pot. liuku, Kontrasti
4 RS Register Select.
0 = Instruction input
1 = Data input
5 RW Read/Write,
0 = Write to LCD
1 = Read from LCD
6 E Enable, 1>>0
7 DB0 GND, jos 4-bitin ohjaus, LSB
8 DB1 GND, jos 4-bitin ohjaus
9 DB2 GND, jos 4-bitin ohjaus
10 DB3 GND, jos 4-bitin ohjaus
11 DB4 Data 4
12 DB5 Data 5
13 DB6 Data 6
14 DB7 Data 7, MSB
15 Anode Taustavalo +V,
16 Cathode Taustavalo GND
3
LCD-näytön liittäminen AVR-mikro-ohjaimeen
Japanilaisen Hitachin LCD-näytön ohjaustapa HD44780 on vallitseva normi
sulautettuihin soveltuvissa merkkinäytöissä. Valmistaja saa olla kuka tahansa, sen
ohjaus tapahtuu aina samalla tavalla.
LCD-näytön käyttöönotto
LCD-näytön ohjelmointi
4
PV-EMOssa on (kun siihen on liitetty PV-M32-kortti) A-porttiin kytkettynä 2*16
merkin LCD-näyttö. LCD:n taustavaloa ohjataan ON/EI C-portin PC.0-bitillä.
/*A PORT where the LCD is connected and the Data Direction Register
* of that PORT.*/
#define LCD_PORT PORTA
#define LCD_PIN PINA
#define DIRECTION_REGISTER DDRA
5
Näytön liittäminen AVR:n porttiin:
/**
* Bit connections between the LCD and the PORT
*/
#define LCD_4_RS 0x01 // Bit 0, Register Select line
#define LCD_5_RW 0x02 // Bit 1, ReadWrite control line
#define LCD_6_EN 0x04 // Bit 2, Enable
//#define LCD_11_D4 0x10 // Bit 4
//#define LCD_12_D5 0x20 // Bit 5
//#define LCD_13_D6 0x40 // Bit 6
#define LCD_14_D7 0x80 // Bit 7
/**
* A delay between commands. The delay should be about 450ns (might
vary
* a little between different LCDs).
*/
#define COMMAND_DELAY_US 1
lcd_1.c, esimerkki
/**********************************************************
Project : lcd_1.c
Hardware: PV-M32, (4 MHz) + PV-EMO eli LCD on PORTA
Software : WinAVR-20071221
Date : 26.9.2007 + 10.1.2008
Author : pva
Comments: tulostaa tekstiä ja numeroita lcd-näyttöön
6
Klikkaa hiiren oikealla (vasemmalla olevan hakemistopuun)
Source Files, Add Existing Source Files, lisää lcd_tat.c
- tällä kerrotaan C-kääntimelle,
että sen pitää kääntää myös lcd_tat.c
**********************************************************/
#include <avr/io.h>
#include <util/delay.h>
#include "lcd_tat.h"
#define RIVI 0
#define SARAKE 0
// prototyyppi
void wait(uint16_t time);
int main(void)
{
LCD_init(1, 0, 0); // lcd ON, kursori EI, kursori EI VILKU
uint16_t numero = 0;
while(1)
{
LCD_Clear(); // näytön tyhjennys ja kursori "kotiin"
LCD_WriteString("AVR MCU");
LCD_SetCursorXY(SARAKE, RIVI+1);
LCD_WriteUINT(numero);
wait(200);
numero++;
}
}
for(i=0;i<2000;i++)
_delay_loop_2(time);
}
Analysointi
Ensin pitää kopioida lcd_tat.c ja lcd_tat.h tiedostot projektikansioon, kuten
kommenteissa kerrotaan.
AVRStudiossa lcd_tat.c tiedosto otetaan mukaan painamalla hiiren oikealla napilla
Source Files ja sitten Add Existing Source Files... (editorissa vasemmalla
tiedostoikkunassa).
Tämän koodi toimii kuten kommentissa on kerrottu. Sen tarkempi sisältö löytyy
tiedostosta lcd_tat.c.
Seuraava rivi tekee kuten jo funktion nimestä selviää ja kommentti vielä vahvistaa.
LCD_Clear(); // näytön tyhjennys ja kursori "kotiin"
LCD_WriteString("AVR MCU");
7
Sitten näyttöön kirjoitetaan merkkijono. Lainausmerkkien väliin voi laittaa kaikkia
näyttömme osaavia merkkejä. Tekstin pituus on riippuvainen näytöstä.
LCD_SetCursorXY(SARAKE, RIVI+1);
LCD_Write_UINT(numero);
Toinen esimerkki
/**********************************************************
Project : lcd_yksitellen_m32.c
Hardware: PV-M32, (4 MHz) + PV-EMO eli LCD on PORTA
Software : WinAVR-20071221
Date : 10.1.2008
Author : pva
Comments: tulostaa tekstiä lcd-näyttöön merkki kerrallaan
Kopioi lcd_tat.c ja lcd_tat.h tiedostot projektin kansioon.
Klikkaa hiiren oikealla (vasemmalla olevan hakemistopuun)
Source Files, Add Existing Source Files, lisää lcd_tat.c
- tällä kerrotaan C-kääntimelle,
että sen pitää kääntää myös lcd_tat.c
**********************************************************/
#include <avr/io.h>
#include <util/delay.h>
#include "lcd_tat.h"
#define RIVI 0
#define SARAKE 0
for(i=0;i<2000;i++)
_delay_loop_2(time);
}
int main(void)
{
uint8_t i;
uint8_t merkkijono[] = "Upotettu_AVR";
LCD_init(1, 0, 0);
while(1)
{
LCD_Clear(); // näytön tyhjennys ja kursori "kotiin"
8
Analysointi
Edellisen koodin toiminnan kun ymmärtää, niin tämäkin on ”selvää tekstiä”.
Anyway, we do not recommend the printf() family for small devices (at least not
the version in the library -- feel free to use the source code, and cut down your
own customized version). Instead, there are simpler conversion functions
available as well.
9
Merkkijono
Vektori
on samantyyppisten muuttujien kokoelma jolla on yhteinen nimi.
Merkkitaulukko
on char-tyyppisten alkioiden muodostama taulukko.
Merkkijono
on char-tyyppisten alkioiden muodostama taulukko,
joka päättyy ’\0’-merkkiin.
Merkkijonon esittely
char-tyyppinen muuttuja voi tallentaa vain yksittäisen merkin. Koska merkkijonolle ei
ole erityistä tietotyyppiä, muodostetaan merkeistä taulukko.
10
”jono tekstiä”
”” // nollajono
” ” // tyhjää
”a-b+c;” // ei tehdä mitään
”/* ei kommenttia */”
”jono \” juu”
Ongelma on vain siinä miten printf()-funktio saadaan käyttöön avr-gcc:n kanssa. Sitä
varten on opittava C-kielen tiedostojen käsittelyfunktio fopen.
Yleistä
Kaikki ohjelmiemme käsittelemä data katoaa bittien taivaaseen heti kun ohjelman ajo
loppuu. Näin käy ellemme talleta sitä ennen johonkin pysyvään muistiin kuten esim.
kiintolevylle. Tallentamista varten meidän on luotava tiedosto, file.
Funktion fopen
- ensimmäinen argumentti on osoitin
o (ulkoiseen, käsiteltävänä olevaan) tiedostoon
- ja toinen argumentti, mode,
o mitä tiedostolle aiotaan tehdä (w – kirjoitus, r – luku, a – lisäys).
- funktion nimi kuvastaa sen osoitetta.
o tätä osoitetta kutsutaan funktion osoittimeksi, file pointer.
11
Funktiolla on kaksi argumenttia
- eka: mihin merkki kirjoitetaan
- toinen: on osoitin tiedostoon
stdio.h
FILE_ fdevopen (int(_)(char, FILE _) put, int(_)(FILE _) get)
The 3rd argument of fdevopen has been removed since a few avr-
libc versions, it was unused anyway.
Funktion nimi kuvastaa osoitetta, jossa funktio sijaitsee. Tähän osoitteeseen osoittaa
funktion osoitin-pointer. Fdevopen() mahdollistaa funktion osoittimen käytön
parametrina kun kutsutaan itse funktiota ja lähetetään argumentteja sille.
Käytännön esimerkki
/**********************************************************
Project : printf_to_lcd.c
Hardware: PV-M32, (4 MHz) + PV-EMO eli LCD on PORTA
Software : WinAVR-20071221
Date : 10.1.2008
Author : Tomi Tilli & pva
Comments: tulostaa tekstiä lcd-näyttöön merkki kerrallaan
Opiskele fdevopen-dokumentti.
Kopioi lcd_tat.c ja lcd_tat.h tiedostot projektin kansioon.
12
Klikkaa hiiren oikealla (vasemmalla olevan hakemistopuun)
Source Files, Add Existing Source Files, lisää lcd_tat.c
- tällä kerrotaan C-kääntimelle,
että sen pitää kääntää myös lcd_tat.c
**********************************************************/
#include <avr/io.h>
#include <util/delay.h>
#include "lcd_tat.h"
for(i=0;i<2000;i++)
_delay_loop_2(time);
}
int main(void)
{
uint16_t pieni = 123;
uint32_t iso = 123456789;
// Otetaan LCD käyttöön merkinkorjauksella ja ilman kursoria
LCD_init(1, 0, 0);
while (1)
{
// Kirjoitetaan 16-bittinen luku 2.riville
LCD_SetCursorXY(0, 1);
printf("min: %d ", pieni);
wait(500);
// Standard C89/C99 feature:
// long integers require a `l' (letter `ell')
// specifier in integer formats.
LCD_SetCursorXY(0, 1);
// Kirjoitetaan 32-bittinen luku 2.riville
printf("max: %li",iso); // <--- did the trick!!
wait(500);
}
}
Analysointi
Sen suurin hyöty on erilaisten (char, int, hex, des...) numeroiden tulostuksessa.
Toinen huomioitava asia on suurten kokonaislukujen tulostus.
// Standard C89/C99 feature:
// long integers require a `l' (letter `ell')
// specifier in integer formats.
13
LCD_SetCursorXY(0, 1);
// Kirjoitetaan 32-bittinen luku 2.riville
printf("max: %li",iso); // <--- did the trick!!
LCD-näyttö ja liukulukutulostus
Mallikoodi
/**********************************************************
Project : adc_floatingpoint.c
Hardware: PV-M32 (4 MHz) + PV-EMO
Software: WinAVR-20071221
Date : 10.01.2008
Author : pva
Comments: mittaa ADC-3-trimmerin liu'un jännitteen ja
tulostaa sen A-porttiin kytkettyyn LCD-näyttöön.
Laita 10 kohmin trim_potikka GND ja +5 V väliin,
liulle noin 100 kohmia ja
se ADC3-inputtiin, eli PA.3
Säädä potikkaa, seuraa lcd-näyttöä.
uint8_t lippu = 0;
uint16_t adc_data = 0;
14
void Tulosta(uint16_t jannite)
{
cli(); // kielletään keskeytykset
LCD_Clear();
void ADC_init(void)
{
ADMUX |= 1<<REFS0;
// (1<<REFS0) AVCC=5V with external capacitor at AREF pin
ADMUX |= (1<<MUX1) | (1<<MUX0); // valitaan ADC.3-input
ADCSRA |= (1<<ADPS2) | (1<<ADPS0); // jakoluku 32
// 4000000/32 = 125 kHz
// oltava välillä 50 kHz ... 200 kHz
ADCSRA |= (1<<ADIE) | (1<< ADEN); // adc ON ja keskeytys ON
}
int main(void)
{
DDRC |= TAUSTAVALO;
PORTC |= TAUSTAVALO;
// Otetaan LCD käyttöön merkinkorjauksella ja ilman kursoria
LCD_init(1, 0, 0);
if(lippu==1)
Tulosta(adc_data);
}
}
/*
Oletuksena avr-libc-kirjaston printf-funktio ei osaa tulostaa
liukulukuja, desimaalilukuja.
Kun et käytä liukuluja, säästät muistia melkoisesti.
15
Jos kuitenkin haluat käyttää liukulukuja, meidän on maipuloitava
linkkeriä.
1) Avaa AVRStudion "Project -> Configuration Options"
2) Avaa "Libraries"-välilehti
3) Available Link Objects:
- Add Library: math library (libm.a)
- ja the floating-point printf library (libprintf_flt.a)
libprintf_flt.a täytyy olla ylin ja libm.a täytyy olla alin
16