AVR display

From OmegaV-wiki
Jump to: navigation, search

H-fil: <source lang=c>

  1. if !defined DISPLAY_HEADER
  1. define DISPLAY_HEADER


  1. define asm __asm__


  1. define DISPLAY_PORT PORTA //Porten som brukes
  1. define DISPLAY_PIN PINA
  1. define DISPLAY_DDR DDRA
  1. define DISP_RS_PIN 7
  1. define DISP_RW_PIN 6
  1. define DISP_EN_PIN 5
  1. define DISP_D4_PIN 4
  1. define DISP_D5_PIN 3
  1. define DISP_D6_PIN 2
  1. define DISP_D7_PIN 1


//#define F_CPU 8000000L


  1. include <avr/io.h>
  1. include <avr/interrupt.h>
  1. include <util/delay.h>
  1. include <avr/eeprom.h>
  1. include <avr/pgmspace.h>
  1. include <math.h>


typedef char BOOL;

  1. define TRUE 1;
  1. define FALSE 0;


//char menyHenta[3];



void sendDisplay(uint8_t data, const uint8_t RS);

char hentDisplay(void);

uint8_t initDisplay(void);

uint8_t checkDispStatus(void* ikkeBrukt);



void sendDispRamString(char* progAddresse);

void sendDispProgString(char* progAddresse);

void sendDispInt(int32_t tall);

void sendDispFloat(float tall, uint16_t decimalMultiplier);


static inline void sendDisplayData(char data){

sendDisplay(data, 1);

}


static inline void sendDisplayInstruksjon(char instr){

sendDisplay(instr, 0);

}


static inline char hentDisplayAddresse(void){

asm volatile("clt"::);

return hentDisplay();

}


static inline char hentDisplayData(void) {

asm volatile("set"::);

return hentDisplay();

}


static inline void CursDispShift(char ShiftCurs, char HoyreVenstre){

char inst = 0x10;

if(ShiftCurs) inst |= 0x08;

if(HoyreVenstre) inst |= 0x04;

sendDisplayInstruksjon(inst);

}


static inline void dispClear(void){

sendDisplayInstruksjon(0x01);

}


static inline void dispHome(void){

sendDisplayInstruksjon(0x02);

}


static inline void dispEntryMode(char IncDec, char shift){ //IncDec = 1 øker for hver bokstav, og IncDec = 0 minsker

char inst = 0x04;

if(IncDec) inst |= 0x02;

if(shift) inst |= 0x01;

sendDisplayInstruksjon(inst);

}


static inline void dispAvPaa(char main, char cursor, char blink){

char inst = 0x08;

if(main) inst |= 0x04;

if(cursor) inst |= 0x02;

if(blink) inst |= 0x01;

sendDisplayInstruksjon(inst);

}


static inline void dispSetCGRAM(char nyAddresse){

nyAddresse &= 0x3f;

nyAddresse |= 0x40;

sendDisplayInstruksjon(nyAddresse);

}


static inline void dispSetDDRAM(char nyAddresse){

nyAddresse |= 0x80;

sendDisplayInstruksjon(nyAddresse);

}



  1. endif

</code>

C-fil:

  1. include "disp.h"


char PROGMEM egneKaraktera[] = {

0x0F, 0x14, 0x14, 0x1F, 0x14, 0x14, 0x17, 0x00, //Æ pos 1

0x01, 0x0E, 0x13, 0x15, 0x19, 0x0E, 0x10, 0x00, //Ø pos 2

0x04, 0x0A, 0x04, 0x0E, 0x11, 0x1F, 0x11, 0x00, //Å pos 3

0x00, 0x00, 0x1A, 0x05, 0x0F, 0x14, 0x0F, 0x00, //æ pos 4

0x00, 0x02, 0x0E, 0x15, 0x15, 0x0E, 0x08, 0x00, //ø pos 5

0x04, 0x0A, 0x0E, 0x01, 0x0F, 0x11, 0x0F, 0x00, //å pos 6

0x0C, 0x12, 0x12, 0x0C, 0x00, 0x00, 0x00, 0x00 //Grade-tegn

};



uint8_t displayStatus; //0->ikke tilkoblet, 1->tilkoblet



void sendDispProgString(char* progAddresse){

char tegn = pgm_read_byte(progAddresse++);

while(tegn != 0){

sendDisplayData(tegn);

tegn = pgm_read_byte(progAddresse++);

}

}


void sendDispRamString(char* progAddresse){

char* tegn = progAddresse;

while(*tegn != 0)

sendDisplayData(*tegn++);

}




void sendDispInt(int32_t tall){

if (tall < 0){

tall = - tall;

sendDisplayData('-');

}

if(tall == 0){

sendDisplayData('0');

}


int32_t divisor = 1000000000;

uint8_t startet = 0;

while(divisor != 0){

uint8_t sendes = ((uint8_t) (tall/divisor));

if((startet != 0) || (sendes != 0)){

sendDisplayData(sendes+'0');

startet = 0xFF;

tall = tall%divisor;

}

divisor = divisor/10;

}

}


void sendDispFloat(const float tall, const uint16_t decimalMultiplier){

int32_t vises = (int32_t) (tall*decimalMultiplier);

sendDispInt(vises/decimalMultiplier);

sendDisplayData('.');

sendDispInt( (abs(vises%decimalMultiplier))+0.5 );

}




//RS=1 sender data, RS=0 sender instruksjon (LSB bestemmer). T-flagget brukes i funkjonen

void sendDisplay(uint8_t data, const uint8_t RS){


DISPLAY_PORT = 0;


if(displayStatus==0)//drit i alt hvis displayet ikke er tilkoblet

return;


int teller = 0;

asm volatile("clt" "\n\t"::);

while( (hentDisplay() & 0x80) && ((++teller) < 1000) ){

}

if (!(teller<1000)){

displayStatus = 0;

//OSAddTask(initDisplay, (void*)0, 200);

}



//Skal altså sende...

DISPLAY_DDR = (1<<DISP_RS_PIN)|(1<<DISP_RW_PIN)|(1<<DISP_EN_PIN)|(1<<DISP_D4_PIN)|(1<<DISP_D5_PIN)|(1<<DISP_D6_PIN)|(1<<DISP_D7_PIN);


for(uint8_t i = 2 ; i != 0; i--){

uint8_t utByte = 0;

if(RS){

utByte |= (1<<DISP_RS_PIN);

}

if(data & (1<<4)){

utByte |= (1<<DISP_D4_PIN);

}

if(data & (1<<5)){

utByte |= (1<<DISP_D5_PIN);

}

if(data & (1<<6)){

utByte |= (1<<DISP_D6_PIN);

}

if(data & (1<<7)){

utByte |= (1<<DISP_D7_PIN);

}


DISPLAY_PORT = utByte;

asm volatile("nop"::);

DISPLAY_PORT |= (1<<DISP_EN_PIN); //Setter EN-pinne

asm volatile(

"swap %0" "\n\t" //Bytter om slik at neste gang blir low-nibble sendt

"nop" "\n\t"

"nop" "\n\t"

"nop" "\n\t"

:"=r" (data)

:"r" (data)

);

DISPLAY_PORT = utByte; //Resetter EN-pinne

}




}




char hentDisplay(void){


//Setter dataporter til innganger, og styresignalene til utganger.

DISPLAY_DDR = (1<<DISP_RS_PIN)|(1<<DISP_RW_PIN)|(1<<DISP_EN_PIN);


//setter RW høy og skrur på pullup på innganger

uint8_t styreByte = (1<<DISP_RW_PIN)|(1<<DISP_D4_PIN)|(1<<DISP_D5_PIN)|(1<<DISP_D6_PIN)|(1<<DISP_D7_PIN);


asm volatile( //Setter RS-bit bestemt av T-bit

"bld %0, %1"

:"=r" (styreByte)

:"I" (DISP_RS_PIN), "r" (styreByte)

);


uint8_t ret = 0;


DISPLAY_PORT = styreByte;

asm volatile("nop"::);


for(uint8_t i = 2; i!=0; i--){


DISPLAY_PORT |= (1<<DISP_EN_PIN); //Setter EN-pinne

asm volatile(

"swap %0" "\n\t" //Bytter om slik at neste gang blir low-nibble sendt

"nop" "\n\t"

"nop" "\n\t"

"nop" "\n\t"

"nop" "\n\t"

:"=r" (ret)

:"r" (ret)

);


uint8_t p = DISPLAY_PIN;

DISPLAY_PORT &= ~(1<<DISP_EN_PIN); //Resetter EN-pinne


if(p & (1<<DISP_D4_PIN)){

ret |= (1<<0);

}

if(p & (1<<DISP_D5_PIN)){

ret |= (1<<1);

}

if(p & (1<<DISP_D6_PIN)){

ret |= (1<<2);

}

if(p & (1<<DISP_D7_PIN)){

ret |= (1<<3);

}

}

DISPLAY_PORT = 0;


return ret;


}


uint8_t initDisplay(void){


displayStatus = 1;


DISPLAY_DDR = (1<<DISP_RS_PIN)|(1<<DISP_RW_PIN)|(1<<DISP_EN_PIN)|(1<<DISP_D4_PIN)|(1<<DISP_D5_PIN)|(1<<DISP_D6_PIN)|(1<<DISP_D7_PIN);


for(char i = 0x0f; i; i=i>>1){

_delay_loop_2(0x3FFF);


uint8_t pinne = (1<<DISP_D5_PIN);


asm volatile(

"bst %3, 1" "\n\t"

"bld %0, %2" "\n\t"

:"=r" (pinne)

:"r" (pinne), "I" (DISP_D4_PIN), "r" (i) //Setter data4 hvis den skal settes

);


DISPLAY_PORT = pinne;

asm volatile("nop" ::);

DISPLAY_PORT |= (1<<DISP_EN_PIN); //Setter EN-pinne

asm volatile(

"nop" "\n\t"

"nop" "\n\t"

"nop" "\n\t"

"nop" "\n\t"

:

:

);


DISPLAY_PORT &= ~(1<<DISP_EN_PIN); //Resetter EN-pinne


}


sendDisplayInstruksjon(0x28);


if(displayStatus == 0){

return 0;

}


sendDisplayInstruksjon(0x06);

sendDisplayInstruksjon(0x02);

sendDisplayInstruksjon(0x0c);




sendDisplayInstruksjon(0x48); //setter CG-ram-adresse

unsigned int adr = egneKaraktera;

while(adr < (egneKaraktera + sizeof(egneKaraktera)) ){

sendDisplayData(pgm_read_byte(adr++));

}

dispSetDDRAM(0);


return 0;

}


uint8_t checkDispStatus(void* ikkeBrukt){

//Dette kan skje noe uventet, men OS-et skal passe på at det ikke skjer under utførelse av annen prosess.

//Men den kan forårsake at addressen er satt til 0 selv om den ikke var det etter forrige prosess.



uint8_t adr = hentDisplayAddresse();

dispSetDDRAM(adr);


if(displayStatus){

//OSAddTask(checkDispStatus, (void*)0, 300); //gjentaes hvert 3. sekund

}

else {

//OSAddTask(initDisplay, (void*)0, 300); //Skal prøve å koble til displayet

}

return 0;

}





/* chat-discussion with author:


Pål says:

yess

Pål says:

fekk bilde no

erlend says:

jee

erlend says:

alt e perfekt

erlend says:

?

Pål says:

yepp

Pål says:

men ka gjer egentlig metoden hentDisplay?

erlend says:

bare å kjør på da

erlend says:

hent???

erlend says:

hmmmm

erlend says:

hete den hent

erlend says:

?

Pål says:

char hentDisplay(void){

Pål says:

men ej brukte den her uint8_t initDisplay(void* ikkeBrukt){

erlend says:

ikke sikker

erlend says:

ja

Pål says:

ka e egentlig en void* ikkeBrukt?

erlend says:

du kan fjern inout hvis du vil

erlend says:

bare for å tepass drivern te "OS-et"

Pål says:

k

erlend says:

brukes ikke te nå, men funksjonen må ha en standard form siden den kalles av "OSet"

Pål says:

k

Pål says:

ka du meina med å fjerne inout?

erlend says:

input

erlend says:

ikkeBrukt

Pål says:

ok

erlend says:

hentDisplay les ut data fra displayet

erlend says:

hentDisplay les ut data fra displayet

erlend says:

hentDisplay les ut data fra displayet

erlend says:

brukes også av sende-funksjonen

erlend says:

så den må vær der

Pål says:

ok

Pål says:

korleis ej kjøm til neste linje?

erlend says:

huske ikke navne på funksjonen

erlend says:

men den står nesten nederst i h-fila

Pål says:

CursDispShift

erlend says:

setDDRAM eller nå sånt

Pål says:

k

erlend says:

nei

Pål says:

e rutinå slik at ej skriv frå starten av displayet og når ej skal entre nokke so jeng ej til starten og skriv alt på nytt?

erlend says:

den samme

erlend says:

har du navnet?

Pål says:

static inline void dispSetDDRAM(char nyAddresse){

erlend says:

ja

erlend says:

dispSetDDRAM starte i rute 1

Pål says:

ok

erlend says:

evt 0

erlend says:

dispSetDDRAM(0x40) starte i rute 0 på andre lnje

Pål says:

so ej kan gå til den rutå ej vil å skrive det ej vil? alt treng ikkje å ver i sekvens nei?

erlend says:

ja

Pål says:

cool

Pål says:

trur ej he det no

erlend says:

hvis du skrur på cursor bli det enklar å sje

Pål says:

k

Pål says:

no sendte ej hello world å no stend det "å"

erlend says:

da e det i live

Pål says:

hmm

Pål says:

skal ikkje det gå an å skrive sendDispProgString("Hello World"); ?

erlend says:

nei

erlend says:

den stringen vil lagres i RAMen

erlend says:

du må deklarer den som en global variabel

Pål says:

ok

Pål says:

greit

erlend says:

char PROGMEM ....

Pål says:

k

Pål says:

hmmm

Pål says:

char* PROGMEM tekst1 = "hallo verden";

Pål says:

sendDispProgString(tekst1);

erlend says:

ikke char*

Pål says:

ah

erlend says:

men du må inkluder ei fil

Pål says:

å?

erlend says:

pmgspace eller nå sånt

Pål says:

ok

Pål says:

fekk ikkje feilmelding

Pål says:

den e inkludert i disp.h

erlend says:

oki

erlend says:

char PROGMEM tekst1 = "hallo verden";

erlend says:

nei

erlend says:

char* PROGMEM tekst1[] = "hallo verden";

erlend says:

[] ? [ ]

erlend says:

[] = [ ]

erlend says:

nei

Pål says:

no funka det

Pål says:

no stend det hallo verden

erlend says:

bra ting

erlend says:

skriv du: char PROGMEM tekst1[] = "hallo verden";

erlend says:

?

Pål says:

ja

Pål says:

for å slette so bere sende ej en space?

erlend says:

ja

erlend says:

eller funksjone clearDisp eller nå sånt

Pål says:

ok

Pål says:

cool

erlend says:

dispClear kanskje

Pål says:

no trur ej ej skal få til resten

erlend says:

det e bra

Pål says:

tjaa...

Pål says:

vist ej skal skrive pål er tøff då?

Pål says:

ø'en blir en x med strek over

erlend says:

det går ikke

Pål says:

ok

erlend says:

fysisk umulig

erlend says:

sjølmotsigels

Pål says:

hehe

erlend says:

har en tabell som definere æøå

Pål says:

må vel sende ett og ett tegn for å sende æøå

Pål says:

jepp såg tabelln

Pål says:

ej drit i æøå ej

erlend says:

trur æ=\001

erlend says:

eller nå sånt

erlend says:

\00x

erlend says:

der x-en står som kommentar i tabellen

Pål says:

k




erlend says:

asm volatile("jmp 0" : ;

erlend says:

eller

erlend says:

asm volatile("jmp 0" "\n\t": ;

erlend says:

eller

erlend says:

__asm__ volatile("jmp 0" "\n\t": ;



  • /

</source>