Surveyor
10.04.2007, 20:22
Hi,
Ich möchte Daten vom AD-Wandler über den USB-Bus übertragen. Leider gibt es ein Problem und zwar werden mehr Bytes übertragen als ich senden will. Das Programm sieht folgendermaßen aus:
;
; uC: Atmel, AT90s2333
;
;
; Used PINs:
;
; +5V, GND - power supply
; ADC0...ADC5 - ADC
;
; PD0..7 - Data I/O
;
; PB0 - RXF# (IN)
; PB1 - TXF# (IN)
; PB2 - WR (OUT)
; PB3 - RD# (OUT)
;
; Further connection for XTAL and ADC see manual.
; (8 MHz)
.include "2333def.inc"
;***** Register definitions *****
.equ tmp, 16
.equ data, 17
.equ adc_lo, 18
.equ adc_hi, 19
.equ bool, 20
;***** Bit definitions **********
.equ RXF, 0 ; bit number
.equ TXF, 1 ; bit number
.equ WR, 2 ; bit value
.equ RD, 3 ; bit value
;***** Interrupt Vectors ********
RJMP RESET ; Reset - Hardware Pin, Power-on Reset, Watchdog Reset
reti ; INT0 - external interrupt request 0
reti ; INT1 - external interrupt request 1
reti ; Timer1 capt1 - timer/counter1 capture event
reti ; Timer1 comp1 - timer/counter1 compare mach
reti ; Timer1 ovf1 - timer/counter1 overflow
reti ; Timer0 ovf0 - timer/counter0 overflow
reti ; SPI - SPI interrupt
reti ; Uart, Rx - UART, RX complete
reti ; Uart, UDRE - Uart Data Register Empty
reti ; Uart, Tx - Uart, TX complete
RJMP ADC_Interrupt ; ADC - ADC interupt
reti ; EEPROM - EEPROM Interrupt
reti ; Ana_comp - Analog Comparator
ADC_Interrupt:
IN r0,SREG
IN adc_lo,ADCL
IN adc_hi,ADCH
LDI bool,1
OUT SREG,r0
reti
SendData:
LDI tmp,0xFF ; PORTD as ouput
OUT DDRD,tmp
LDI adc_lo,65
LDI adc_hi,65
LDI tmp,0x00 ; select channel 0
OUT ADMUX,tmp
LDI tmp,0xCF ; start AD conversion
OUT ADCSR,tmp
LDI bool,0
WAIT:
CPI bool,1
BRNE WAIT
LDI tmp,0
OUT PORTD,adc_lo ; send low byte
SBI PORTB,WR ; set WR bit
CBI PORTB,WR ; clear WR bit
LDI tmp,0
OUT PORTD,adc_hi ; send high byte
SBI PORTB,WR ; set WR bit
CBI PORTB,WR ; clear WR bit
NOP
NOP
LDI tmp,0x00 ; PORTD as input
OUT DDRD,tmp
OUT PORTD,tmp
RET
RESET:
LDI tmp,0x80 ; init 32 byte stack
OUT SPL,tmp
; PD0..7 as Data I/O
LDI tmp,0x00 ; PORTD as input
OUT DDRD,tmp
OUT PORTD,tmp ; Pull-ups off
; PB0..3 as Control
LDI tmp,0xFC ; PB2,PB3 as Output
OUT DDRB,tmp
LDI tmp,0x08 ; WR,RD# inactiv
OUT PORTB,tmp
LDI tmp,0x80 ; GIE
OUT SREG,tmp
MAIN:
IN tmp,PINB ; read Control bits
SBRC tmp,RXF ; Skip if Bit in Register is Clear = Data available
RJMP NoData
CBI PORTB,RD ; clear READ# bit
NOP
NOP
IN data,PIND ; read Data
SBI PORTB,RD ; set RD# bit
CPI data,0x01 ; send data?
BRNE NotDataCommand
RCALL SendData
NotDataCommand:
NoData:
RJMP MAIN
Wenn ich die Datenblätter richtig verstanden habe, sollte das Programm beim empfangen von "1" zwei Bytes senden. Gesendet wird aber folgendes:
Wenn ich ein Poti am ADC0 gegen Masse gedreht habe erhalte ich folgendes:
0, 1, 0 - 2. und 3. Byte sind richtig (= ADC_lo/hi)
Wenn ich es gegen +5V gedreht habe erhalte ich die Bytes:
0, 127, 3, 3 - 2. und 3. sind richtig (= ADC_lo/hi)
Ich habs auch mal ausprobiert nur den PORTD von Input auf Output umschalten selbst dann wird ein Byte gesendet.
Vermuten tue ich das es beim Umschalten des PORTD irgendwie zu störungen kommen muss die ein Schreiben des Bytes auslösen, was wohl an meinem Steckbrett aufbau liegen könnte.
Hat jemand sonst eine Idee?
Ich möchte Daten vom AD-Wandler über den USB-Bus übertragen. Leider gibt es ein Problem und zwar werden mehr Bytes übertragen als ich senden will. Das Programm sieht folgendermaßen aus:
;
; uC: Atmel, AT90s2333
;
;
; Used PINs:
;
; +5V, GND - power supply
; ADC0...ADC5 - ADC
;
; PD0..7 - Data I/O
;
; PB0 - RXF# (IN)
; PB1 - TXF# (IN)
; PB2 - WR (OUT)
; PB3 - RD# (OUT)
;
; Further connection for XTAL and ADC see manual.
; (8 MHz)
.include "2333def.inc"
;***** Register definitions *****
.equ tmp, 16
.equ data, 17
.equ adc_lo, 18
.equ adc_hi, 19
.equ bool, 20
;***** Bit definitions **********
.equ RXF, 0 ; bit number
.equ TXF, 1 ; bit number
.equ WR, 2 ; bit value
.equ RD, 3 ; bit value
;***** Interrupt Vectors ********
RJMP RESET ; Reset - Hardware Pin, Power-on Reset, Watchdog Reset
reti ; INT0 - external interrupt request 0
reti ; INT1 - external interrupt request 1
reti ; Timer1 capt1 - timer/counter1 capture event
reti ; Timer1 comp1 - timer/counter1 compare mach
reti ; Timer1 ovf1 - timer/counter1 overflow
reti ; Timer0 ovf0 - timer/counter0 overflow
reti ; SPI - SPI interrupt
reti ; Uart, Rx - UART, RX complete
reti ; Uart, UDRE - Uart Data Register Empty
reti ; Uart, Tx - Uart, TX complete
RJMP ADC_Interrupt ; ADC - ADC interupt
reti ; EEPROM - EEPROM Interrupt
reti ; Ana_comp - Analog Comparator
ADC_Interrupt:
IN r0,SREG
IN adc_lo,ADCL
IN adc_hi,ADCH
LDI bool,1
OUT SREG,r0
reti
SendData:
LDI tmp,0xFF ; PORTD as ouput
OUT DDRD,tmp
LDI adc_lo,65
LDI adc_hi,65
LDI tmp,0x00 ; select channel 0
OUT ADMUX,tmp
LDI tmp,0xCF ; start AD conversion
OUT ADCSR,tmp
LDI bool,0
WAIT:
CPI bool,1
BRNE WAIT
LDI tmp,0
OUT PORTD,adc_lo ; send low byte
SBI PORTB,WR ; set WR bit
CBI PORTB,WR ; clear WR bit
LDI tmp,0
OUT PORTD,adc_hi ; send high byte
SBI PORTB,WR ; set WR bit
CBI PORTB,WR ; clear WR bit
NOP
NOP
LDI tmp,0x00 ; PORTD as input
OUT DDRD,tmp
OUT PORTD,tmp
RET
RESET:
LDI tmp,0x80 ; init 32 byte stack
OUT SPL,tmp
; PD0..7 as Data I/O
LDI tmp,0x00 ; PORTD as input
OUT DDRD,tmp
OUT PORTD,tmp ; Pull-ups off
; PB0..3 as Control
LDI tmp,0xFC ; PB2,PB3 as Output
OUT DDRB,tmp
LDI tmp,0x08 ; WR,RD# inactiv
OUT PORTB,tmp
LDI tmp,0x80 ; GIE
OUT SREG,tmp
MAIN:
IN tmp,PINB ; read Control bits
SBRC tmp,RXF ; Skip if Bit in Register is Clear = Data available
RJMP NoData
CBI PORTB,RD ; clear READ# bit
NOP
NOP
IN data,PIND ; read Data
SBI PORTB,RD ; set RD# bit
CPI data,0x01 ; send data?
BRNE NotDataCommand
RCALL SendData
NotDataCommand:
NoData:
RJMP MAIN
Wenn ich die Datenblätter richtig verstanden habe, sollte das Programm beim empfangen von "1" zwei Bytes senden. Gesendet wird aber folgendes:
Wenn ich ein Poti am ADC0 gegen Masse gedreht habe erhalte ich folgendes:
0, 1, 0 - 2. und 3. Byte sind richtig (= ADC_lo/hi)
Wenn ich es gegen +5V gedreht habe erhalte ich die Bytes:
0, 127, 3, 3 - 2. und 3. sind richtig (= ADC_lo/hi)
Ich habs auch mal ausprobiert nur den PORTD von Input auf Output umschalten selbst dann wird ein Byte gesendet.
Vermuten tue ich das es beim Umschalten des PORTD irgendwie zu störungen kommen muss die ein Schreiben des Bytes auslösen, was wohl an meinem Steckbrett aufbau liegen könnte.
Hat jemand sonst eine Idee?