www.mikrocontroller.net

Forum: Compiler & IDEs Mega168 Modul Seriell ansprechen


Autor: Moritz Sch (mollitz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

Ich sitz jetzt schon Tage daran meinen 
ATMega168(http://embedit.de/content/view/37/26/) seriell anzusprechen.
Ich habs mit mehreren eigenen und mehreren kopierten(aus dem Internet) 
Quelltexten und mit Linux und Windows probiert.
Hier mal ein Beispiel aus dem Internet, das einwandfrei kompiliert:

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>

#define USART_BAUDRATE 9600
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)

int main (void)
{
  DDRB = 0xff;
  PORTB = 0xff;
  UCSR0B |= (1 << RXEN0) | (1 << TXEN0);   // Turn on the transmission 
and reception circuitry
   UCSR0C |= (1 << UMSEL00) | (1 << UCSZ00) | (1 << UCSZ01); // Use 
8-bit character sizes

   UBRR0L = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value 
into the low byte of the UBRR register
   UBRR0H = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate 
value into the high byte of the UBRR register

   UCSR0B |= (1 << RXCIE0) | (1 << RXC0); // Enable the USART Recieve 
Complete interrupt (USART_RXC)
   sei(); // Enable the Global Interrupt Enable flag so that interrupts 
can be processed
   while(1);
}

ISR(SIG_USART_RECV)
{
   char ReceivedByte;
   ReceivedByte = UDR0; // Fetch the recieved byte value into the 
variable "ByteReceived"
   UDR0 = ReceivedByte; // Echo back the received byte back to the 
computer
   if(PORTB == 0xff)
     PORTB = 0x00;
   else
     PORTB = 0xff;
}

Die 3 wichtigen Pins RxD, TxD und Ground sind mit dem PC verbunden( RxD 
und TxD sind gekreuzt).
Signale geb ich mit SuperTerm 2. Ich Connecte mit der Baudrate 9600 auf 
den entsprechenden COM-Port und schreib was ins Terminal-> Nichts 
passiert.

Was mir unter Linux mit einem anderen Quelltext, in dem nur das RXEN0 
angeschaltet sein musste und ein serielles Signal ankommen musste, 
passiert ist, war dass der Controller einfach gar nichts mehr getan hat. 
(Da war eine while Schleife, die die Lampe immer an und ausgeschalten 
hatte und wo das Byte kam, blieb die Lampe an bzw. aus).

Sicher ist das ganze ein Anfängerfehler da ich aber schon ewig 
rumprobiere, kann ich grad echt nicht weitergooglen. Ich finde einfach 
nichts mehr, weil ich nicht weiß obs am PC, am Kabel, am Controller oder 
sonst was liegt.

Für Hilfe wär ich sehr dankbar,

Moritz

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moritz Sch wrote:

> Hier mal ein Beispiel aus dem Internet, das einwandfrei kompiliert:

Bitte benutze [c]-Markierungen um deine Quelltexte, sonst kann die
keiner mehr lesen.

> Die 3 wichtigen Pins RxD, TxD und Ground sind mit dem PC verbunden( RxD
> und TxD sind gekreuzt).

Aber RS-232-Levelshifter (und -Inverter) hast du drin, ja?

Autor: Stefan P. (form)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast Du einen Pegelwandler zwischen AVR und PC?
Die TTL-Signale (0V 5V) müssen erst noch auf höhere Pegel (+12V -12V) 
gebracht werden, damit der PC damit was anfangen kann.

z.B. Der MAX232 ist dafür da.....

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan P. wrote:

> Hast Du einen Pegelwandler zwischen AVR und PC?
> Die TTL-Signale (0V 5V) müssen erst noch auf höhere Pegel (+12V -12V)
> gebracht werden, damit der PC damit was anfangen kann.

Vor allem müssen sie negiert werden.  Viele PC-Schnittstellen
würden vermutlich statt ±12 V ganz brauchbar mit 0 V / 5 V
hinkommen, aber dummerweise entspricht TTL/CMOS-High einem
RS-232-Pegen von -(5...12) V und TTL/CMOS-Low einem RS-232-Pegel
von +(5...12) V.

Autor: Moritz Sch (mollitz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auf dem Modul ist ein Pegelwandler für RS232 Signale untergebracht. Dadurch kann das Modul von
einem PC gesteuert werden oder kann selbst über die serielle Schnittstelle andere Geräte steuern. Die
RS232 Signale sind auf einer 10 poligen Stiftleiste herausgeführt wie sie auch auf einem PC Mainboard zu
finden sind.
Ein Pegelwandler ist auf dem Modul. Ich geh mal davon aus, dass er die 
Signale gleich noch mit invertiert.

Autor: Moritz Sch (mollitz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

Also ich habe jetzt mal einen neuen Code (unter Linux) probiert:
#include <avr/io.h>
#include <avr/interrupt.h>

#include <stdint.h>
#include <util/delay.h>

#define USART_BAUD_RATE 9600
#define USART_BAUD_SELECT (F_CPU/(USART_BAUD_RATE*16L)-1)


uint16_t gloFrequ;

int main()
{
  //SREG |=(1<<7);
  sei();

  UBRR0H = (unsigned char)(USART_BAUD_SELECT>>8);
  UBRR0L = (unsigned char)USART_BAUD_SELECT;
  UCSR0B = (1<<RXEN0)|(1<<TXEN0) | (1<<RXCIE0);
  /* Set frame format: 8data, 2stop bit */
  UCSR0C = (1<<USBS0)|(3<<UCSZ00);

  DDRC = 0xff;
  DDRB = 0xff;
  //register aktivieren
  PORTB = 0xff;
  PORTC = 0xff;
  gloFrequ=500;
  //lichter an aus
  while(1)
  {
    _delay_ms(gloFrequ);
    if(PORTB == 0xff)
      PORTB = 0x00;
    else if(PORTB == 0x00)
      PORTB = 0xff;
  }
  return(0);
}

ISR(USART_RX_vect)
{
  gloFrequ = 100;
  PORTC = 0xFF;
}

//
und folgendes festgestellt: Sende ich ein Byte auf den seriellen Port, 
dann wird der Controller um ca. 1/10 langsamer. (die Lampe blinkt 
langsamer).
der code in ISR(USART_RX_vect) wird nicht ausgeführt. (PORTC wird nicht 
aktiviert und die lampe blinkt nach senden eines Bytes unabhängig von 
gloFrequ = ...; immer gleich schnell.
Kommentiere ich die ISR-Funktion komplett aus, dann bleibt der 
Controller ganz stehen (die Lampe bleibt bei dem Wert, als das Byte 
gesendet wurde).

Ideen?

Gruß Moritz

Autor: Michael Potthoff (mipo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du nutzt ein _delay_ms(), daher musst Du die Optimierung anschalten, 
damit das richtig funktioniert, hast Du das? (siehe 
http://www.mikrocontroller.net/articles/AVR-GCC-Tu...)

Ist das Modul tatsächlich mit 20 MHz getaktet, sprich sind die Fuses 
richtig gesetzt? (http://www.mikrocontroller.net/articles/AVR_Fuses)

Wo wird F_CPU definiert? Makefile? Einfach mal "#define F_CPU 20000000" 
Testweise ausprobieren.

Ansonsten 
http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

Autor: Moritz Sch (mollitz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erstmal zu dem Mhz-Problem: Ich verwende Eclipse AVR Plugin und da kann 
ich den Projekt-Einstellungen die Frequenz einstellen. Wenn ich die 
verändere verändert sich auch die Geschwindigkeit mit der die Lampe 
blinkt.
Und wenn ich die Frequenz auf 20000000 stelle, dann blinkt die Lampe 
auch so schnell wie sie soll. (In meinem Code einmal an und einmal aus 
pro Sekunde). Das heißt doch, dass F_CPU richtig ist oder?

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> der code in ISR(USART_RX_vect) wird nicht ausgeführt.

Vermutlich doch.

> (PORTC wird nicht aktiviert

Was soll denn da aktiviert werden? Du setzt den Port doch schon in 
main auf 0xFF, wie soll denn das "PORTC = 0xFF;" in der ISR noch 
irgendetwas sichtbares bewirken?

> und die lampe blinkt nach senden eines Bytes unabhängig von
> gloFrequ = ...; immer gleich schnell.

Weil du gloFrequ nicht volatile deklariert hast.

Und dass der Controller scheinbar langsamer wird, liegt daran, dass du 
in der ISR das UART-Datenregister nicht ausließt. Deshalb wird der 
Interrupt nach Verlassen der ISR sofort (naja, fast sofort, nach einem 
Befehl) wieder ausgelöst, und die ISR wird daher immer und immer wieder 
ausgeführt.

Autor: Moritz Sch (mollitz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

Hab grad nicht so viel Zeit, werd mich aber nachher vielleicht mal drann 
setzen und das Register auslesen.

Autor: Moritz Sch (mollitz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank jetzt tuts:
#ifndef F_CPU
#define F_CPU 20000000UL
#endif

#include <avr/io.h>
#include <avr/interrupt.h>

#include <stdint.h>
#include <util/delay.h>


#define USART_BAUD_RATE 9600
#define USART_BAUD_SELECT (F_CPU/(USART_BAUD_RATE*16L)-1)


volatile uint16_t gloFrequ;

int main()
{
  //SREG |=(1<<7);
  sei();

  UBRR0H = (unsigned char)(USART_BAUD_SELECT>>8);
  UBRR0L = (unsigned char)USART_BAUD_SELECT;
  UCSR0B = (1<<RXEN0)|(1<<TXEN0) | (1<<RXCIE0);
  /* Set frame format: 8data, 2stop bit */
  UCSR0C = (1<<USBS0)|(3<<UCSZ00);

  DDRC = 0xff;
  DDRB = 0xff;
  //register aktivieren
  PORTB = 0xff;
  gloFrequ=500;
  //lichter an aus
  while(1)
  {
    _delay_ms(gloFrequ);
    if(PORTB == 0xff)
      PORTB = 0x00;
    else if(PORTB == 0x00)
      PORTB = 0xff;
  }
  return(0);
}

ISR(USART_RX_vect)
{
  gloFrequ = UDR0*5;
}

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.