PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : USB-Übertragung mit FTDI 245AM und AT90S2333



Surveyor
10.04.2007, 19: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?

Surveyor
11.04.2007, 08:58
Ich denke, ich habe das Problem gefunden. Hab folgendes in der Knowledgebase von FTDI gefunden:

----
Why do I get repeated data when I read from the FT245BM?

The WR and RD pins may be driven too hard, which can cause ringing on the lines. This can result in corrupted data because WR and RD are edge sensitive. Fitting series resistors to the WR and RD pins in the range 20-40W close to the microcontroller should remedy the problem.
----

Nachdem ich nun 24 Ohm in die WR-Leitung eingbaut habe scheint es zu funktionieren.