Hey Leute! Folgendes: Ich bräuchte für meinen Mega8 eine 2. Serielle Schnittstelle, bzw. Lösungsideen. Ich will Daten von einem Gerät auslesen (Gerät sendet diese Daten im Sekunden Takt) diese seriellen Daten umwandeln und dann an ein anderes Gerät (Notebook) senden. Ist es möglich, nur den Rx-Pin an die eine und nur den Tx-Pin an die andere Schnittstelle zu geben? Das "Sende-Gerät" benötigt keine Rückmeldung (soweit ich bis jetzt herausfinden konnte). lg Fox
Sender und Empfänger sind beim USART weitgehend voneinander unabhängig (abgesehen von einigen Einstellungen die für beide Teile gleichzeitig gelten, also Baudrate und Frame-Format). Du kannst sie aber auch getrennt einsetzen.
Johannes M. wrote: > Sender und Empfänger sind beim USART voneinander unabhängig. Du kannst > die auch getrennt einsetzen. ... solange die Baudrate gleich ist. Peter
klar kannst Du RX und TX auf verschiedene Geräte verteilen. Dann gibts noch die Möglichkeit die RX und TX beispielsweise per Transistor hin und her zu schalten oder wenns nicht viele Bauteile sein sollen kannste auch ne zweite UART als Software-UART einprogrammieren. Viele Wege führen ans Ziel.
>... solange die Baudrate gleich ist.
sie kann natürlich auch verschieden sein, vorausgesetzt du willst nicht
gleichzeitig senden un empfangen
Die grosse Nährende Mutter Atmel hat auch daran gedacht. http://www.atmel.com/dyn/general/advanced_search_results.asp?appNotes=1&target=software%20UART AVR274: Single-wire Software UART AVR304: Half Duplex Interrupt Driven Software UART AVR305: Half Duplex Compact Software UART Ansonsten Google "AVR software UART"
Hey! Sorry, aber ich steh grad voll auf der Seife... Wie kann ich am besten eine Wechselschaltung realisieren, bei der die TX-Leitung zwischen den Anschlüssen T1IN und T2IN des MAX232 geschaltet wird... lg Fox
Damit ich mit einer UART Schnittstelle zwei RS232 Schnittstellen realisieren kann... lg
>Wie kann ich am besten eine Wechselschaltung realisieren, bei der die >TX-Leitung zwischen den Anschlüssen T1IN und T2IN des MAX232 geschaltet >wird... Wenn das die Sende-TTL-Seite des MAX ist, dann kann man da ein paar Gatter davor hängen. Dazu muß man sich nur im Klaren darüber sein, wann welches Bit wohin soll.
Ist doch scheiße. Such dir aus http://www.atmel.com/dyn/products/param_table.asp?family_id=607 statt des Mega8 einen AVR mit zwei UARTs raus, oder nimm einen Software UART.
Problem ist, dass ich die Schaltung so schnell wie möglich brauche und noch einen Haufen ATmega8 herumliegen habe... Daher muss ich hier eine Lösung finden, um es mit dem mega8 hinzubekommen... lg
Danke Peter, Hab ich mir schon angesehen... Ich muss das ganze jetzt noch auf meinen Compiler "umwälzen" (CVAVR). lg
Hallo! Leider muss ich zugeben, dass ich's nicht pack.
1 | /************************************************************************/ |
2 | /* */ |
3 | /* Software UART using T1 */ |
4 | /* */ |
5 | /* Author: P. Dannegger */ |
6 | /* danni@specs.de */ |
7 | /* */ |
8 | /************************************************************************/ |
9 | #include <main.h> |
10 | #include <suart.h> |
11 | |
12 | |
13 | #define BIT_TIME (u16)((XTAL + BAUD/2) / BAUD) |
14 | |
15 | |
16 | volatile u8 stx_count; |
17 | u8 stx_data; |
18 | |
19 | volatile u8 srx_done; |
20 | u8 srx_data; |
21 | u8 srx_mask; |
22 | u8 srx_tmp; |
23 | |
24 | |
25 | void suart_init( void ) |
26 | { |
27 | OCR1A = TCNT1 + 1; // force first compare |
28 | TCCR1A = 1<<COM1A1^1<<COM1A0; // set OC1A high, T1 mode 0 |
29 | TCCR1B = 1<<ICNC1^1<<CS10; // noise canceler, 1>0 transition, |
30 | // CLK/1, T1 mode 0 |
31 | TIFR = 1<<ICF1; // clear pending interrupt |
32 | TIMSK = 1<<TICIE1^1<<OCIE1A; // enable tx and wait for start |
33 | |
34 | stx_count = 0; // nothing to sent |
35 | srx_done = 0; // nothing received |
36 | STXDDR |= 1<<STX; // TX output |
37 | } |
38 | |
39 | |
40 | u8 sgetchar( void ) // get byte |
41 | { |
42 | while( !srx_done ); // wait until byte received |
43 | srx_done = 0; |
44 | return srx_data; |
45 | } |
46 | |
47 | |
48 | SIGNAL( SIG_INPUT_CAPTURE1 ) // rx start |
49 | { |
50 | OCR1B = ICR1 + (u16)(BIT_TIME * 1.5); // scan 1.5 bits after start |
51 | srx_tmp = 0; // clear bit storage |
52 | srx_mask = 1; // bit mask |
53 | TIFR = 1<<OCF1B; // clear pending interrupt |
54 | if( !(SRXPIN & 1<<SRX)) // still low |
55 | TIMSK = 1<<OCIE1A^1<<OCIE1B; // wait for first bit |
56 | } |
57 | |
58 | |
59 | SIGNAL( SIG_OUTPUT_COMPARE1B ) |
60 | { |
61 | u8 in = SRXPIN; // scan rx line |
62 | |
63 | if( srx_mask ){ |
64 | if( in & 1<<SRX ) |
65 | srx_tmp |= srx_mask; |
66 | srx_mask <<= 1; |
67 | OCR1B += BIT_TIME; // next bit slice |
68 | }else{ |
69 | srx_done = 1; // mark rx data valid |
70 | srx_data = srx_tmp; // store rx data |
71 | TIFR = 1<<ICF1; // clear pending interrupt |
72 | TIMSK = 1<<TICIE1^1<<OCIE1A; // enable tx and wait for start |
73 | } |
74 | } |
75 | |
76 | |
77 | void sputchar( u8 val ) // send byte |
78 | { |
79 | while( stx_count ); // until last byte finished |
80 | stx_data = ~val; // invert data for Stop bit generation |
81 | stx_count = 10; // 10 bits: Start + data + Stop |
82 | } |
83 | |
84 | |
85 | void sputs( u8 *txt ) // send string |
86 | { |
87 | while( *txt ) |
88 | sputchar( *txt++ ); |
89 | } |
90 | |
91 | |
92 | SIGNAL( SIG_OUTPUT_COMPARE1A ) // tx bit |
93 | { |
94 | u8 dout; |
95 | u8 count; |
96 | |
97 | OCR1A += BIT_TIME; // next bit slice |
98 | count = stx_count; |
99 | |
100 | if( count ){ |
101 | stx_count = --count; // count down |
102 | dout = 1<<COM1A1; // set low on next compare |
103 | if( count != 9 ){ // no start bit |
104 | if( !(stx_data & 1) ) // test inverted data |
105 | dout = 1<<COM1A1^1<<COM1A0; // set high on next compare |
106 | stx_data >>= 1; // shift zero in from left |
107 | } |
108 | TCCR1A = dout; |
109 | } |
110 | } |
Im Anhang findet ihr die Fehlerliste... Ich weiß leider nicht, wie ich die Fehler ausbessern soll. Mein Compiler ist der Codevision AVR. lg
Du mußt die Symboldatei einbinden, wo die ganzen Register und Ports definiert sind. Unter AVR-GCC ist das die io.h, Du müßtest daher ne Fehlermeldung erhalten haben, daß die io.h nicht gefunden wird. Peter
Ich habe die mega8.h und auch die io.h eingebunden und es klappt trotzdem nicht... in der mega8.h steht u.a. das hier:
1 | sfrb TWBR=0; |
2 | sfrb TWSR=1; |
3 | sfrb TWAR=2; |
4 | sfrb TWDR=3; |
5 | sfrb ADCL=4; |
6 | sfrb ADCH=5; |
7 | sfrw ADCW=4; // 16 bit access |
8 | sfrb ADCSRA=6; |
9 | sfrb ADMUX=7; |
10 | sfrb ACSR=8; |
11 | sfrb UBRRL=9; |
12 | sfrb UCSRB=0xa; |
13 | sfrb UCSRA=0xb; |
14 | sfrb UDR=0xc; |
15 | sfrb SPCR=0xd; |
16 | sfrb SPSR=0xe; |
17 | sfrb SPDR=0xf; |
18 | sfrb PIND=0x10; |
19 | sfrb DDRD=0x11; |
20 | sfrb PORTD=0x12; |
21 | sfrb PINC=0x13; |
22 | sfrb DDRC=0x14; |
23 | sfrb PORTC=0x15; |
24 | sfrb PINB=0x16; |
25 | sfrb DDRB=0x17; |
26 | sfrb PORTB=0x18; |
27 | sfrb EECR=0x1c; |
28 | sfrb EEDR=0x1d; |
29 | sfrb EEARL=0x1e; |
30 | sfrb EEARH=0x1f; |
31 | sfrw EEAR=0x1e; // 16 bit access |
32 | sfrb UBRRH=0x20; |
33 | sfrb UCSRC=0X20; |
34 | sfrb WDTCR=0x21; |
35 | sfrb ASSR=0x22; |
36 | sfrb OCR2=0x23; |
37 | sfrb TCNT2=0x24; |
38 | sfrb TCCR2=0x25; |
39 | sfrb ICR1L=0x26; |
40 | sfrb ICR1H=0x27; |
41 | sfrw ICR1=0x26; // 16 bit access |
42 | sfrb OCR1BL=0x28; |
43 | sfrb OCR1BH=0x29; |
44 | sfrw OCR1B=0x28; // 16 bit access |
45 | sfrb OCR1AL=0x2a; |
46 | sfrb OCR1AH=0x2b; |
47 | sfrw OCR1A=0x2a; // 16 bit access |
48 | sfrb TCNT1L=0x2c; |
49 | sfrb TCNT1H=0x2d; |
50 | sfrw TCNT1=0x2c; // 16 bit access |
51 | sfrb TCCR1B=0x2e; |
52 | sfrb TCCR1A=0x2f; |
53 | sfrb SFIOR=0x30; |
54 | sfrb OSCCAL=0x31; |
55 | sfrb TCNT0=0x32; |
56 | sfrb TCCR0=0x33; |
57 | sfrb MCUCSR=0x34; |
58 | sfrb MCUCR=0x35; |
59 | sfrb TWCR=0x36; |
60 | sfrb SPMCR=0x37; |
61 | sfrb TIFR=0x38; |
62 | sfrb TIMSK=0x39; |
63 | sfrb GIFR=0x3a; |
64 | sfrb GICR=0x3b; |
65 | sfrb SPL=0x3d; |
66 | sfrb SPH=0x3e; |
67 | sfrb SREG=0x3f; |
lg
Wirf unbedingt einen Blick in die Doku zur Lib-c. Da steht AFAIR drin, dass man nur die io.h einfügen soll. Das Makefile sogrt dann dafür, sass die m8.h eingefügt wird.
Fox wrote: > Ich habe die mega8.h und auch die io.h eingebunden und es klappt > trotzdem nicht... Hast Du denn schon irgendwas mit dem Codevision zum Laufen gebracht? Da muß doch auch ein Exampleverzeichnis mit Timerinterrupt sein. Bring das mal zum Laufen. Und dann schau Dir an, wie dort IO-Register und Interrupts definiert werden. Deine mega8.h enthält ja keine Bitnamen. Peter P.S.: Benutze den Dateianhang!
Sorry für die Frage, aber wozu brauch ich Bit Namen? Ich habe mit CodeVision AVR bereits einige "Projekte" hinter mir und habe noch nie Bit Namen gebraucht... lg
Fox wrote:
> Sorry für die Frage, aber wozu brauch ich Bit Namen?
Wenn Du Dir mal ein Datenblatt anguckst, dann wimmelt es nur so vor
Bitnamen.
Man kann natürlich statt der Bitnamen auch kryptische Hexwerte
hinschreiben. Bloß sieht dann kein Schwein mehr durch, was der Code
macht.
Daher bevorzugen erfahrene Programmierer die Namen aus dem Datenblatt,
auch wenns mehr Schreibarbeit ist.
Z.B. bei:
1 | TIMSK = 1<<TICIE1^1<<OCIE1A; |
weiß jeder gleich: aha, der Inputcapture und Outputcompare A Interrupt von T1 werden enabled. Es steht Dir frei, das nicht zu tun. Dann schau ins Datenblatt, was die Bits bedeuten, rechne den entsprechenden Hexwert aus und schreib ihn hin. Peter
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.