Seit gegrüßt Bastler,
heute mal eine Ansteuerung eines Standard-LCD (HD44780) mit einem 74HC164 in 8Bit-Form.
Ist nix neues wurde auch hier schon mit einem 74hc595 durchgeführt.
Änderung in der HEX_DEZ_Wandlung.asm wurden die Abholpunkte hinzugefügt das diese nicht ständig geändert werden müssen und somit nur in der Zahlenausgabe von 10 bis 2stellig leider noch ohne Führungsnullunterdrückung.... vielleicht kommts noch.....
Änderung LCD_Routine Zahlenausgabe entweder komplett oder aber mit dem Befehl SET so das hier nur entsprechende Stellen ausgegeben werden SIEHE start Makierung ROT
Alle andere Funktionen bleiben wie gehabt und werden nicht beeinflusst
Aber genug der Labberei hier die Infos:
origin.asm
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!Code:;########################################### ;# Projekt: LCD 8bit seriel # ;# # ;# # ;# Taktfrequenz des AVR: 4 MHz # ;# # ;# CS-SOFT # ;########################################### .include "m8def.inc" ;Atmega8 .def math1h = r8 .def math1l = r9 .def math2h = R10 .def math2l = r11 .def matherghh = r12 .def mathergh = r13 .def mathergl = r14 .def mathergll = r15 .def temp0 = r16 ; .def temp1 = r17 ; .def temp2 = r18 .def temp3 = r19 ; .def temp4 = r20 .def cnt = r21 ;**********LCD Port mit 74HC164 .equ port_lcd_x = portc .equ ddrx_lcd_x = ddrc ; Pinbelegungen ; STD .equ SClock = 0 ;LCD ;;; .equ SRS = 0 .equ SData = 1 ;74164 ;;;;;so Kann die HW angeschlossen sein .equ SRW = 1 .equ Light = 2 ;LCD ;;;;; .equ SEnable = 3 ;74164 ;;; ;Entry Set .equ SH = 0 ;1 = Display shift 0 = not shifted .equ ID = 1 ;1 = increase 0 = decrease .equ HES = 2 ;immer 1 setzen Symbolisiert das Ende ;des Commandos ;DISPLAY on/off .equ B = 0 ;1 = Blink 0 = no Blink .equ C = 1 ;1 = Cursor on 0 = Cursor off .equ D = 2 ;1 = Disp on 0 = Disp off .equ HD = 3 ;immer 1 setzen Symbolisiert das Ende ;des Commandos ;Shift .equ RL = 2 ;1 = right shift 0 = left shift .equ SC = 3 ;1 = Disp shift 0 = Cursor move .equ HS = 4 ;immer 1 setzen Symbolisiert das Ende ;des Commandos ;SET Function .equ F = 2 ;1 = 5x10 0 = 5x7 .equ N = 3 ;1 = 2line(4line) 0 = 1line .equ DL = 4 ;1 = 8bit int 0 = 4bit interface .equ HSF = 5 ;immer 1 setzen Symbolisiert das Ende ;des Commandos ;**********SRAM .equ erg_k = $0060 ;erg_k wird bis zu 5 weiteren bytes genutzt sprich erg_k+5 .equ ocr2s = $0065 ;für T2 .equ ocra1h = $0066 ;;;;; .equ ocra1l = $0067 ;;;;;;;; für T1 A channel .equ ocrb1h = $0068 ;;;;; .equ ocrb1l = $0069 ;;;;;;;; für T1 B channel .equ icr1xh = $006a ;;;;; .equ icr1xl = $006b ;;;;;;;; für T1 ICR .equ hadc = $006c ;adc .equ ladc = $006d ;adc .equ eep_adrh = $006e ;eeprom .equ eep_adrl = $006f ;eeprom .equ LTC_wertH = $0070 .equ LTC_wertL = $0071 .equ Poti0 = $0072 ;Potentiometer 0 .equ ploudr = $0073 ;poti für lautstärke rechts .equ ploudl = $0074 ;poti für lautstärke links .equ phigh = $0075 ;poti für höhen .equ pbass = $0076 ;poti für bass .equ halbeh = $0077 ; .equ halbel = $0078 ;***************************Einsprungadressen*********************** .cseg .org $0000 rjmp stack .org $0001 ;1 reti;rjmp INT_0 .org $0002 ;2 reti;rjmp INT_1 .org $0003 ;3 reti;rjmp INT_OC2 .org $0004 ;4 reti;rjmp INT_OVF2 .org $0005 ;5 reti;rjmp INT_ICP1 .org $0006 ;6 reti;rjmp INT_OC1A .org $0007 ;7 reti;rjmp INT_OC1B .org $0008 ;8 reti;rjmp INT_OVF1 .org $0009 ;9 reti; rjmp INT_OVF0 reti ;a keine SPI Routinen .org $000b ;b reti;rjmp INT_URXC .org $000c ;c reti;rjmp INT_UDRE .org $000d ;d reti;rjmp INT_UTXC .org $000e ;e reti;rjmp adc_rdy .org $000f ;f reti;rjmp eeprom_rdy .org $0010 ;10 reti;rjmp ac_int reti ;11 keine 2wireRoutinen reti ;12 keine SPMRoutinen .org $001c reti;rjmp OC0A_int ;***************************Init mit allem drumdran***************** stack: ldi temp0,high(ramend) ;Stackpointer festlegen out sph, temp0 ldi temp0,low(ramend) ;Stackpointer festlegen out spl, temp0 rcall sram rcall lcd_init rcall lcd_clear rcall werbe1 rcall werbe2 start: lds mathergll,ladc inc mathergll sts ladc,mathergll rcall wert_out rcall wait1s rcall wert_out_all ;Augabe aller Dezimalstellen ohne Punkt ab tr xy zw de rcall wait1s rcall wert_out_4 ;Ausgabe Vorkommastellen und aller Nachkommastellen mit Punkt tr.xy zw de rcall wait1s rcall wert_out_4_2 ;Ausgabe Vorkommastellen und einiger Nachkommastellen mit Punkt tr.xy zw rcall wait1s rcall wert_out_2 ;Ausgabe der letzten 4 Dezimalstellen mit Punkt dazwischen zw.de rjmp start ;**********************Masterclr*************************************** sram: clr temp0 ldi yl,low(SRAM_START) ldi yh,high(SRAM_START) ;Masterclr des Sram's über sram2: st y+,temp0 ;die indirekte Adressierung cpi yl,$a0 ;bis zur zelle x=$a0 löschen brne sram2 ret ;*************************weitere*includedata*********************** .include "hex_dez_wandlung.asm" .include "lcd_KS0066_KS0070_8bit.asm" .include "zeitschleifen.asm" .include "DbTxt_LCD.asm" ;*************************ENDE**************************************
Änderung load_hex_dez kann jetzt mit nur hex_dez aufgerufen werden.
Schnittstelle bleibt matherghh:hl:l:ll in die die zu wandelnde Werte, zu laden sind.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
hex_dez_wandlung.asm
lcd_KS0066_KS0070_8bit.asmCode:;*************************AUSGBAE zahlen******************************** neu ;*******************Welche/Wieviele Stellen ausgegeben werden sollen load_Y_ergk: ;Ausgabe 1Mrd / 100Mio ldi yh,high(erg_k) ldi yl,low(erg_k) ;speicherpunkt laden ret load_Y_ergk1: ;Ausgabe 10Mio / 1Mio ldi yh,high(erg_k+1) ldi yl,low(erg_k+1) ;speicherpunkt laden ret load_Y_ergk2: ;Ausgabe 100 000 / 10 000 ldi yh,high(erg_k+2) ldi yl,low(erg_k+2) ;speicherpunkt laden ret load_Y_ergk3: ;Ausgabe 1000 / 100 ldi yh,high(erg_k+3) ldi yl,low(erg_k+3) ;speicherpunkt laden ret load_Y_ergk4: ;Ausgabe 10 / 1 ldi yh,high(erg_k+4) ldi yl,low(erg_k+4) ;speicherpunkt laden ret ;**********Wandlungsvorbereitung von HEX in DEZ****** hex_dez:push xl push xh push zl push zh mov zh,matherghh ;highhigh ;wenn ZH=ff>>LCD=4294967295 mov zl,mathergh ;highlow ;wenn ZL=ff>>LCD=16777215 bei ZH=0 mov xh,mathergl ;high ;wenn XH=ff>>LCD=65535 bei ZH:ZL=0 mov xl,mathergll ;low ;wenn xl=ff>>LCD=255 bei XH=0 push yl push yh rcall load_Y_ergk ;Speicherbereich laden ldi cnt,$ff ; num_1000000000: ;Milliarden inc cnt subi xh, byte2(1000000000) sbci zl, byte3(1000000000) sbci zh, byte4(1000000000) brcc num_1000000000 swap cnt st y,cnt ldi cnt,$0a num_100000000: ;100Millionen dec cnt ;+1 subi xh, byte2(-100000000) sbci zl, byte3(-100000000) sbci zh, byte4(-100000000) brcs num_100000000 ;ja ld temp0,y or cnt,temp0 st y+,cnt ;fertig speichern ldi cnt,$ff ; num_10000000: ;10Millionen inc cnt subi xl, byte1(10000000) sbci xh, byte2(10000000) sbci zl, byte3(10000000) sbci zh, 0 brcc num_10000000 swap cnt st y,cnt ldi cnt,$0a num_1000000: ;1Million dec cnt ;+1 subi xl, byte1(-1000000) ; sbci xh, byte2(-1000000) ;vergleich auf >1000000 sbci zl, byte3(-1000000) brcs num_1000000 ;ja ld temp0,y or cnt,temp0 st y+,cnt ;fertig speichernn ldi cnt,$ff ; num_100000: ;100Tausend inc cnt subi xl, byte1(100000) sbci xh, byte2(100000) sbci zl, byte3(100000) brcc num_100000 swap cnt st y,cnt ldi cnt,$0a num_10000: ;10Tausend dec cnt ;+1 subi xl, byte1(-10000) ; sbci xh, byte2(-10000) ;vergleich auf >10000 sbci zl, byte3(-10000) brcs num_10000 ;ja ld temp0,y or cnt,temp0 st y+,cnt ;fertig speichern ldi cnt,$ff num_1000: ;Tausender inc cnt subi xl, low(1000) sbci xh, high(1000) brcc num_1000 swap cnt st y,cnt ldi cnt,$0a num_100:dec cnt ;100 subi xl, low(-100) sbci xh, high(-100) brcs num_100 ld temp0,y or cnt,temp0 st y+,cnt ldi cnt,$ff num_10: inc cnt ;Zehner + Einer subi xl, 10 brcc num_10 subi xl, -10 swap cnt or cnt,xl st y+,cnt pop yh pop yl pop zh pop zl pop xh pop xl ret
DbTxt_LCD.asmCode:;******************************Header /*;das ist die Testbelegung für sriell über 74hc164 zu 8bit .equ erg_k = $0060 ;zahlenspeicher für ausgabe ; Pinbelegungen ; STD ; .equ SClock = 0 ;LCD ;;; .equ SRS = 0 .equ SData = 1 ;74164 ;;;;;so Kann die HW angeschlossen sein .equ SRW = 1 .equ Light = 2 ;LCD ;;;;; .equ SEnable = 3 ;74164 ;;; ;Entry Set .equ SH = 0 ;1 = Display shift 0 = not shifted .equ ID = 1 ;1 = increase 0 = decrease .equ HES = 2 ;immer 1 setzen Symbolisiert das Ende ;des Commandos ;DISPLAY on/off .equ B = 0 ;1 = Blink 0 = no Blink .equ C = 1 ;1 = Cursor on 0 = Cursor off .equ D = 2 ;1 = Disp on 0 = Disp off .equ HD = 3 ;immer 1 setzen Symbolisiert das Ende ;des Commandos ;Shift .equ RL = 2 ;1 = right shift 0 = left shift .equ SC = 3 ;1 = Disp shift 0 = Cursor move .equ HS = 4 ;immer 1 setzen Symbolisiert das Ende ;des Commandos ;SET Function .equ F = 2 ;1 = 5x10 0 = 5x7 .equ N = 3 ;1 = 2line(4line) 0 = 1line .equ DL = 4 ;1 = 8bit int 0 = 4bit interface .equ HSF = 5 ;immer 1 setzen Symbolisiert das Ende ;des Commandos */ ;*************************LCDinit************************************** lcd_init: ; rcall reset_chip ;wenn reset-pin getriggert wird sbi Port_lcd_x,SRS ldi temp0,(1<<SData|1<<Light|1<<SEnable) out ddrx_lcd_x,temp0 ldi temp0,$14 ;32ms warten rcall waitxms ; rcall lcd_function_set_ext ;LCD mit Kontrastumschaltung und anderen Features rcall lcd_function_set_std ;Standard LCD rcall lcd_on ;LCD an rcall entry_mode_std ;Haupteinstellungen ret lcd_clear: ldi temp1,0b00000001 rcall lcd_command ldi temp0,$14 rcall waitxms ret lcd_DDR_AdrX: ;ldi temp1,0b1xxxxxxx ;1 Signalisiert das es DisplayDaten sind und in den rcall lcd_command ;DisplayDatenRam DDRam geschrieben werden für die Anzeige rcall wait50us ;auf dem Display xxx= ist die Adresse ret ;********Funktion Set für Displays MIT RE-Bit ***************************** lcd_function_set_ext: ldi temp1,0b00100100 ;funktionset nur für LCD mit RE-Bit rcall lcd_command ;DatenLine1=8bit, RE=1 (für Unterfunktionen an) rcall wait50us ldi temp1,0b00001001 ;funktionset nur für ReversDisplay rcall lcd_command ;DatenLine1=8bit, N=1 4zeilig, rcall wait50us ldi temp1,0b00100000 ;funktionset nur für ReversDisplay rcall lcd_command ;DatenLine1=8bit, RE=0 (Unterfuntionen aus) , rcall wait50us ret lcd_reverse: ldi temp1,0b00101011 ;funktionset nur für ReversDisplay rcall lcd_command ;DatenLine1=8bit, N=1 2zeilig á 40 Zeichen d.h. 4zeilig á 20Zeichen rcall wait50us ret ;********Funktion Set für Displays OHNE RE-Bit Std-Display***************** entry_mode_std: ldi temp1,(1<<HES|1<<ID|0<<SH) rcall lcd_command ret lcd_on: ldi temp1,(1<<HD|1<<D|0<<C|0<<B) rcall lcd_command ret lcd_shift: ldi temp1,(1<<HS|0<<SC|1<<RL) rcall lcd_command ret lcd_function_set_std: ldi temp1,(1<<HSF|1<<DL|1<<N|0<<F) ;funktionset rcall lcd_command ;DatenLine1=8bit, N=1 2zeilig á 40 Zeichen d.h. 4zeilig á 20Zeichen ret ;**********************command***************************************** lcd_command:;SRS-PIN ist immer über int. pullup aktiv muss aber für lcd_cmd gelöscht mov xl,temp1 rcall data_chip ;RS = 0 weil Commands gesendet werden cbi port_lcd_x,SRW ;SRW-Pin löschen falls gesetzt sbi ddrx_lcd_x,SRS ;SRS ddr setzen cbi port_lcd_x,SRS ;SRS pullup deakt. rcall lcd_enable cbi ddrx_lcd_x,SRS ;SRS ddr löschen sbi port_lcd_x,SRS ;SRS pullup akt. ret ;**************************data**************************************** lcd_data:;SRS-PIN ist immer über int. pullup aktiv, weil wenn hier es erst aktiv wird shiftreg +1 weitershiftet mov xl,temp1 rcall data_chip ;RS = 1 weil Daten gesendet werden z.B.: 'A' cbi port_lcd_x,SRW rcall lcd_enable ret ;***********************Enable***************************************** lcd_enable: ;LCD soll Byte lesen sbi port_lcd_x,SEnable rcall wait50us cbi port_lcd_x,SEnable ret ;**********************daten seriel übertragen 74164******************* data_chip: ldi temp3,$08 ;1Byte = 8Bit data_chip_2: sbrc xl,7 ;wenn Bit 7 = 1 dann sbi port_lcd_x,SData ;den Pin auf 1 setzen sbrs xl,7 ;wenn Bit 7 = 0 dann cbi port_lcd_x,SData ;den Pin auf 0 setzen rcall clock_chip ;74164 Clocken zum shiften lsl xl ;links shiften Vorbereitung neues Bit dec temp3 cpi temp3,$00 ;Abbruchbedingung brne data_chip_2 ret clock_chip: ;Takt cbi port_lcd_x,SClock sbi ddrx_lcd_x,SClock rcall wait1us cbi ddrx_lcd_x,SClock sbi port_lcd_x,SClock rcall wait50us ret /* Falls in HW nicht genutzt wird dann in SW deaktivieren reset_chip: ;MUSS AUF 1 gesetzt werden damit der Chip cbi port_lcd_x,Rst ;daten shiftet rcall wait50us ;Kann auch extern mit einen PullUp am ResetPin sbi port_lcd_x,Rst ;beschaltet werden rcall wait50us ret */ ;*************************Ausgabe TXT********************************** txt_out:lpm temp1,z+ ;!!! muss der .db *2 genommen werden cpi temp1,$ff breq txt_out_end rcall lcd_data ;z.b.: ldi ZH,high(out0*2) rjmp txt_out txt_out_end: ret /*;Nur ein Zeichen Ausgeben falls erforderlich Zeichen in Sram definieren zeichen_out: ;adr rcall lcd_clearAX lds temp1,zeichen ;Zeichen rcall lcd_data ret */ ;**********Ausgabe Zahl Byte als ASCII zu LCD schicken lcd_zahlout_5: rcall load_Y_ergk ;Stellenangabe rjmp lcd_zahlout_X lcd_zahlout_4: rcall load_Y_ergk1 ;Stellenangabe rjmp lcd_zahlout_X lcd_zahlout_3: rcall load_Y_ergk2 ;Stellenangabe rjmp lcd_zahlout_X lcd_zahlout_2: rcall load_Y_ergk3 ;Stellenangabe rjmp lcd_zahlout_X lcd_zahlout_1: rcall load_Y_ergk4 ;Stellenangabe lcd_zahlout_X: ldi temp3,high(erg_k+5) ldi temp4,low(erg_k+5) lcd_zahlout_X_2: ld temp1,y+ ;DezZahl von RAM holen mov temp2,temp1 ;copieren swap temp1 ;Nibbletausch andi temp1,$0f ;unden ori temp1,$30 ;Wandlung in ASCII-Zahl rcall lcd_data ;ab in den Chip mov temp1,temp2 ;Nibbletausch andi temp1,$0f ;unden ori temp1,$30 ;Wandlung in ASCII-Zahl rcall lcd_data ;ab in den Chip brts lcd_zahlout_end cp yl,temp4 ;Abbruchbedingung brne lcd_zahlout_x_2 ;Sprung zu Label lcd_zahlout_end: clt ret lcd_licht_an: sbi Port_lcd_x,light ret lcd_licht_aus: cbi Port_lcd_x,light ret
Die Zeitschleifen ASM kann aus der Atmega8 Bibliothek kopiert werden das sich hier nix geändert hatCode:;********************TextAusgabeLCD********************************* werbe1: ldi temp1,0b10000000 rcall lcd_DDR_AdrX ldi ZH,high(out0*2) ldi ZL,low(out0*2) rcall txt_out ret werbe2: ldi temp1,0b11000000 rcall lcd_DDR_AdrX ldi ZH,high(out1*2) ldi ZL,low(out1*2) rcall txt_out ret wert_out: ldi temp1,0b11001000 rcall lcd_DDR_AdrX clr matherghh clr mathergh clr mathergl lds mathergll,ladc rcall hex_dez ;Wandlung von HEX in DEZ steht dierekt im RAM rcall lcd_zahlout_1 ret ;TESTANZEIGEN zum auslesen verschiedener Werte ;alles mit * sind Testwerte nur zu Demozwecken wert_out_all: ldi temp2,$ff ;* ldi temp1,$ff ;* ldi temp0,$ff ;* clr matherghh ;Schnittstelle mov mathergh,temp2 mov mathergl,temp1 mov mathergll,temp0 ;Wert laden rcall hex_dez ldi temp1,0b11001000 rcall lcd_DDR_AdrX ;ADRx -> LCD rcall lcd_zahlout_5 ;um hier Abbruch zu schaffen ldi temp1,'?' ;Masseinheit = ? rcall lcd_data ;Punkt setzen ret wert_out_4: rcall werbe2 ;2te Zeile überschreiben ldi temp2,$ff ;* ldi temp1,$ff ;* ldi temp0,$ff ;* clr matherghh mov mathergh,temp2 ;Schnittstelle mov mathergl,temp1 mov mathergll,temp0 ;Wert laden rcall hex_dez ldi temp1,0b11001000 rcall lcd_DDR_AdrX ;ADRx -> LCD set ;T-Flag setzen rcall lcd_zahlout_4 ;um hier Abbruch zu schaffen ldi temp1,'.' ; rcall lcd_data ;Punkt setzen rcall lcd_zahlout_3 ;Nachkommastellausgabe komplett ldi temp1,'?' ;Masseinheit = ? rcall lcd_data ;Punkt setzen ret wert_out_4_2: rcall werbe2 ;2te Zeile überschreiben ldi temp2,$ff ;* ldi temp1,$ff ;* ldi temp0,$ff ;* clr matherghh mov mathergh,temp2 ;Schnittstelle mov mathergl,temp1 mov mathergll,temp0 ;Wert laden rcall hex_dez ldi temp1,0b11001000 rcall lcd_DDR_AdrX ;ADRx -> LCD set ;T-Flag setzen rcall lcd_zahlout_4 ;um hier Abbruch zu schaffen ldi temp1,'.' ; rcall lcd_data ;Punkt setzen set rcall lcd_zahlout_3 ;nur bestimmte Nachkommastellausgabe set rcall lcd_zahlout_2 ;nur bestimmte Nachkommastellausgabe ldi temp1,'?' ;Masseinheit = ? rcall lcd_data ;Punkt setzen ret wert_out_2: rcall werbe2 ldi temp1,$03 ldi temp0,$ff clr matherghh clr mathergh ;Schnittstelle mov mathergl,temp1 mov mathergll,temp0 ;Wert laden rcall hex_dez ldi temp1,0b11001000 rcall lcd_DDR_AdrX ;ADRx -> LCD set ;T-Flag setzen rcall lcd_zahlout_2 ;um hier Abbruch zu schaffen ldi temp1,'.' ; rcall lcd_data ;Punkt setzen rcall lcd_zahlout_1 ldi temp1,'?' ;Masseinheit = ? rcall lcd_data ;Punkt setzen ret ;************************direktwandlung*wort*in*ASCII*************** ; * + *=16Stellen/+=20stellen ; "0123456789ABCDEF01234" out0: .db " LCD-Test AVR ",$ff out1: .db "Zahlen: ",$ff
hier der Schaltplan
LCD 8Bit Ser.pdf![]()







Zitieren

Lesezeichen