Forum: Mikrocontroller und Digitale Elektronik Frequenzmessung mit übertragung an RS232


von Pascal Enz (Gast)


Lesenswert?

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...

von Pascal Enz (Gast)


Lesenswert?

;***************************************************************
;*
;* 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

von Klaus (Gast)


Lesenswert?

>Was habe ich im Code übersehen?

Habe ich den Code übersehen?

von Gast (Gast)


Lesenswert?

>Habe ich den Code übersehen?

Bist Du aber blind :-)

von rene (Gast)


Lesenswert?

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.

von Pascal Enz (Gast)


Lesenswert?

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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.