mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Atmega16L @ gcc [Prg. läuft nur Debug Mode]


Autor: luke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo.

Meine ersten Gehversuche mit einem AVR werfen zahlreiche Fragen auf. Auf 
einige findet sich eine Antwort auf andere nicht.
Der letztere Umstand zwingt mich hier um Rat zu bitten.

Ich benutze folgendes:

AVRStudio 4 @ gcc (neueste Version) sowie einen Atmega16L.

Das folgende Programm liest eine Zeichenfolge über RS232 ein, extrahiert 
daraus eine Zahl mit Hilfe von sscanf() und schreibt diese in das OCR0 
Register des Timer0, um die Tastrate der Fast-PWM zu stellen.

Das Ganze funktioniert allerdings nur im Debug-Modus.
Wenn ich das Programm direkt, also nich im D-Modus, im Controller laufen 
lasse. So stelle ich fest (Debug-LED), dass kein Sprung in 
"ISR(USART_RXC_vect)" stattfindet, nachdem ich ein Zeichen zum µC sende.

Woran kann das liegen?

Vielen Dank & Grüße
luke
/* . */

#include <avr/io.h>
#include <avr/interrupt.h>
#include "C:/Program Files/Atmel/WinAVR/avr/include/stdio.h"

#define F_CPU       7372800UL

#define BAUD        9600UL
#define UBRR_BAUD   ((F_CPU/(16UL*BAUD))-1)

volatile char intflg = 0;
volatile unsigned char rx_buf[6];
volatile unsigned char n = 0;
char test = 0;
unsigned int druck = 0;
unsigned char cdruck = 0;


// Funktionsdeklarationen
void pwm_conf( void);
void uart_init(void);




int main(void)
{
    uart_init();
  pwm_conf();

    sei();



    while(1)
  {

    if( (intflg & 0b00000001) & 0b00000001)
    {

      sscanf( rx_buf,"D%i.", &druck);

      druck = (druck*0.0254);
      cdruck = (unsigned char)druck;
         while ( !( UCSRA & (1<<UDRE)) );
      UDR = cdruck;
      OCR0 = cdruck;
      PORTB ^= (1<<PB4); 
      intflg = ( 0b11111110 & intflg);
    }
    
  }
        
}


// Interrupt wird ausgelöst sobald neue Daten im USART-Empfangspuffer liegen
ISR(USART_RXC_vect)
{
  unsigned char buffer;
    // Daten aus dem Puffer lesen ...
    buffer = UDR;
  rx_buf[n]=buffer; n++;
  if( buffer == '.'){ n= 0; intflg = ((intflg & 0b111111111) | 0b00000001);}
  
}


// Konfiguriert Timer0 für den Fast-PWM Modus
void pwm_conf( void)
{
//           +++------- Clock Source
  TCCR0 = 0b01111001;
//         +  +---------- Waveform Generation Mode


  OCR0 = 120; // Vergleichsregister. Wenn wert erreicht -> Ausgang TOGGLE

//Port D pins as input

  DDRD=0x00;

//Enable internal pull ups

  PORTD=0xFF;

//Set PORTB1 pin as output

  DDRB=0xFF;

  OCR0 = 0;
}




void uart_init(void)
{
    // Baudrate einstellen (Normaler Modus)
    UBRRH = (unsigned char) (UBRR_BAUD>>8);
    UBRRL = (unsigned char) (UBRR_BAUD & 0x0ff);

    // Aktivieren des Empfängers, des Senders und des "Daten empfangen"-Interrupts
    UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);

    // Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit
    UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
}

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
luke schrieb:
> while ( !( UCSRA & (1<<UDRE)) );
Diese Zeile im Hauptprogramm ist eine unendliche Schleife.  Denn UDRE 
wird zwar beim Empfang eines Zeichens gesetzt.  Da aber der Rx-Interrupt 
aktiv ist, wird bei Zeichen sofort die Interruptroutine angesprungen, 
dort UDR ausgelesen und damit UDRE gelöscht -- und bis die UDRE-Abfrage 
im Hauptprogramm ausgeführt wird, ist UDRE längst wieder 0.

Es gibt auch sonst noch einiges Verbesserungspotenzial, z.B. bei der 
Bitmanipulation.  Meditiere doch mal über folgende Zeilen (die zwar 
nicht falsch sind, aber so recht unsinnig):
intflg = ((intflg & 0b111111111) | 0b00000001);
if( (intflg & 0b00000001) & 0b00000001)
 ...

Ein Bufferüberlauf (Index n für rx_buf) wird nicht abgefangen.  Auch das 
eine Stelle, die zwar momentan notfalls geht, aber so nicht bleiben 
sollte, denn Schnittstellen sind notorisch für potentielle Überläufe.

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.