Mikrocontroller und Digitale Elektronik
›
Thread
Frequenzmessung mit übertragung an RS232
PE
Pascal Enz
Gast
25.11.2008 13:31
#1058481
Guten Tag
im Anhang mein Programm.
(Target ATMEGA128 )
Es wird ein Laserstrom über ADC gemessen -> funktioniert
Daten werden über RS232 übertragen -> läuft
Frequenz wird über den ICP1 gemessen.
über das Terminal gibt er mir sobald ich ein "f" sende
(Frequenzmessungsroutine) eine unmengen an Daten zurück.
Jedoch nix brauchbares.
Was habe ich im Code übersehen?
Danke für die Antwort.
Mit besten Grüssen aus dem kleinen Nachbarländchen...
PE
Pascal Enz
Gast
25.11.2008 13:32
#1058483
;***************************************************************
;*
;* Project Adressboard-EDM
;*
;* Project Description Here
;*
;***************************************************************
;*
;* Author: Pascal Enz
;* Lab: 3044
;* Date: 1.9.08
;*
;***************************************************************
.include "m128def.inc" ; Definition file for ATmega128
.include "macros.inc"
#define F_CPU 1000000
;***************************************************************
;* Program Constants
;***************************************************************
.equ const =$00 ; Generic Constant Structure
.equ baud = 2400
.equ UBRR_VAL = ((F_CPU+BAUD*8)/(BAUD*16)-1)
.equ BAUD_REAL = (F_CPU/(16*(UBRR_VAL+1)))
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)
.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))
.error "Baudrate grösser 1 Prozent"
.endif
;***************************************************************
;* Program Variables Definitions
;***************************************************************
.def temp = r16
.def zeichen = r17
.def mpr = r18
.def testzeichen = r19
.def adapterwahl = r20
.def stacktemp = r21
.def nummer = r22
.def overflow = r23
.def flanke = r24
.def time11 = r1
.def time21 = r2
.def time12 = r3
.def time22 = r4
.def finito = r25
;***************************************************************
;* Interrupt Vectors
;***************************************************************
.cseg
.org $0000 ; Define start of Code segment
ldi overflow,0
rjmp RESET ; Reset Handler
.org $0016
rjmp Auswert
.org $001C
rjmp TIMER_OVER
reti ; IRQ0 Handler
nop
reti ; IRQ1 Handler
nop
reti ; Timer2 Compare Handler
nop
reti ; Timer2 Overflow Handler
nop
reti ; Timer1 Capture Handler
nop
reti ; Timer1 CompareA Handler
nop
reti ; Timer1 CompareB Handler
nop
reti ; Timer1 Overflow Handler
nop
reti ; Timer0 Overflow Handler
nop
reti ; SPI Transfer Complete Handler
nop
reti ; USART RX Complete Handler
nop
reti ; UDR Empty Hanlder
nop
reti ; USART TX Complete Handler
nop
reti ; ADC Conversion Complete Handler
nop
reti ; EEPROM Ready Hanlder
nop
reti ; Analog Comparator Handler
nop
reti ; Two-wire Serial Interface Handler
nop
reti ; Store Program Memory Ready Handler
nop
;***************************************************************
;* Func: RESET
;* Desc: Reset Handler Routine
;***************************************************************
RESET:
; ***** Stack Pointer Init *****
ldi mpr, LOW(RAMEND)
out SPL, mpr
ldi mpr, HIGH(RAMEND)
out SPH, mpr
ldi mpr,0b11111111
out DDRC,mpr
ldi temp,high(UBRR_VAL)
sts UBRR1H,temp
ldi temp,low(UBRR_VAL)
sts UBRR1L,temp
lds temp,UCSR1B
sbr temp,0b00011000
sts UCSR1B,temp
ldi mpr, 0b00001000
out DDRD,mpr
ldi finito,0
rjmp init
;***************************************************************
;* Func: MAIN
;* Desc: Main Entry into program
;***************************************************************
init:
ldi zeichen, 'E'
rcall serout
ldi zeichen, 'D'
rcall serout
ldi zeichen, 'M'
rcall serout
ldi zeichen, '-'
rcall serout
ldi zeichen, 'A'
rcall serout
ldi zeichen, 'd'
rcall serout
ldi zeichen, 'a'
rcall serout
ldi zeichen, 'p'
rcall serout
ldi zeichen, 't'
rcall serout
ldi zeichen, 'e'
rcall serout
ldi zeichen, 'r'
rcall serout
ldi zeichen, '-'
rcall serout
ldi zeichen, 'V'
rcall serout
ldi zeichen, '.'
rcall serout
ldi zeichen, '1'
rcall serout
ldi zeichen, 13
rcall serout
ldi zeichen, 10
rcall serout
;< Insert your program Here>
sbi ADMUX,REFS0
cbi ADMUX,REFS1
cbi ADMUX,MUX0
cbi ADMUX,MUX1
cbi ADMUX,MUX2
cbi ADMUX,MUX3
cbi ADMUX,MUX4
sbi ADCSRA,ADEN
ldi mpr,0b00000000
out PORTC,mpr
rjmp main
;***************************************************************
;* Func: MAIN
;* Desc: Main Entry into program
;***************************************************************
MAIN:
ldi flanke,0
ldi finito,0
ldi overflow,0
polling_at:
load temp, UCSR1A
sbrs temp, RXC1
rjmp polling_at
lds temp,UDR1 ; UART Polling zum abwarten des Befehls
ldi mpr,'d'
cp temp,mpr
breq dagoon; Transistor durchschalten - Gerät1 on
ldi mpr,'a'
cp temp,mpr
breq atron; Transistor durchschalten - Gerät2 on
ldi mpr,'o'
cp temp,mpr
breq hardoff; Transistor sperren - all off
ldi mpr,'l'
cp temp,mpr
breq adcstart; Laserstrommessung durchführen
ldi mpr,'f'
cp temp,mpr
breq timeinit; Counter1 initialisieren
rjmp MAIN
adcstart:
sbi ADCSRA,ADIE
sbi ADCSRA,ADSC
adcloop:
load temp,ADCSRA
sbrs temp,ADIF
rjmp adcloop
in zeichen, ADCL
rcall serout
in zeichen, ADCH
rcall serout
rjmp Main
hardoff:
ldi mpr,0b00000000
out PORTC,mpr
rjmp MAIN
dagoon:
ldi mpr,0b00001000
out PORTC,mpr
rjmp MAIN
atron:
ldi mpr,0b00001100
out PORTC,mpr
rjmp MAIN
serout:
lds temp,UCSR1A; Übertragungsroutine RS232
sbrs temp,5
rjmp serout
sts UDR1,zeichen
ret
USART_Rec:
lds temp, UCSR1A
sbrs temp,7
rjmp USART_Rec
lds r16, UDR1
ret
TIMER_OVER: ; Timer1 Overflow Interrupt
cli
ldi mpr,1
add overflow,mpr
sei
reti
timeinit: ; Initialisierung Timer1
load temp, TCCR1A
sbr temp, (0<<COM1A1)
sbr temp, (0<<COM1B1)
sbr temp, (0<<COM1C1)
sbr temp, (0<<WGM11)
sbr temp, (0<<WGM10)
store TCCR1A,temp
load temp,TCCR1B
sbr temp, (1<<ICNC1)
sbr temp, (1<<ICES1)
sbr temp, (1<<CS10)
sbr temp, (0<<CS11)
sbr temp, (1<<CS12)
store TCCR1B,temp
load temp, TIMSK
sbr temp, (1<<TOIE1)
sbr temp, (1<<TICIE1)
store TIMSK,temp
sei
rjmp freqmeas
auswert: ; erste Flanke an ICP1
cli
ldi mpr,0 ; flag für erste Flanke
cp flanke,mpr
brne secflank
ldi overflow,0
in zeichen,ICR1L ;zeichen für RS232
rcall serout ; rs232 übertragung
in zeichen,ICR1H
rcall serout
ldi flanke,1
sei
reti
secflank: ; zweite Flanke an ICP1
cli
ldi flanke,0
in zeichen,ICR1L
rcall serout
in zeichen,ICR1H
rcall serout
mov zeichen,overflow
rcall serout
ldi finito,1
reti
freqmeas: ; loop-routine der frequenzmessung
ldi mpr,1
cp finito,mpr
brne freqmeas
cli
rjmp main
K
Klaus
Gast
25.11.2008 13:33
#1058484
>Was habe ich im Code übersehen?
Habe ich den Code übersehen?
G
Gast
Gast
25.11.2008 13:35
#1058489
>Habe ich den Code übersehen?
Bist Du aber blind :-)
R
rene
Gast
25.11.2008 14:38
#1058571
Das ist aber duesterste Klempnerei. In den Interrupts muss man die
Interrupts nicht abschalten, sind sie bereits. Es gibt gewisse
interrupts, da muss man mehr machen als nur ein reti, sonst beleibt die
Bedingung bestehen. Zudem muss man in einem Interupt das Statusregister
wegspeichern und restoren sonst ist eh nichts.
Als beispiel schau dir mal
http://www.ibrtses.com/embedded/avr.html
an. Da hat's auch ein paar beispiele.
PE
Pascal Enz
Gast
25.11.2008 14:57
#1058588
Danke für die rasche Antwort.
Ja, man wird wohl merken, dass ich bereits seit zwei Jahren nichts mehr
in Assembler geschrieben habe...
Also habe, die Overflow, resp Capture Interrupt mit Push und Pop (SREG)
erweitert.
Zudem habe ich die CLI SEI anderst gesetzt.
Nach meinen Überlegungen müsste nach einer kompletten Signalperiode das
Programm wieder ins Main springen.
Ich bekomme nun eine wahre Datenflut rein über RS232.
Wie bekomme ich das sonst noch besser geklemptnert? Irgendwelche smarte
Ideen?
1 TIMER_OVER: ; Timer1 Overflow Interrupt
2 push r5
3 in r5,SREG
4 push r5
5 ldi mathreg,1
6 add overflow,mathreg
7 pop r5
8 out SREG,r5
9 pop r5
10 reti
11
12 timeinit: ; Initialisierung Timer1
13 load temp, TCCR1A
14 sbr temp, (0<<COM1A1)
15 sbr temp, (0<<COM1B1)
16 sbr temp, (0<<COM1C1)
17 sbr temp, (0<<WGM11)
18 sbr temp, (0<<WGM10)
19 store TCCR1A,temp
20 load temp,TCCR1B
21 sbr temp, (1<<ICNC1)
22 sbr temp, (1<<ICES1)
23 sbr temp, (1<<CS10)
24 sbr temp, (0<<CS11)
25 sbr temp, (1<<CS12)
26 store TCCR1B,temp
27 load temp, TIMSK
28 sbr temp, (1<<TOIE1)
29 sbr temp, (1<<TICIE1)
30 store TIMSK,temp
31 sei
32 rjmp freqmeas
33
34 auswert: ; erste Flanke an ICP1
35 push r5
36 in r5,SREG
37 push r5
38 ldi mpr,0 ; flag für erste Flanke
39 cp flanke,mpr
40 brne secflank
41 ldi flanke,1
42 ldi overflow,0
43 in zeichen,ICR1L ;zeichen für RS232
44 rcall serout ; rs232 übertragung
45 in zeichen,ICR1H
46 rcall serout
47 pop r5
48 out SREG,r5
49 pop r5
50
51 reti
52
53 secflank: ; zweite Flanke an ICP1
54
55 ldi flanke,0
56 in zeichen,ICR1L
57 rcall serout
58 in zeichen,ICR1H
59 rcall serout
60 mov zeichen,overflow
61 rcall serout
62 ldi finito,1
63 pop r5
64 out SREG,r5
65 pop r5
66 cli
67 reti
68
69
70 freqmeas: ; loop-routine der frequenzmessung
71
72 ldi mpr,1
73 cp finito,mpr
74 brne freqmeas
75 cli
76 rjmp main
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.
Noch kein Account?
Die Registrierung ist kostenlos und dauert nur eine Minute.
Jetzt registrieren