Nahmd Gemeinde, in nutze die USART-Schnittstelle des ATmega48 als SPI, weil die eigendliche SPI schon besetzt ist. Ich möchte einen MCP3208 damit ansteuern. Im Datenblatt des MCP3208 ist zwar diese Sende/Befehlssequenz beschrieben, aber er reagiert nicht darauf. Ich wähle den MCP3208 per /CS an und sende meine 3Byte und sehe auf dem Oszi keine Antwort. Die Taktfrequenz des XCK ist 500kHz. USART ist im SPI-Mastermode (Mode 0). Rx und Tx sind aktiv, DDRD = 0b11111110 und PORTD=0b11101110, Flaggen und Interrupts auch alle aktiv. Senden klapt ja, aber ich erhalte keine Antwort. Irgend 'was mache ich falsch, sonst würde es ja funzen. Wenn jemand eine Idee hat, was ich machen kann, wüerde mich das sehr freuen. MfG Hagen
Hier ist der Quell-Code für meine Schwierigkeit ; ************************************************************************ * ; Timer 1 Test ; Datum: 30.09.2008 ; Letzte Änderung: 21.10.2008 ; Hagen Großmann ; ************************************************************************ * /*********************************************************************** *** Einstellung für AVRstudio Main: ATmega48 ISP mode Program: Fuses: BODLEVEL brown-out detection disable SUT_CKSEL Ext. Full-swing Crystal; Start-up time PWRDWN/RESET: 16K CK/14 CK + 4.1 ms LockBits:no memory lock feattures enable (lockbit 0xff) Mod1 ************************************************************************ ***/ ;*********************************************************************** *** ; Anschlußbelegung für ATmega48 ; ; ;oder weil USART nicht 8 bit synchron ohne Start und Stopbit übertragen kann: ;Port B: ; 0 -> DE Daten ; 1 -> /RE Daten/Takt ; 2 -> DE Takt und /SS ; 3 -> MOSI ; 4 -> MISO ; 5 -> CLK ; 6 -> XTAL ; 7 -> XTAL ; Port C: ; 0 -> frei ; 1 -> frei ; 2 -> frei ; 3 -> frei ; 4 -> frei ; 5 -> frei ; 6 -> Reset ; ; ; Port D: ; 0 -> RxD -> Dout ; 1 -> TxD -> Din ; 2 -> /CS -> ext.ADC0 Spannungseingänge 0-7 ; 3 -> /CS -> ext.ADC1 Stromeingänge 0-7 ; 4 -> CLK ; 5 -> LED onBoard+ext. ; 6 -> frei ; 7 -> frei ;*********************************************************************** ********* ; ; Konfigurations- und Sicherheitsbits ; an in Ponyprog(programmiert, bei Atmel -> 0) WDTON,SUT0,CKSEL2,CKSEL1,CKSEL0 .include "m48def.inc" .def Empf =r9 .def Send =r10 .def ADC_high =r11 .def ADC_low =r12 .def Lese_Zeiger =r13 .def Zeitgeber1 =r14 .def Kanal_Zeiger =r15 .def Temp1 =r16 .def Temp2 =r17 .def Temp3 =r18 .def Temp4 =r19 .def ZP_b =r20 ;byte-Zähler für RS485-Schnittstelle .def ZP_p =r21 ;Paketzähler für RS485-Schnittstelle .def status =r22 .def PIND_filter =r23 .def Z_l =r24 .def Z_h =r25 ;********************************************************************** ;Aufteilung vom RAM .equ lesen=SRAM_START ; Rechner liest vom Modul .equ schreiben=lesen+32 ; Rechner schreib auf Modul .equ sendesequenz=schreiben+32 ; 3Byte für Befehlsfolge an ADCs .equ pininterupt=sendesequenz+3 ; .equ schleifendurchlauf1=pininterupt+1 ; ;********************************************************************** ;*************** Macro Definition ************************************* .MACRO LED_ON sbi PORTD, 5 .ENDMACRO .MACRO LED_OFF cbi PORTD, 5 .ENDMACRO .MACRO LED_toggle in Temp1, PORTD ldi Temp2, 0x20 eor Temp1, Temp2 out PORTD,Temp1 .ENDMACRO ;************** Macro Definition Ende ********************************* .cseg ;*********************************************************************** **** ;Interuptverteiler ab Adresse 0 .org $0000 ; AVR mega168 vectors starten bei Addresse 0 ; und haben lange absolute Sprünge rjmp reset ;reset-Sprung rjmp ext_int0 ;nicht benutzt rjmp ext_int1 ;nicht benutzt rjmp PCINT_0 ;nicht benutzt rjmp PCINT_1 ;nicht benutzt rjmp PCINT_2 ;nicht benutzt rjmp WDT ;nicht benutzt rjmp TIM2_compA ;nicht benutzt rjmp TIM2_compB ;nicht benutzt rjmp TIM2_ovf ;nicht benutzt rjmp TIM1_capt ;Zeitmessung zwischen 2 Flanken an B0 rjmp TIM1_compA ;nicht benutzt rjmp TIM1_compB ;nicht benutzt rjmp TIM1_ovf ;innere Uhr (1ms) rjmp TIM0_compA ;Kontroll-Leuchtdiode rjmp TIM0_compB rjmp TIM0_ovf ;Kontroll-Leuchtdiode rjmp SPI_int ;Übnertragung zum Hauptrechner rjmp USART_rxc ;UART Empfang fertig (Befehle) rjmp USART_dre ;nicht benutzt rjmp USART_txc ;nicht benutzt rjmp ADC_int rjmp EE_rdy ;nicht benutzt rjmp ANA_comp ;nicht benutzt rjmp TWI rjmp SPM_rdy PCINT_1: push R0 in R0,SREG push R0 push Temp2 ; ldi Temp4,0x05 ; 5-mal blinken in Temp1,PINC ; welcher Pin ist low ldi Temp2,0xFF ; Schiebemaske mit Carry ldi Temp4,0x00 ; SchleifenZähler für Anzahl Blinken ori Temp1,0xC0 ; Bit 7 & 6 setzen, weil Port C nut 7 Bit breit und Bit 6 als Ausgang ; out PORTD,Temp1 ; Kontrollausgabe clc rcall welcher_pin rcall s4 pop Temp2 pop R0 out SREG,R0 pop R0 reti ; ****************************************************************** ;Timer1 compare TIM1_compA: ldi YH,high(sendesequenz+3) ldi YL,low(sendesequenz+3) ldi Temp2, 0x03 mov Lese_Zeiger,Temp2 rcall sendeByte pop Temp1 pop R0 out SREG,R0 pop R0 reti USART_rxc: push R0 in R0,SREG push R0 pop R0 out SREG,R0 pop R0 reti USART_dre: push R0 in R0,SREG push R0 pop R0 out SREG,R0 pop R0 reti ;USART Sende-Interrupt USART_txc: push R0 in R0,SREG push R0 pop R0 out SREG,R0 pop R0 reti ;----------------------------------------------------------------------- ------------------ ;*** Ende Interruptprogramme *** ;*********************************************************************** **************** /*********************************************************************** ** initialisieren ************************************************************************ **/ RESET: ldi Temp1,high(RAMEND) ;Stabel auf Ende (stapelt abwärts) out SPH,Temp1 ldi Temp1,low(RAMEND) out SPL,Temp1 rcall PORTB_konfigurieren rcall PORTC_konfigurieren rcall PORTD_konfigurieren ; rcall SPI_konfigurieren rcall USART_als_SPI_konfigurieren rcall Sendesequenz_Werte ; rcall USART_konfigurieren ; rcall Timer0_konfigurieren rcall Timer1_konfigurieren ldi Temp4,3 ; erstmal 3-mal blinken ; ldi Temp4,1 ; erstmal 1-mal blinken rcall s4 sbi PIND,PIND2 ; Testzwecke ADC0 aktiv sei ; ************************************************************************ * ; Hauptprogramm ; ************************************************************************ * Rhein_Schleife: nop rjmp Rhein_Schleife ; ***** ENDE Hauptprogramm ************************************************* /*********************************************************************** **** Controller konfigurieren ************************************************************************ ***/ PORTB_konfigurieren: ldi Temp1,0b00010010 ;B0 ist DE Daten, kommt bei Kommunikation auf 1 ;B1 ist /RE Daten/Takt, kommt normalerweise immer auf 0 ;B2 ist DE Takt und /SS, ;kommt normalerweise immer auf 0, wenn Modul Slave ist ;B4 ist MISO (Datenausgang Kommunikation); out DDRB,Temp1 ;Datenrichtungsregister ldi Temp1,0b00000000 ; out PORTB,Temp1 ret PORTC_konfigurieren: ldi Temp1, 0x40 ldi Temp2, 0x3F out DDRC,Temp1 ; Input out PINC, Temp2 ; ldi Temp1,0x02 ; PinInterupt Port C eingeschaltet ldi Temp2,0x3F ; PinInteruptMaske Port C eingeschaltet sts PCICR,Temp1 sts PCMSK1,Temp2 ret PORTD_konfigurieren: ldi Temp1,0b11111110 ; ldi Temp1,0x00 out DDRD,Temp1 ldi Temp1,0b11101100 out PORTD,Temp1 ret SPI_konfigurieren: ret USART_als_SPI_konfigurieren: clr Temp1 sts UBRR0H,Temp1 sts UBRR0L,Temp1 sbi PIND, XCK ; Setting the XCKn port pin as output, enables master mode. clr Temp1 ldi Temp1,(1<<UMSEL1 | 1<<UMSEL0 | 0<<UCPHA0 | 0<<UCPOL0) sts UCSR0C,Temp1 ; MSPIM MasterMode, MSP first out, SPI-Mode 0 clr Temp1 ldi Temp1,(1<<RXCIE0 | 1<<TXCIE0 | 0<<UDRIE0 | 1<<RXEN0 | 1<<TXEN0) ; sts UCSR0B,Temp1 ; RX Interrupt Enable, USART Data Register Empty Interrupt Enable, Receiver Enable, Transmitter Enable clr Temp1 ldi Temp2, 0x13 ; Taktteiler für XCK = 20MHz/40 sts UBRR0H,Temp1 sts UBRR0L,Temp2 ret Sendesequenz_Werte: ldi Temp4, 0x07 ; Sequenz für ADC ldi Temp3, 0xC0 ; Platzhalter für XCK ldi Temp2, 0x00 ; Platzhalter für XCK sts sendesequenz+2,Temp4 sts sendesequenz+1,Temp3 sts sendesequenz,Temp2 ret USART_konfigurieren: clr Temp1 sts UBRR0H,Temp1 sts UBRR0L,Temp1 ldi Temp1,(1<<RXCIE0 | 1<<TXCIE0| 1<<UDRIE0 | 1<<RXEN0 | 1<<TXEN0) ; sts UCSR0B,Temp1 ; RX Interrupt Enable, USART Data Register Empty Interrupt Enable, Receiver Enable, Transmitter Enable clr Temp1 ldi Temp1,(1<<USBS0 | 1<<UCSZ01 | 1<<UCSZ00) sts UCSR0C,Temp1 ; MSPIM MasterMode, MSP first out, ldi Temp1,0x02 ldi Temp2, 0x08 ; Taktteiler für BAUD=2400 bei 20 MHz ; clr Temp1 ; ldi Temp2, 0xcf ; Taktteiler für BAUD=2400 bei 8 MHz sts UBRR0H,Temp1 sts UBRR0L,Temp2 ret Timer0_konfigurieren: ret Timer1_konfigurieren: ldi Temp1, 0x00 ; normale Port-Operation, Kein Ausgang auf OC1A/OC1B sts TCCR1A, Temp1 ; Timer/Counter1 Control Register A ldi Temp1, 0x09 ; Übereinstimmung mit VergleichsregisterA,Rücksetzen bei Gleichheit,Taktteiler 1 ; ldi Temp1, 0x0D ; Übereinstimmung mit VergleichsregisterA,Rücksetzen bei Gleichheit,Taktteiler 1024 sts TCCR1B, Temp1 ; Timer/Counter1 Control Register B ldi Temp1, 0x80 ; Match für Channel A & B sts TCCR1C, Temp1 ; Timer/Counter1 Control Register C clr Temp1 sts TCNT1H,Temp1 ; Zählregister löschen sts TCNT1L,Temp1 ; Zählregister löschen ; ldi Temp1, 0x4E ; Vergleichsregister wird mit Vergelichswert ; ldi Temp2, 0x1F ; 0x4E20 gefüllt entspricht 20k Takte = 0.001sec ldi Temp1, 0x4C ; Testweise 1024*19531=19999744 Takte ldi Temp2, 0x4B ; Testweise sts OCR1AH, Temp1 sts OCR1AL, Temp2 clr Temp1 sts ICR1H,Temp1 sts ICR1L,Temp1 ldi Temp1, 0x27 ; Capture Interrupt ist an,Compare B Match Interrupt an, Compare A Match Interrupt an, Overflow Interrupt an sts TIMSK1, Temp1 ret /*********************************************************************** ** Ende Controller konfigurieren ************************************************************************ **/ /*********************************************************************** ** Unterprogramme ************************************************************************ **/ LED_toggle_Schleife: LED_toggle clr Zeitgeber1 clr Temp3 ldi Temp3,(1 << OCF1B | 1 << OCF1A) out TIFR1, Temp3 ret Werte_holen: ret Kanal_abfragen: ret sendeByte: lds Temp1,UCSR0A sbis 0x10,UDRE0 ; wenn SendeRegister leer, dann kein Rücksprung ; sbis nimmt keinen "Temp1"-Bezeichner an, nur die reale Adresse von Temp1 -> Bug rjmp sendeByte ; Rücksprung, wenn SendeRegister voll ld Temp1, -Y ; Testzwecke sts UDR0, Temp1 ; Testzwecke dec Lese_Zeiger brne sendeByte LED_toggle ret S4: LED_ON rcall pause LED_OFF rcall pause dec Temp4 brne S4 ret pause: ldi Temp3,30 ; ldi Temp3,1 S3: ldi Temp2,255 ; ldi Temp2,1 S2: ldi Temp1,255 ; ldi Temp1,1 S1: dec Temp1 brne S1 dec Temp2 brne S2 dec Temp3 brne S3 ret welcher_pin: rol Temp2 ; Rollen links mit Carry -> PinMaske bewegen inc Temp4 ; Schleifendurchlauf = entsprechender Pin cpse Temp1,Temp2 ; Pins mit Maske vergleichen und bei Gleichheit Schleife abbrechen brne welcher_pin ; bei Ungleichheit neuer Schleifendurchlauf ret
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.