PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : USART simulieren im Atmelstudio6



marcus.m
23.01.2014, 13:28
Hallo,

ich bin nach etlichen Jahren Abstinenz wieder zum MCU Programmieren gekommen.
Ich habe die letzten Jahre vorwiegend Elektronikschaltungen entwickelt und programmieren "lassen".
Früher habe ich selber meistens mit Microchip und in Assembler gearbeitet, leider nur wenig mit den Atmels und dem AVR Studio 4.

Leider habe ich meine C Kenntnisse nie so wirklich gepflegt bzw. ausgebaut (ich hatte ja einen Programmierer).
Jetzt wollte ich das nachholen und habe mir das Atmelstudio6 zugelegt.
Leider sieht das alles etwas ungewohnt aus und ich komme nicht wirklich voran.

Ich wollte für ein kleines Heimprojekt (Haus Bus zum Üben) eine „minimale“ Kommunikation über eine RS485 Hardware realisieren.
Als MCU habe ich mir den ATMega64 ausgeguckt, und schon ein klein wenig Code geschrieben.

Da ich noch keine Hardware zum Üben habe wollte ich das mal mit dem Simulator durchtesten.

Ich komme aber nie in die ISR (der Breakpoint wird nie erreicht).
Den Registereintrag RXC0 kann ich zwar setzen, aber zur ISR führt das nicht.

Was mache ich falsch? Geht das überhaupt?
Das UDR0 kann ich auch nicht beschreiben um dort etwas zu sehen.

Über Hilfe würde ich mich freuen.
Bitte aber berücksichtigen, dass ich mit C üblichen Vorgehensweisen noch nicht so vertraut bin.
;)


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

/* F_CPU = 16000000UL MCU Frequenz 16MHz externes Quarz
global gesetzt unter AVR/GNU C Compiler - Symbols*/

#define USART_BAUD_RATE 9600 //gewünschte Baudrate

#define USART_BAUD_CALC (F_CPU/(USART_BAUD_RATE*16L)-1) //berechnet Registerwerte für Baudrate

#define LOW(x) ((x) & 0xFF) //LOW-Byte
#define HIGH(x) (((x) >> 8) & 0xFF) //HIGH-Byte

volatile uint8_t data=0x00; //nur zum Anschauen im Watch

ISR (USART0_RX_vect) //Interrupt wenn empfang abgeschlossen
{
data=UDR0;
UDR0=data;

}



int main(void)
{


DDRA=0b00000000;
DDRB=0b11111111;
DDRC=0b11111111;
DDRD=0b10111011;
DDRE=0b10111110;
DDRF=0b11111111;
DDRG=0b11111;


UBRR0H = HIGH(USART_BAUD_CALC); //Setzen des HIGH-Byte vom USART-Register für Baudrate
UBRR0L = LOW (USART_BAUD_CALC); //Setzen des LOW-Byte vom USART-Register für Baudrate

UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<RXCIE0); //Empfangen, Senden und Empfangsinterrupt aktivieren
UCSR0A = (1<<MPCM0); //Bit zur "SLAVE" Kennzeichnung !/nur Adressen ansehen, Daten ignorieren

//Codierungsbits abfragen und RRS485-ID Adressierung festlegen


sei(); //Interruptfreigabe


while(1)
{


PORTG =0b10101; //setzt Port G Bitmuster nurm zum Anschauen im IO View
PORTG ^=(1<<PG1); //toggelt Port G Bit 1

}

}

marcus.m
24.01.2014, 07:22
Hallo,?

Hat denn keiner eine Idee?

Ich wäre sehr froh wenn sich mal jemand meldet.
Hits habe ich schon eine Menge, aber noch keine Antworten.

Gruß an alle

Stone
24.01.2014, 09:18
Kommunikation zu Simulieren ist immer schwierig mit dem Simulator. Das die ISR aufgerufen wird müsstest du das Interrupt-Flag händisch aktivieren.
Aber du kannst ja mit anderen Sachen mal starten und wenn die Hardware da ist mit der Uart Schnittstelle weiter machen.

Kleiner Tipp



DDRD=0b10111011;

so würde ich das nicht schreiben ist einfach unübersichtlich.
lieber


DDRD = (1<<PD7)|(1<<PD5)|(1<<PD4)|(1<<PD3)|(1<<PD1)|(1<<PD0);

Dauert zwar länger zum schreiben, aber liest sich viel schneller als Bits zählen

Sonst sieht eigentlich ganz gut aus für den Anfang.


Gruß Matthias

marcus.m
24.01.2014, 09:36
Danke für den Tipp mit der Bit Zählerei (da hab ich mich schon öfter verzählt ;) ).

Das Flag händisch zu setzen hatte ich schon versucht. Hat nichts gebracht.

Ich habe schon begonnen mir Gedanken über den Rest zu machen (Aufbau des Protokolls, FIFO-Register usw.).
Ist ne zähe Sache, wenn man nebenbei erst noch C (neu) lernen muss.

Gruß Marcus

Stone
24.01.2014, 10:40
Fang erst mal klein an. LEDs an/aus, Taster, Timer, PWM, ... . So kannst du dich schrittweise einarbeiten und an die C Syntax gewöhnen.. Wenn du zu komplex startest wirst du früher oder später frustriert aufgeben.

Gruß Matthias

sternst
24.01.2014, 11:34
Das Flag händisch zu setzen hatte ich schon versucht. Hat nichts gebracht.
Debug -> Options and Settings -> Tools -> Tool Settings -> Mask interrupts while stepping


BTW:
#include <avr (http://www.rn-wissen.de/index.php/AVR-Einstieg_leicht_gemacht)/iom64.h>
Dies hat in deinem Code nichts zu suchen. Du inkludierst immer nur <avr/io.h>.

marcus.m
24.01.2014, 13:01
Debug -> Options and Settings -> Tools -> Tool Settings -> Mask interrupts while stepping

und dann?

Default ist auf True, Ändern auf False bringt auch nichts.

Das #include <avr/iom64.h> habe ich drin, weil ich mit dem ATMega64 arbeiten will.

Ohne hatte ich nicht alle Ports bis G zur Verfügung,
die kamen erst nach dem Einbinden von iom64.h

Gruß Marcus

@Stone
...LEDs an/aus, Taster, Timer, PWM, ...

Ports "wackeln" kann ich schon. :cool:

- - - Aktualisiert - - -


/************************************************** **************************
** - iom64.h -
**
** This file declares the internal register addresses for ATmega64.
**
** Used with iccAVR and aAVR.
**
** Copyright IAR Systems 2002. All rights reserved.
**
** File version: $Revision: 1.8 $
**
************************************************** *************************/

#ifdef __IAR_SYSTEMS_ICC__
#ifndef _SYSTEM_BUILD
#pragma system_include
#endif
#endif



Gruß Marcus

- - - Aktualisiert - - -

Das mit dem DDRn Register ist echt praktisch.
Kann man mit den internen PullUp kombinieren (wer will).




int main(void)
{

RS485_Adresse=0x00;



DDRA =(0<<PA7) | (0<<PA6) | (0<<PA5) | (0<<PA4) | (0<<PA3) | (0<<PA2) | (0<<PA1) | (0<<PA0); //Richtung
PORTA=(1<<PA7) | (1<<PA6) | (1<<PA5) | (1<<PA4) | (1<<PA3) | (1<<PA2) | (1<<PA1) | (1<<PA0); //int. PullUp
DDRB =(1<<PB7) | (1<<PB6) | (1<<PB5) | (1<<PB4) | (1<<PB3) | (1<<PB2) | (1<<PB1) | (1<<PB0); //Richtung

DDRC =(1<<PC7) | (1<<PC6) | (1<<PC5) | (1<<PC4) | (1<<PC3) | (1<<PC2) | (1<<PC1) | (1<<PC0); //Richtung

DDRD =(1<<PD7) | (0<<PD6) | (1<<PD5) | (1<<PD4) | (1<<PD3) | (0<<PD2) | (1<<PD1) | (1<<PD0); //Richtung
PORTD= (1<<PD6) | (1<<PD2) ; //int. PullUp
DDRE =(1<<PE7) | (0<<PE6) | (1<<PE5) | (1<<PE4) | (1<<PE3) | (1<<PE2) | (1<<PE1) | (0<<PE0); //Richtung
PORTE= (1<<PE6) | (1<<PE0); //int. PullUp
DDRF =(1<<PF7) | (1<<PF6) | (1<<PF5) | (1<<PF4) | (1<<PF3) | (1<<PF2) | (1<<PF1) | (1<<PF0); //Richtung

DDRG = (1<<PG4) | (1<<PG3) | (1<<PG2) | (1<<PG1) | (1<<PG0); //Richtung




".. verrutscht leider immer in der Ansicht"

Gruß Marcus

sternst
24.01.2014, 13:22
Das #include <avr/iom64.h> habe ich drin, weil ich mit dem ATMega64 arbeiten will.

Ohne hatte ich nicht alle Ports bis G zur Verfügung,
die kamen erst nach dem Einbinden von iom64.h
Dann kompilierst du nicht für den richtigen Controller (in den Projekt-Einstellungen einstellen). Das erklärt dann auch die nicht funktionierenden Interrupts.

Nochmal: Du inkludierst immer nur <avr/io.h>, niemals die Controller spezifischen Header.
Und schon gar nicht besorgst du dir von irgendwo her einen Header, der noch nicht mal für den von dir verwendeten Compiler gedacht ist. Oder was genau wolltest du uns mit dem Posten des IAR-Headers sagen?

marcus.m
24.01.2014, 13:53
...Header, der noch nicht mal für den von dir verwendeten Compiler gedacht ist. Oder was genau wolltest du uns mit dem Posten des IAR-Headers sagen?

Hatte die falsche Datei geöffnet. Ich benutze natürlich den aus dem AtmelStudio.

Den Controller habe ich schon vorher eingerichtet.
27320

Nach dem entfernen des #include <avr/iom64.h> ist nach dem "Build" wieder der iom64.h dabei.
Ist das normal?

Gruß
Marcus

sternst
24.01.2014, 14:09
Nach dem entfernen des #include <avr/iom64.h> ist nach dem "Build" wieder der iom64.h dabei.
Ist das normal?Ja. Es wird ja über <avr/io.h> automatisch eingebunden. Du sollst es nur nicht selber direkt einbinden, weil es nicht nur unnötig ist, sondern schlimmstenfalls andere Fehler überdeckt (wie eben einen falschen eingestellten Controller).

marcus.m
24.01.2014, 14:43
OK, Danke.

So, jetzt geht's weiter.

:gift

UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<RXCIE0);


wer sieht den Tippfehler.

Jetzt kann ich den Interrupt "händisch" aufrufen.
Gruß Marcus

Wochenende....

marcus.m
27.01.2014, 09:57
Hallo,

soweit habe ich den manuellen Interrupt Aufruf im Griff.
Auch wenn ich im Register UDR0 (USART I/O DATA REGISTER) nichts schreiben oder lesen kann.

Jetzt wollte ich die "Stimuli" Datei benutzen um einige Anfangszustände an den I/O Ports zu simulieren.

Ich finde aber (blöder Weise) nur den Aufruf dieser Datei.

Wie kann ich die aber erstellen?

Kennt das einer von euch für das Atmelstudio6?

Ferdinand
07.02.2014, 22:01
Hi

Wie ist das den mit dem neuen AVR Studio 6.1 und den ISR schlüssel Wörter, da wurde doch so fiel geändert, ich benutze den ATmega644p wo finde ich ein aktuelles TUT oder eine aktuelle Lib für uart ich habe sonst immer die http://homepage.hispeed.ch/peterfleury/group__pfleury__uart.html (http://http://homepage.hispeed.ch/peterfleury/group__pfleury__uart.html) verwendet nun aber scheint die nicht mehr aktuell zu sein.

marcus.m
11.02.2014, 11:37
Hallo,

@Ferdinand
bei mir kam das (denke ich, ich übe noch) alles mit den Einstellungen Device (ATMega64).
Dadurch hat der Compiler die iom64.h dazu gepackt.
Da steht einiges drin.

Kennt jemand den Syntax für eine STIM-Datei im Studio6?
Da gibt es ja so gut wie keine Dokumentation.
Oder ich finde sie nicht.:(

marcus.m
24.02.2014, 15:38
Hallo,

ich brauche noch einmal Hilfe.

Ich habe mir jetzt ein Board zum Testen beschafft (fertiges Hardware mit ATMega und RS485 Schnittstelle).
Nun wollte ich meinen Code zum ersten Test auf das Board laden. Das geht aber nicht.
Ich bekomme immer einen Timeout.
Wenn ich den Programmer (AVRISP mkII) und das Device auswähle, dann auf Apply drücke, kommt nach einer gewissen Zeit eine Fehlermeldung. Die Meldung kann man wegdrücken mit "noch eine Minute warten" oder Stoppen.
27597
Warten bringt nichts (die Meldung kommt wieder), nach dem Stoppen geht es weiter aber das ganze scheint nicht mehr stabil zu sein.

Bemerkenswert ist auch das Verhalten des mkII alle LED sind grün und die Kommunikation ist auch gegeben.
Nur während der "Apply" Phase zeigt das Atmelstudio den mkII als "Disconnected".
2759927600
Danach ist der mkII aus der Toolauswahl raus er funktioniert aber noch und liest fleißig ID, Spannung und Fuses aus.
2760127602
Erase und Verify funktionieren auch (sagt das Studio) nur programmieren kann ich nicht. Dann kommt wieder das "Warte eine Minute...".

Ich bin langsam am Verzweifeln.
Kennt einer von euch das Problem und eine Lösung?

Danke im Voraus.

Gruß
Marcus

wkrug
24.02.2014, 17:16
Versuch mal die ISP Taktfrequenz von 125kHz auf 250kHz zu ändern und probiers dann noch mal.

marcus.m
25.02.2014, 11:54
Hallo,

ich habe die Taktrate von 125 auf 64 und auch schon auf 250 geändert, hat nichts gebracht.
Ich habe mittlerweile herausgefunden, dass ich nach jedem einzelnen Schritt eine Fehlermeldung provozieren muß.

Dann komme ich in Einzelschritten durch!
apply=>timeout(quit mit stop)=>erase=>ok=>programming=>timeout(quit mit stop)=> programming=>ok=>verify=>timeout(quit mit stop)=>verify=>ok

Das kann es aber doch nicht sein, oder?

Ich bin mir nicht sicher ob der USB Treiber das tut was er soll.
Ich habe jetzt schon (leider) öfter gelesen,
dass es Probleme mit dem Atmelstudio6 und dem AVRISP mkII gibt.
Ich möchte jetzt aber nicht auf ein älteres Studio wechseln, da ich mich gerade auf dem 6er eingearbeitet habe.

Gruß
Marcus