;########################################### ;# Projekt: ADC Testprogramm # ;# # ;# 1--------GND # ;# 2--------VCC # ;# 3---Poti-10K # ;# 4-----RS--B4 # ;# 5----RW--GND # ;# 6------E--B5 # ;# 11--Bit5--B0 # ;# 12--Bit6--B1 # ;# 13--Bit7--B2 # ;# 14--Bit8--B3 # ;# # ;# # ;# Erstellt am: # ;# # ;# Taktfrequenz des AVR: 4 MHz # ;# # ;# CS-SOFT # ;########################################### .include "m8def.inc" ;Atmega8 ;.include "2313def.inc" ; Viele definierte Register werden nicht gebraucht .DEF rd1lh = R0 ; LSB Divident Multiplikator 1 (8 Bit) .DEF rd1l = R1 ; LSB Divident Multiplikator 1 (8 Bit) .DEF rd1h = R2 ; MSB Divident Hilfsregister für Multiplikation .DEF rd2h = R3 ; MSB Divident Hilfsregister für Multiplikation .DEF rd3h = R4 ; MSB Divident Hilfsregister für Multiplikation .DEF rd1u = R5 ; Hifsregister Multiplikator 2 (1-8 Bit) .DEF rd2u = R6 ; Hifsregister Multiplikator 2 (9-16 Bit) .DEF rd3u = R7 ; Hifsregister Multiplikator 2 (16-24 Bit) .DEF rel = R8 ; LSB Ergebnis Ergebnis, LSB (16 Bit) = zehner und einer .DEF reh = R9 ; MSB Ergebnis Ergebnis, MSB1 = tauserder und hunderter .DEF reh2 = R10 ; Ergebnis, MSB2 .DEF rd2 = R11 ; Divisor ;.def disp = r12 ; Zähler für Sekundenausgabe .def BCD0 = r13 .def BCD1 = r14 ; .def BCD2 = r15 ;Speicherregister für Status des Hauptprogr. .def temp0 = r16 ;da ein Verknüpfung mit .def temp1 = r17 ;dem Infodisplay geplant ist. .def temp2 = r18 .def temp3 = r19 ;Registerbezeichnung bleibt, .def temp4 = r20 .def cnt = r21 .def sek = r22 .def WorkH = r23 ; Arbeitsregister für das Hauptprogramm .def Count1= r24 ; Zähler der Interrupts .def Count2= r25 ; Zählt die festgelegten sek runter ;;;;;;$0060 benutzt ;;;;;;$0061 benutzt ;;;;;;$0062 benutzt .equ Hadc=$0063 ; .equ Ladc=$0064 ; .equ Madc=$0065 ; ;.equ =$0066 ; ;.equ =$0067 ; ;.equ =$0068 ; ;.equ =$0069 ; ;.equ =$006a ; ;.equ =$006b ; ;.equ =$006c9 ; ;.equ =$006d ; ;.equ =$0090 ; ;.equ =$0091 ; ;.equ =$0092 ; ;.equ =$0093 ; ;.equ =$0094 ; ;.equ =$0095 ; ;.equ =$0096 ; ;.equ =$0097 ; ;.equ =$0098 ; ;.equ =$0099 ; ;.equ =$009a ; ;.equ Prozent = $25 ;Wert für % Zeichen erhalten ;.equ Time = 125 ; Anzahl der Taktimpulse bis zum nächsten Int. ; 120 Impulse bei F = 4 MHz -> 10us-Intervall ;***************************Einsprungadressen*********************** .cseg .org $0000 rjmp Reset .org $000e rjmp adc_read Reset: rjmp stack reti reti reti reti reti ;***************************Init mit allem drumdran***************** stack: ldi temp1,high(ramend) ;Stackpointer festlegen out sph, temp1 ldi temp1,low(ramend) ;Stackpointer festlegen out spl, temp1 rcall sram ldi temp0,$3f out ddrb,temp0 clr temp0 out ddrd,temp0 rcall lcd_init rcall lcd_clear rcall wait1s ldi temp1,0b10000000 rcall test ldi temp1,0b11000000 rcall test1 rcall wait1s rcall lcd_clear ldi temp1,0b10000101 rcall adc_out_l ;ldi temp1,0b10000011 ;rcall adc_out_m ldi temp1,0b10000010 rcall point ldi temp1,0b10000000 rcall adc_out_h start: rcall adc_header ldi temp1,0b10000101 rcall adc_out_l ;ldi temp1,0b10000011 ;rcall adc_out_m ldi temp1,0b10000000 rcall adc_out_h ldi temp0,$64 rcall waitxms rjmp start ;************************Unterprogramme****************************** ;************************Ausgabe************************************ test: rcall lcd_clearAX ldi ZH,high(out0) ldi ZL,low(out0) ldi cnt,$14 ;8 Zeichen im Display ansteuern rcall txt_out ret test1: rcall lcd_clearAX ldi ZH,high(out1) ldi ZL,low(out1) ldi cnt,$14 ;8 Zeichen im Display ansteuern rcall txt_out ret point: rcall lcd_clearAX ldi ZH,high(out2) ldi ZL,low(out2) ldi cnt,$01 ;8 Zeichen im Display ansteuern rcall txt_out ret adc_out_l: rcall lcd_clearAX lds temp1,ladc rcall Zahldezi ;Hex in Dezimal rcall Zahlout4 ;DezimalWert 2 Stellen ret adc_out_m: rcall lcd_clearAX lds temp1,madc rcall Zahldezi ;Hex in Dezimal rcall Zahlout2 ;DezimalWert 2 Stellen ret adc_out_h: rcall lcd_clearAX lds temp1,hadc rcall Zahldezi ;Hex in Dezimal rcall Zahlout2 ;DezimalWert 2 Stellen ret ;************************direktwandlung*wort*in*ASCII*************** out0: .db " ADC-Test " out1: .db " AT-Mega8 " out2: .db "." ;*************************weitere*includedata*********************** .include "adc_lst.asm" .include "lcd_initb.asm" ;*************************ENDE************************************** ;******************************adc_interrupt********************** ;.org $000e ; rjmp adc_read adc_read: in temp0,adcl sts ladc,temp0 in temp1,adch sts hadc,temp1 set ret ;***********************adc_header************************** adc_header: rcall adc_init rcall convers_init rcall start_convers ret ;***********************adc_init***************************** adc_init: clt ldi temp0,$c0 ;laden von refquelle out admux,temp0 ;u. mux.x ret convers_init: ldi temp0,$87 out adcsra,temp0 ret start_convers: in temp0,adcsra ori temp0,$48 out adcsra,temp0 sei start_convers2: brtc start_convers2 ret ;**********************Masterclr*************************************** sram: clr temp0 clr temp1 ldi r28,low($0060) ldi r29,high($0060) sram2: inc temp1 ;Masterclr des Sram's über st y+,temp0 ;die indirekte Adressierung cpi temp1,$10 ;anzahl der zellen zum löschen breq sramstopp ; rjmp sram2 sramstopp: ret ;*************************LCDinit************************************** lcd_init: ldi temp0,$64 ;20ms warten rcall waitxms ldi temp1,0b00110000 ;??? out portB,temp1 rcall wait100us ;warten bis daten da sind rcall lcd_enable ;enablen ldi temp0,$01 ;10ms warten rcall waitxms rcall lcd_enable ;enablen rcall wait1ms rcall lcd_enable ;enablen rcall wait100us ldi temp1,0b00000010 ;4bit mod einstellen out portB,temp1 rcall wait100us ;warten rcall lcd_enable ldi temp0,$01 rcall waitxms ldi temp1,0b00101000 ;funktionset rcall lcd_command ldi temp1,0b00001100 ;display on rcall lcd_command ldi temp1,0b00000110 ;entry mod set rcall lcd_command ret lcd_clear: ldi temp1,$01 rcall lcd_command ldi temp0,$0a rcall waitxms ret lcd_enable: sbi portB,5 rcall wait50us cbi portB,5 ret ;**********************command***************************************** lcd_command: rcall wait100us mov temp2,temp1 swap temp1 andi temp1,$0f out portB,temp1 rcall wait100us1 rcall lcd_enable rcall wait100us1 andi temp2,$0f out portB,temp2 rcall wait100us1 rcall lcd_enable rcall wait100us1 cbi portb,4 ret ;**************************data**************************************** lcd_data: mov temp2,temp1 swap temp1 andi temp1,$0f sbr temp1,1<<4 out portB,temp1 rcall wait100us1 rcall lcd_enable rcall wait100us1 andi temp2,$0f sbr temp2,1<<4 out portB,temp2 rcall wait100us1 rcall lcd_enable rcall wait100us1 cbi portB,4 ret ;*************************Ausgabe TXT********************************** lcd_clearAX: rcall lcd_command ldi temp0,$0a rcall waitxms ret txt_out:lsl zl rol zh txt_o1: lpm mov temp1,R0 rcall lcd_data adiw zl,$01 dec cnt brne txt_o1 ret ;*************************AUSGBAE zahlen******************************** Zahldezi: clr temp2 clr temp3 clr temp4 rcall HexBCD ;HexZahl wird in BCD umgerechnet sts $0060, BCD2 ;zur Sicherung in Speicher schieben sts $0061, BCD1 sts $0062, BCD0 ret ;Hexadezimalzahl wird auf Dezimalzahl umgerechnet xxxx (Hex) -> 0abcde (BCD) HexBCD: rcall Div10 ; hexH:hexL / 10, Rest in tmp1.. mov BCD0,temp3 ; ..Erg. in hexH:hexL, tmp1 = Digit1 rcall Div10 ; Rest = Digit2 swap temp3 ; Digit2 ins High-Nibble or BCD0,temp3 ; Digit2, Digit1 in BCD0 kombiniert rcall Div10 ; Rest = Digit3 mov BCD1,temp3 ; nach BCD1 rcall Div10 ; Rest = Digit4 swap temp3 ; Digit4 ins High-Nibble or BCD1,temp3 ; Digit4, Digit3 in BCD1 kombiniert mov BCD2,temp1 ; Digit5 nach BCD2, High-Nibble = 0 ret ; dividiert hexH:hexL durch 10,Erg. in hexH:hexL, Rest in tmp1 Div10: clr temp3 lsl temp1 rol temp2 rol temp3 ; die Division der höchstwertigsten lsl temp1 ; drei Bits durch 10 kann nur Null rol temp2 ; ergeben rol temp3 lsl temp1 rol temp2 rol temp3 ldi cnt,13 ; Zähler für restl. 13 Bits Loop10: lsl temp1 ; Divident um 1 nach links rol temp2 rol temp3 ; Überlauf in tmp1 subi temp3,10 ; Test: Überlauf > 10 ? brlo HB1 ; Sprung, wenn nicht inc temp1 ; Divisionszähler um 1 inkrem. rjmp HB2 HB1: subi temp3,-10 ; Test rückgängig machen HB2: dec cnt ; Bitzähler dekrementieren brne Loop10 ; Sprung, wenn noch nicht alle Bits ret Zahlout6: mov temp1,BCD2 ;100 tausend und 10 tausend rcall LCD_Zahl ;Zahl wird für LCD vorbereitet rcall Zahl_out Zahlout4: mov temp1,BCD1 ;1 tausend und 100 rcall LCD_Zahl ;Zahl wird für LCD vorbereitet rcall Zahl_out Zahlout2: mov temp1,BCD0 ;10ner und 1ner rcall LCD_Zahl ;Zahl wird für LCD vorbereitet rcall Zahl_out ret Zahl_out: ldi cnt,$3 mov temp1,ZL ;BCD aus R30 laden rcall lcd_data ;1.Ziffer ausgeben mov temp1,ZH ;BCD aus R31 laden rcall lcd_data ;2.Ziffer ausgeben ret ;Zahl wird für Ausgabe vorbereitet LCD_Zahl: push temp1 swap temp1 rcall Lcd4PBcd1 mov ZL, temp1 pop temp1 rcall Lcd4PBcd1 mov ZH, temp1 ret Lcd4PBcd1: andi temp1, 0x0f ori temp1, 0x30 ret ;************************zeitschleifen****************************************** wait1us:nop ret wait50us: ldi temp4,$41 wait50us1: dec temp4 brne wait50us1 ret wait100us: ldi temp4,$83 wait100us1: dec temp4 brne wait100us1 ret wait1ms:ldi temp3,$06 wait1ms1: ldi temp4,$df wait1ms2: dec temp4 brne wait1ms2 dec temp3 brne wait1ms1 ret waitxms: rcall wait1ms dec temp0 brne waitxms ret wait1s: ldi temp1,$0a wait1s1:ldi temp2,$63 wait1s2:rcall wait1ms dec temp2 brne wait1s2 dec temp1 brne wait1s1 ret ;**************************ende**************************************************