Hi,
ich brauche Hilfe bei meinem AVR-C Code fuer einen ATmega8. Um Kontext
zu schaffen: Dieser Code soll mithilfe des ADCs die Spannung eines
Spannungsteilers einlesen. Diese value wird an die Funktion
'Update_CtrlCntr1' uebergen, welche sie so umrechnet, dass ich fuer den
Counter 1 eine Compare-value bekomme, die die ON-Time eines von diesem
Counter generiertem 50-Hz Signal bestimmt.
Wie man im Code unten sieht, wird der character cmd als 'f' gesetzt. In
diesem Mode liest der ADC bei jedem Durchlauf der while Schleife eine
neue value von dem Spannungsteiler ein und updated so die ON-Time des
PWM-Signals.
Nun, ich moechte diesen ATmega mithilfe eines Arduinos steuern, heisst,
ich sende ueber Serial die characters 'A', 'B', 'C', ... und moechte,
dass die in der Switch Case Anweisung spezifizierte mot_control value
benutzt wird und solange cmd nicht 'f' ist, der ADC nicht aktiv ist (Die
mot_control value also fest ist). Mithilfe der 'Serial_avail()'
Funktion wird, wie es der Name verratet, gecheckt, ob das 'RXC' (Receive
Complete) Bit gesetzt ist, bzw. etwas empfangen wurde, also etwas im
'UDR' Register ist. Nur falls diese Funktion eine '1' zurueckgibt, soll
der command eingelesen und verarbeitet werden.
Mein Problem ist, dass der ATmega zwar das PWM-Signal richtig generiert
und den ADC richtig einliest, aber nicht auf die vom Arduino gesendeten
Bytes reagiert. Generell, wenn ich in der 'default' Sektion der Switch
Case Anweisung NICHT den cmd direkt wieder auf 'f' setze, die anfangs
anliegende Spannung eingelesen wird und gesetzt BLEIBT, egal ob ich die
Spannung veraendere. Also wird sofort in die Switch Case Anweisung
geleitet und die Variable cmd geaendert. Ein Senden von commands bringt
nichts. Ich hab mir das jetzt schon ziemlich oft durchgeschaut, etwas
veraendert, komm jedoch nicht auf den Fehler. Kann sein, dass es etwas
offensichtliches ist, wer weiss.
Unten hier liegen die Codes fuer die Main-Funktion, Serial_init
Funktion, Serial_avail Funktion und Serial_read Funktion.
Vielen Dank im Voraus!
1 | int main(void)
|
2 | {
|
3 | Serial_init( MYUBRR );
|
4 | Init_CtrlCntr1(); // Control Counter 1
|
5 | Init_ADC();
|
6 |
|
7 | int mot_ctrl; // motor control value (10-bit because ADC)
|
8 | char cmd = 'f'; //cmd = 'command' received by Arduino
|
9 |
|
10 | while(1)
|
11 | {
|
12 | if (cmd == 'f') mot_ctrl = ADC_read ( ADC_INPUT );
|
13 | Update_CtrlCntr1 ( mot_ctrl );
|
14 |
|
15 | if(Serial_avail() == 1){
|
16 | cmd = Serial_readChr();
|
17 | switch(cmd){
|
18 | case 'A': mot_ctrl = 0; break;
|
19 | case 'B': mot_ctrl = 114; break;
|
20 | case 'C': mot_ctrl = 228; break;
|
21 | case 'D': mot_ctrl = 341; break;
|
22 | case 'E': mot_ctrl = 455; break;
|
23 | case 'F': mot_ctrl = 569; break;
|
24 | case 'G': mot_ctrl = 683; break;
|
25 | case 'H': mot_ctrl = 796; break;
|
26 | case 'I': mot_ctrl = 910; break;
|
27 | case 'J': mot_ctrl = 1024; break;
|
28 | default: cmd = 'f'; break;
|
29 | }
|
30 | }
|
31 | }
|
32 | }
|
1 | void Serial_init(int ubrr){
|
2 | UBRRH = 0;
|
3 | UBRRL = 0;
|
4 | UCSRA = 0;
|
5 | UCSRB = 0;
|
6 | UCSRC = 0;
|
7 |
|
8 | // Set UBRR for BAUD
|
9 | UBRRH = ubrr >> 8;
|
10 | UBRRL = ubrr & 0xFF;
|
11 | // Enable Receiver and/or Transmitter (Here only RX)
|
12 | UCSRB |= (1 << RXEN);
|
13 | // Set Modes (Here Asynchronous modes, no parity, 8 data bits, 1 stop bit)
|
14 | UCSRC |= (1 << UCSZ1) | (1 << UCSZ0);
|
15 | }
|
1 | int Serial_avail(){
|
2 | if ( UCSRA & (1<<RXC) ) return 1;
|
3 | else return 0;
|
4 | }
|
1 | char Serial_readChr(){
|
2 | // Return Value currently in the Data Register
|
3 | return UDR;
|
4 | }
|
Hier auch noch die Berechnung der UBRR-value mit der Baudrate und dem
Clock-Speed.
1 | #define F_CPU 1000000L
|
2 | #define BAUD 4800L
|
3 |
|
4 | #define MYUBRR (F_CPU/(16*BAUD)-1)
|