Hi und zwar habe ich grad ein Problem: Schaltung besteht aus einem Attiny4313 und einem Max485. dieser soll daten an den pc senden. Das ganze soll später mit einem Protokoll implementiert werden das grob auch schon steht. Folgende Fehler finde ich: 1. TX_EN, der die umschaltung am Max485 tun soll, verursacht probleme. dieser sendet z.B. nicht alle zeichen von "initial" oder auch nur 'l' 2. in der funktion rx_block() geht er nicht über die zeile while (! (UCSRA & (1<<RXC))); // warten bis zeichen da nun wollte ich mit 2 grundfunktionen beide wege Rx und Tx testen. als anhang habe ich nochmal die dateien kann mir jemand helfen ? hier mein code: main: #include <avr/io.h> #include <util/delay.h> #include <ctype.h> #include <stdio.h> #include "define.h" #include "rs485.h" // -------------------- Main --------------------- int main (void) { DDRD |= TX | TX_EN | LED_GR | LED_RT; // Ausgänge configurieren PORTD |= RX | Adr_Pin; // interne Pull-ups für Eingänge //aktivieren uint8_t Data_Array[10] = {0,0,0,0,0,0,0,0,0,0}; // Daten-Array UART_init(); _delay_ms(10); tx_block('i'); tx_block('n'); tx_block('i'); tx_block('t'); tx_block('i'); tx_block('a'); tx_block('l'); tx_block('\r'); while(1) { tx_block(rx_block()); _delay_ms(50); } return 0; } dazu noch aus der rs485.c die beiden funktionen die benutzt werden void tx_block(uint8_t to_send) { PORTD |= TX_EN | LED_RT; // MAX485 auf Senden + LED an while ( !(UCSRA & (1<<UDRE)) ); // Wait for empty transmit buffer PORTD &= ~TX_EN & ~LED_RT; // MAX485 auf Empfang + LED aus UDR = to_send; // Start transmittion } uint8_t rx_block(void) { while (! (UCSRA & (1<<RXC))); // warten bis zeichen da tx_block('b'); if(UCSRA & (1 << UPE)) // wenn Paritäts-Error {parity_error = 1; } // Paritätsfehler vermerken } return UDR; } und hier die relevanten teile aus define.h #define RX (1<<PD0) // IN #define TX (1<<PD1) // OUT #define TX_EN (1<<PD2) // OUT wenn 1 : TX wenn 0 : RX #define LED_GR (1<<PD3) // OUT #define LED_RT (1<<PD4) // OUT #define Adr_Pin (1<<PD5) // IN #define baudrate 51 // 9600 #define FS (1<<7) // vorderstes bit (Bit 7) // im Uart-block ist Framestart //als letztes habe ich hier noch die init funktion void UART_init(void) { // Set the USART baudrate registers UBRRH = (uint8_t)baud>>8; UBRRL = (uint8_t)baud; // --- UART Sender/Empfänger Freigabe --------------------------------- UCSRB = (1<<RXEN)|(1<<TXEN); // UART Receiver, Transmitter: on // --- UART Mode Select ----------------------------------------------- // UMSEL = 0: UART Mode Select - Asynchron Mode // UPM0..1 = 10: UART Parity Mode - gerade Parity // USBS = 0: UART Stop Bit Select - 1 Stopbit // UCSZ0..1 = 11: UART Character Size - 8 Bit UCSRC=(0<<UMSEL)|(0<<UPM0)|(1<<UPM1)|(0<<USBS)|(1<<UCSZ0)|(1<<UCSZ1); }
:
Bearbeitet durch User
ok einen fehler hab ich selbst gefunden: Ich darf bei den internen Pull-Ups natürlich nicht den RX mit aktivieren Das löst aber nur das 1. problem. initial wird jetz vollständig gesendet. aber ein zeichen kommt nicht zurück wenn ich eins eingebe
:
Bearbeitet durch User
Hi >Das löst aber nur das 1. problem. initial wird jetz vollständig >gesendet. aber ein zeichen kommt nicht zurück wenn ich eins eingebe Hast du eine Schaltplan zu dem Programm? Was machen RX, TX, TX_EN. MfG Spess
ich benutze zum testen momentan noch ein pollinboard und den max auf einem breadboard.
Roland Höck schrieb: > void tx_block(uint8_t to_send) > { > PORTD |= TX_EN | LED_RT; // MAX485 auf Senden + LED an > while ( !(UCSRA & (1<<UDRE)) ); // Wait for empty transmit buffer > PORTD &= ~TX_EN & ~LED_RT; // MAX485 auf Empfang + LED aus > UDR = to_send; // Start transmittion > } Interessanter Ansatz: Driver einschalten und vor dem Absenden wieder ausschalten. Üblicherweise schaltet man ein, sendet einen kompletten Frame, wartet bis das letzte Byte raus ist (TXC oder so) und schaltet dann wieder ab.
:
Bearbeitet durch User
Hi >Interessanter Ansatz: Driver einschalten und vor dem Absenden wieder >ausschalten. Rate mal, weshalb ich gefragt habe? MfG Spess
oh du hast recht. g habs jetz unter der zeile UDR = to_send ausgeschaltet, aber funktionieren tuts immer noch nicht. das problem, war vorher schon, dass er über die zeile while(!(UCSRA & (1<<RXC))) nicht drüber hinaus
:
Bearbeitet durch User
Roland Höck schrieb: > oh du hast recht. g habs jetz unter der zeile UDR = to_send > ausgeschaltet, aber funktionieren tuts immer noch nicht. Auch dann schaltest du den Driver bereits aus, bevor das Zeichen raus ist. Das dauert ja einen Weile.
Hi
>Ich darf bei den internen Pull-Ups natürlich nicht den RX mit aktivieren
Was soll die Umschalterei zwischen RXD und Pin mit Pull-Up?
MfG Spess
also das ein und ausschalten von TX_EN wird später wieder geändert, da ja wie du schon sagst mehrere zeichen geschickt werden bevor der frame zu ende ist. die pull ups brauch ich für nen ganz normalen eingang. für z.B. Adr_Pin, der momentan noch nicht benutzt wird. RX ist da bereits wieder raus genommen, weil das ja ein UART eingang ist
spess53 schrieb: > Was soll die Umschalterei zwischen RXD und Pin mit Pull-Up? Umschalterei sehe ich keine. Aber einen RxD Pin, der sonst bei eingeschaltetem Driver floatet, weil DE=/RE. Da ergibt der Pullup durchaus Sinn.
wenn ich aber den RX eingang mit einem pull-up versehe versendet er mir nur noch "initia"
Roland Höck schrieb: > also das ein und ausschalten von TX_EN wird später wieder geändert, da > ja wie du schon sagst mehrere zeichen geschickt werden bevor der frame > zu ende ist. Schon, aber wenn du dir mal das bizarre Oszi-Diagramm von dem Kram ansehen würdest, dann wär die vmtl. klar, was da schief läuft. Dass die meisten Bytes funktionieren liegt nur daran, dass der Fehler vom nächsten Byte den Fehler im vorigen Byte deckt. Beim letzten Byte gibts aber niemanden mehr, der den Fehler in diesem Byte deckt. ;-) Also nochmal en detail: Driver einschalten. do Auf UDRE warten Byte senden until alle Bytes gesendet Auf TXC warten. Driver ausschalten.
:
Bearbeitet durch User
funktioniert leider immer noch nicht in meinem ersten test, wollte ich nur ein zeichen vom terminal schicken, das mit dann der tiny zurück schicken soll. später werden natürlich erst alle zeichen geschickt und dann TX_EN wieder auf empfang. also hab ichs ungefähr so wie du geschrieben hast pull-up für RX ein TX_EN auf senden warten auf UDRE Byte senden warten auf TXC TX_EN auf empfang aber es bleibt bei "initia" und auch kein zeichen kommt zurück ohne den pull-up für RX kommt zumindest das "initial" komplett an mehr aber auch nicht
:
Bearbeitet durch User
ahhh ich hab den fehler. habe mein schlaues buch nochmal durchwühlt und nachdem TXC gekommen ist musste ich da noch ne 1 rein schreiben, damit das wieder gelöscht wird. nun gehts. nun versteh ich auch was du damit meinst, dass das letzte byte keine nachfolger mehr hat der den fehler ausbügeln kann vielen dank
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.