PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : impulse messen und via rs232 ausgeben



moto
28.02.2008, 15:48
hallo miteinander,

ich habe ein kleines "roboter fremdes" problem (auser man sieht wie ich eine jura e55 als roboter an...)

und zwar (entschuldigt bitte meine wort wahl) kotzt mich der funktionsumfang des, eigentlich guten, VAs seit einiger zeit an... daher bin ich atm dabei dem ding einen avr als "gehirn" zu schenken und nach und nach neue funktionen ein zubauen...

das zur vorgeschichte... bis jetzt hab ich daran noch absolut nichts gemacht auser kleine hardware änderungen (mechanik)...

jetzt zu meiner frage (entschuldigt bitte die frage schon im vorraus ich bin totaler anfänger und hab mir bis jetzt erst mal das tut auf mikrocontroller.net angeschaut und kleine led leuchte/blink programme gebaut... jetzt brächte ich einen daten logger der einen poti ausliest (konstanter wert zwischen 0 und 5V über die messdauer) und impulse (von einem flowmeter) an einem eingang zählt (mehr als 256)... die messwert erfassung soll mit einem taster gestartet werden und mit einem anderen taster dann per rs232 gesendet werden so das ich es dann auf dem pc "auswerten" kann...

das problem ist jetzt das ich das mit dem senden und analogwert erfassen (warscheinlich) hinbekomme ich aber absolut keine idee habe wie ich das mit den impulsen machen soll... ich hoffe einer von euch profis kann mir da weiter helfen...

vielen dank schon mal und bis später (entlich feierabend xD)

gruß rezzo

zerush
28.02.2008, 16:33
Bei den ATMegas kannst du einen Timer/Counter so einstellen, dass er als Counter arbeitet. Du stellst also als Taktgeber eine externe Quelle ein. Der Counter zählt dann immer bei einer steigenden oder fallenden (einstellbar) um 1 hoch.
Bei einem 16Bit Timer (Timer1 beim Mega32) reicht der Bereich bis 65535. Diesen Wert kannst du jederzeit aus den Registern TCNT1H (high byte) und TCNT1L (low byte) auslesen.

mfg
zerush

moto
28.02.2008, 17:53
super danke das bringt mich meinem "neuen" VA wieder 5 schritte näher... gleich das proggi basteln und im VMlab testen... ich werde berichten...

moto
28.02.2008, 19:07
-.- sorry für doppelpost

also ich hab das jetzt mal (denke ich) soweit das fast alles tut... nur wie kann ich den timer auslesen?


edit:

hier mal mein code:

.include "m8def.inc"

.def temp = r16 ; Register für kleinere Arbeiten
.def zeichen = r17 ; in diesem Register wird das Zeichen an die
; Ausgabefunktion übergeben
.def adlow = r18 ; Register für lowbyte adc
.def adhigh = r19 ; Register für highbyte adc
.def impulsL = r20 ; Register für lowbyte timer
.def impulsH = r21 ; Register für highbyte timer
.def run = r22 ; Register für programmselektion

.equ F_CPU = 4000000 ; Systemtakt in Hz
.equ BAUD = 9600 ; Baudrate

; Berechnungen
.equ UBRR_VAL = ((F_CPU+BAUD*8)/(BAUD*16)-1) ; clever runden
.equ BAUD_REAL = (F_CPU/(16*(UBRR_VAL+1))) ; Reale Baudrate
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000) ; Fehler in Promille

.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10)) ; max. +/-10 Promille Fehler
.error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
.endif

.org 0x000
rjmp main ; Reset Handler
.org URXCaddr ; Interruptvektor für UART-Empfang
rjmp int_rxc



; Hauptprogramm





main:

; Stackpointer initialisieren

ldi temp, LOW(RAMEND)
out SPL, temp
ldi temp, HIGH(RAMEND)
out SPH, temp

; Baudrate einstellen

ldi temp, HIGH(UBRR_VAL)
out UBRRH, temp
ldi temp, LOW(UBRR_VAL)
out UBRRL, temp

; Timer Init
ldi temp, 0b00000110 ; CS10-12: Ext.Takt neg.Flanke
out TCCR1B, temp


; Frame-Format: 8 Bit

ldi temp, (1<<URSEL)|(3<<UCSZ0)
out UCSRC, temp

sbi UCSRB,TXEN ; TX aktivieren

ldi temp, (1<<URSEL)|(3<<UCSZ0)
out UCSRC, temp

sbi UCSRB, RXCIE ; Interrupt bei Empfang
sbi UCSRB, RXEN ; RX (Empfang) aktivieren

sei ; Interrupts global aktivieren

; ADC initialisieren: Single Conversion, Vorteiler 128
; Kanal 0, interne Referenzspannung AVCC

ldi temp, (1<<REFS0)
out ADMUX, temp
ldi temp, (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)
out ADCSRA, temp


loop:
cpi run, 0x0F ; run mit '0F' vergleichen (Send)
BREQ send ; wenn gleich, dann zu send
cpi run, 0xF0 ; run mit 'F0 vergleichen (Get
BREQ get ; wenn gleich, dann zu get

rjmp loop ; Endlosschleife

get:
sbi ADCSRA, ADSC ; den ADC starten

adc_warten:
sbic ADCSRA, ADSC ; wenn der ADC fertig ist, wird dieses Bit gelöscht
rjmp adc_warten

in adlow, ADCL ; LOW Byte lesen
in adhigh, ADCH ; High Byte lesen


;;HIER TIMER ROUTINE EINFÜGEN;;




send:
ldi zl,low(my_string*2); ; Z Pointer laden
ldi zh,high(my_string*2);
rjmp uart_warten
out UDR, adlow
rjmp uart_warten
out UDR, adhigh
rjmp uart_warten
out UDR, impulsL
rjmp uart_warten
out UDR, impulsH
rjmp uart_warten
serout_string:
lpm ; nächstes Byte aus dem Flash laden
and r0,r0 ; = Null?
breq serout_string_ende ; wenn ja, -> Ende
serout_string_wait:
sbis UCSRA,UDRE ; Warten bis UDR für das nächste
; Byte bereit ist
rjmp serout_string_wait
out UDR, r0
adiw zl:zh,1 ; Zeiger erhöhen
rjmp serout_string ; nächstes Zeichen bearbeiten
serout_string_ende:
rjmp loop ; zurück zum Hauptprogramm










; Interruptroutine: wird ausgeführt sobald ein Byte über das UART empfangen wurde

int_rxc:
push temp ; temp auf dem Stack sichern
in temp, sreg ; SREG sichern
push temp

in temp, UDR ; UART Daten lesen
cpi temp, 0x53 ; empfangenes Byte mit '53' (S) vergleichen
brne int_rxc_1 ; wenn nicht gleich, dann zu int_rxc_1
ldi run, 0x0F ; run auf 0F setzen (daten senden)
rjmp int_rxc_3 ; Zu int_rxc_3 springen

int_rxc_1:
cpi temp, 0x52 ; empfangenes Byte mit '52' (R) vergleichen
brne int_rxc_2 ; wenn nicht gleich, dann zu int_rxc_2
ldi run, 0xF0 ; run auf F0 setzen (daten erfassen)
rjmp int_rxc_3 ; Zu int_rxc_3 springen

int_rxc_2:
ldi run, 0x00 ; run auf 00 setzen (idle)
rjmp int_rxc_3 ; Zu int_rxc_3 springen

int_rxc_3:
pop temp
out sreg, temp
pop temp
reti

uart_warten:
sbis UCSRA,UDRE ; Warten bis UDR für das nächste
; Byte bereit ist
rjmp uart_warten
ret

my_string: .db "Ende",10,13,0

zerush
28.02.2008, 20:26
Ich bin nicht so der Assembler Profi, aber es sollte

in tlow, TCNT1L ; LOW Byte lesen
in thigh, TCNT1H ; High Byte lesen

sein.