Led mit UART ansteuern

Gast #3877409
Lesenswert?

Hallo Leute, bin noch ein MC Greenhorn.

Ich versuche eine LED oder irgendwas durch eine über serielle 
Schnittstelle übermittelten Variable zu steuern. Wenn die Variable 1 ist 
dann soll dies gemacht werden und bei 2 jenes. Die Baudrate und alles 
ist richtig, also es ist schonmal was angekommen.
Könnt ihr mir vll helfen ?
1
#include <stdlib.h>
2
#include <avr/io.h>
3
#include <util/delay.h>
4
#include <avr/interrupt.h>
5

6
#define F_CPU 16000000UL
7

8
/* 9600 baud */
9
#define BAUD  9600 
10
#include <util/setbaud.h>
11

12
char = c;
13

14
void setutil(){
15
UBRR0H = UBRRH_VALUE;
16
UBRR0L = UBRRL_VALUE;
17
UCSR0C = (1<<UCSZ01)|(1<<UCSZ00); // Asynchron 8N1
18
UCSR0B |= (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0);     
19
}
20

21

22
ISR(USART_RXC_vect){
23
  c= UDR0;
24
}
25

26
int main(void) {
27
  setutil();
28
  DDRC |= (1<<PC5);
29
  sei();
30
  while (1) {
31
    if (c ==1)
32
    {
33
      PORTB &= (!(1<<PB1));
34
      _delay_ms(5000);
35
      PORTB |= (1<<PB1);
36
      _delay_ms(5000);
37
    
38
    } 
39
    else
40
    {
41
    }
42
    PORTB = (0<<PB1);  
43
  }
44
  return 1;
45
}

--

Bitte in Zukunft die Formatierungszeichen für Quelltext ([с][/с]) 
verwenden.

-rufus
#3877436
Lesenswert?

Sind ein paar Frage erlaubt ?

was ist PC5 ?

was ist /char = c;/ - wird das überhaupt übersetzt ?

Ich würde in der ISR USART_RXC_vect ein Event-Flag setzen (neues 
Zeichen da!).

Eine weitere Möglichkeit ist, das empfange Zeichen in einem RX-Fifo zu 
speichern und über die RX-Fifo Methode new_char():
1
bool_t rx_fifo_new_char(void);
abfragen, ob neue Zeichen eingetroffen sind.

was soll den hier passieren ?
1
else {
2
}
3
PORTB = (0<<PB1);

Das was ist mir klar.
Gast #3877617
Lesenswert?

Vielen Dank schonmal für die Beteiligung, ich bin echt beeindruckt von 
diesem Forum !

ja in dem Quellcode sind echt grobe Fehler drin, dafür muss ich mich 
entschuldigen und ein bisschen konzentrieren.

meine nächste Frage ist, kann ich diese ganze Umwandlung umgehen indem 
ich dem MC hexadezimalzahlen schicke? ich glaube für meine Anwendung 
würde das reichen ...
#3877638
Lesenswert?

Kanaille schrieb:

> ja in dem Quellcode sind echt grobe Fehler drin, dafür muss ich mich
> entschuldigen und ein bisschen konzentrieren.

Das solltest du unbedingt.

> meine nächste Frage ist, kann ich diese ganze Umwandlung

welche Umwandlung?

Ob du im Programm schreibst
1
...
2
    if( c == 'E' )             // E wie 'ein'
3
      PORTB &= ~( 1 << PB1 );
4
    else if( c == 'A' )        // A wie 'aus'
5
      PORTB |= ( 1 << PB1 );     
6
...

und dann auf deinem Terminal die Taste E bzw. A drückst, ist doch völlig 
unabhängig davon, dass die Variable volatile sein muss (weil sie in 
einer ISR beschrieben und in main abgefragt wird) und dass du dein C 
richtig schreiben musst.

Viellcith solltest du deine ersten Versuche mal mit einer 
Nicht-Interrupt-getriebenen Lösung machen, wenn du mit Interrupts noch 
nicht so auf du-und_du stehst und noch mit recht banalen C Grundlagen 
kämpfst?
#3877642
Lesenswert?

Und noch ein kleiner Tipp:
Du hast eine UART. DIe kann man auch wunderbar dazu benutzen, dass einem 
das Programm dort Ausgaben machen kann. Zb. Ausgaben, in denen einem das 
Programm selber mitteilt, was es aus welchem Grund gemacht hat.
Es gibt kein Gesetz, dass einem verbieten würde, während der 
Entwicklungszeit Ausgaben zu machen, die im endgültigen Programm dann 
wieder rausfliegen.
Gast #3877726
Lesenswert?

irgendwie kommt hier nichts an..
muss ich die Variable noch irgendwo zwischenspeichern oder hat das vll. 
was mit dem Terminal zutun?
MfG

[с]
#include <stdlib.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define F_CPU 16000000UL

/* 9600 baud */
#define BAUD  9600
#include <util/setbaud.h>

volatile c = '2';

void setutil(){
  UBRR0H = UBRRH_VALUE;
  UBRR0L = UBRRL_VALUE;
  UCSR0C = (1<<UCSZ01)|(1<<UCSZ00); // Asynchron 8N1
  UCSR0B |= (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0);
}


ISR(USART_RX_vect){

  c = UDR0;
}

int main(void) {
  setutil();
  DDRD |= (1<<4);
  sei();
  while (1) {
    if( c == '2' )
    PORTD = ( 0 << PD4);
    else if( c == '1' ) {
    PORTD = ( 1 << PD4 );
    }
  }
  return 1;
}
[/с]
#3877746
Lesenswert?

Kanaille schrieb:
> irgendwie kommt hier nichts an..

Dann würde ich halt mal an deiner Stelle die Umkehrung probieren.
Nicht der PC sendet, sondern der µC sendet. Denn im Unterschied zum µC 
kannst du im Terminal-Programm vom PC, ob vom µC was kommt und wenn ja, 
ob das richtig ist.

> int main(void) {
>   setutil();
>   DDRD |= (1<<4);
>   sei();

    uart_putc( 'x' );


eventuell in einer Schleife mal 10 oder 20 mal ein x ausgeben.
Wenn du die x im Terminal nicht siehst, dann stimmt was nicht.
Und dem solltest du zuerst nachgehen, ehe du im Nebel stocherst, warum 
am µC nichts ankommt oder das falsche ankommt oder..

Stimmt die Ausgabe am Terminal, dann hindert dich nichts und niemand 
daran, mal den µC das was er gekriegt hat, zurückschicken zu lassen

  while (1) {
    uart_putc( c );

    if( c == '2' ) PORTD = ( 0 << PD4);
    else if( c == '1' ) { PORTD = ( 1 << PD4 );
  }


Aber erst muss die Datenrichtung µC->PC funktionieren. Wenn die nicht 
funktikoniert, brauchst du mit der Gegenrichtung PC->µC gar nicht erst 
anfangen.


(Handshake am PC hast du abgeschaltet?)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren