AVR display

From OmegaV-wiki

Jump to: navigation, search

H-fil:

#if !defined DISPLAY_HEADER
 
#define  DISPLAY_HEADER
 
 
 
#define asm __asm__
 
 
 
#define DISPLAY_PORT PORTA //Porten som brukes
 
#define DISPLAY_PIN PINA
 
#define DISPLAY_DDR DDRA
 
#define DISP_RS_PIN 7
 
#define DISP_RW_PIN 6
 
#define DISP_EN_PIN 5
 
#define DISP_D4_PIN 4
 
#define DISP_D5_PIN 3
 
#define DISP_D6_PIN 2
 
#define DISP_D7_PIN 1
 
 
 
//#define F_CPU 8000000L
 
 
 
#include <avr/io.h>
 
#include <avr/interrupt.h>
 
#include <util/delay.h> 
 
#include <avr/eeprom.h>
 
#include <avr/pgmspace.h>
 
#include <math.h>
 
 
 
typedef char BOOL;
 
#define TRUE 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);
 
}
 
 
 
 
 
#endif
</code>
 
C-fil:
<code c>
#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": ;
 
 
 
 
 
*/
Personal tools