PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Anfänger in C sucht Tutorial-Empfehlung



oberallgeier
16.11.2007, 14:45
Hallo,

nun muss/will ich endlich C lernen.

Meine bisherigen Erfahrungen sind (vor Ewigkeiten) Fortran (damals u.A. auf Cray´s - später auch MSFortran77) und Assembler (8080/Z80) - sehr umfangreich, kaum was in Basic (aber schon mal ne DGL höherer Ordnung) und homöopathische Spuren von JAVA.

Ich will in die Robotik - entsprechend diesem Forum - einsteigen. Da ist C sicher angebracht (-er für mich als Basic). Nachdem ich jetzt doch mehrere Wochen mit Assembler an einem tiny13 geübt habe, will ich C lernen und suche einen guten Einstieg.

Bisher bin ich gestolpert (bin da aber nie tief eingedrungen) über das AVR-GCC-Tutorial, über Helmut Schellong´s C-Tutorial, über den C-Kurs der ...fh-augsburg.de/informatik/vorlesungen..., im roboternetz über die Kategorie:Quellcode C, über die sehr knappe Darstellung - 9. C für ASURO - im asuro-Handbuch und noch einige kleinere Abhandlungen (und über viele, sehr interessante, aber meist eher spezielle Threads hier - SEHR nützlich - die sind eher für später mal).

Ich habe also die Qual der Wahl - und bitte euch um Rat. Dabei ist mir klar, dass es persönlich unterschiedliche Empfehlungen geben wird. Aber ich erhoffe mir eben ein bisschen "Richtungsempfehlungen" - sonst werde ich mit dem ASURO-Handbuch anfangen und danach - mal weitersehen. Wobei ich nicht sicher bin, dass ich dann das Buch von Ritchie und Kerninghan durcharbeite (wie es das ASURO-Handbuch empfiehlt). Vielleicht - weil ich selber schon so alt bin :)

So, und nun schon mal danke für Eure Ratschläge

uwegw
16.11.2007, 16:16
Das Standard-Tutorial für AVRGCC dürfte das von mikrocontroller.net sein. Und zu C allgemein findet man bei wikibooks.org noch einiges. Mit diesen beiden Quellen bin ich selbst sehr gut in C rein gekommen, wobei ich Vorerfahrungen mit AVRs unter Pascal und Programmierung allgemein mit Delphi hatte.

Hubert.G
16.11.2007, 16:48
Zum richtig C lernen ist ein Buch wie von Kernighan&Ritchi "Programmieren in C" das beste. Die Kontrollerplattform ist einen nicht sehr optimale Lernumgebung. Die Übungen sollte man daher auf einem C-Compiler für den PC machen und nicht mit dem AVR-GCC.

oberallgeier
16.11.2007, 22:24
Hallo uwegw und Hubert.G. Vielen Dank. Ich werds beachten (und mir DOCH den Ritchie-Kernighan antun :)). Hab sogar dem armen Kernighan vorhin ein "n" zuviel verpasst :(. Ja, und am PC üben. Es ist schauderhaft - aber daran hätte ich nun scheuklappenmässig nicht gedacht :( .

ReSeT
17.11.2007, 09:24
Ich hab C auch mit dem Kernighan gelernt. Ab und zu ein paar Programme für die Konsole geschrieben, dann hat man's schnell raus.

Das Kernighan und Ritchie Buch ist meines Erachtens nach das beste Buch über C, auch wenn es anfangs etwas gewöhnungsbedürftig ist.

Wichtig ist eher, daß man das Programieren an sich versteht, dann ist man fast überall zuhause.

oberallgeier
17.11.2007, 17:19
Gut, die beste von allen meinen Frauen hat mir heute das Buch von Kernighan/Ritchie bestellt.
Beim Rumstöbern habe ich ein Freeware gefunden: Visual C++ 2005 Express v8.0. Zwar von Microsoft, aber ... free ist free :) - und, da ich wirklich nicht so perfekt in englisch bin, wäre ich natürlich über vorwiegend deutsche Erklärungen froh.

a) Ist das Visual C++ 2005 sinnvoll für Lernzwecke? (weil da zwei plus hinterm C stehen :( )
b) Weiss jemand, ob da drin eine C-Version (ver-)steckt (ist) ?
c) Welche Alternativen sind empfehlenswert? (evtl. auch Bezahlversion).
d) wäre DJGPP eine sinnvolle Alternative (das scheint ja rein englisch zu sein) :(

Hubert.G
17.11.2007, 18:31
VisualC++ ist glaube ich nicht das ideale.
Hier gibts etwas freies, aber auch nur Neu-Deutsch
www.bloodshed.net/devcpp.html

izaseba
17.11.2007, 18:41
Hallo Joe,

Schau Dir mal Code::Blocks (http://www.codeblocks.org/) an.

Es ist erste Sahne, eine wirklich sehr gut gelungene Umgebung.

Allerdings empfehlt es sich die "nightly builds" Version zu ziehen.
Ein weiterer Vorteil liegt darin, daß man auch die AVR damit ohne Probleme programmieren kann !

Wenn Englisch kein KO Kriterium für Dich ist, ist es eine Überlegung Wert.

Gruß Sebastian

P.S.

K&R war schonmal eine gute Wahl...

oberallgeier
17.11.2007, 19:01
Hei Sebastian, schönen Abend,

danke für Deinen Hinweis. Ach - englisch geht schon, ich habe schon öfters in den USA Vorträge gehalten (und nie auf schwäbisch-bayrisch oder sonst einem deutschen Idiom) , habe auch anderswo auf internationalen Konferenzen englisch vorgetragen, und kann mich auch sonst im englischen Sprach-umfeld bewegen, persönlich und wenns sein muss auch literarisch - blos Sachbücher auf englisch - da quäle ich mich eben.

Ich werde Deinen Hinweis ansehen. Danke.

oberallgeier
24.11.2007, 11:24
Hallo Ihr freundlichen Ratgeber,

nun habe ich angefangen mit C :). (Anmerkung, nicht zum Lesen gedacht: ich bin SEHR zweckorientiert gewesen, habe mir die Anleitung zu C im Asuro durchgelesen, die Tutorials in RN und mikrocontroller.net und den einen oder anderen Codeschnippsel in der AVR-Doku und habe vorerst DOCH mit AVR-Studio/WinAVR angefangen - weil mir meine eigene Zeitplanung zu meinem eigenen Roboterprojekt im Nacken sitzt). Folgende Vorarbeiten:

1) Ein kleines Flashboard für den tiny2313 gebaut, mit je einer seitlichen Steckleiste am Controller
2) ... mit einem max232 (man will ja kommunizieren)

Der Test der selbstgebauten und beschafften Ausrüstung mit Assemblerroutinen z.B. zur Servoansteuerung geht ok. Da habe ich aber nix mit RS232 gemacht, klar. PonyProg 2.07a Beta und RN-ISP-Programmierkabel (ISP Dongle). Geht alles wirklich prima.

Ein kleines C-Programm geschrieben. Es sollte ja wirklich klein sein - "Hallo Welt" und eine LED auf PB2 anzünden.


/*
================================================== =========
Aufgabe:

Sende "Hallo Welt" über die RS232 UND
LED auf PB2 anzünden

Autor: JWT
================================================== =========
*/

#include <stdlib.h>
#include <avr/io.h>
/* #include <avr/iotn2313.h> <<< das is ja wohl nix */

#define MCU = attiny2313

// ### NEIN ### Mit Quarz 16 Mhz-CPU
// Interner Oszillator, 8 MHz
#define F_CPU = 8000000



// ### Portinitialisierung und waitms aus RNContr Demo C

// *### Ports setzen ###
// Ports auf HIGH/LOW setzen

static inline void setportbon(const uint8_t n)
{PORTB |= (1<<n);} //set PORTB.n high
static inline void setportboff(const uint8_t n)
{PORTB &= ~(1<<n);} //set PORTB.n low

/*### Programm pausieren lassen ###*/
/*Pausenwert ist nur experimentell !*/

void waitms(uint16_t ms)
{
for(; ms>0; ms--)
{
uint16_t __c = 4000;
__asm__ volatile (
"1: sbiw %0,1" "\n\t"
"brne 1b"
: "=w" (__c)
: "0" (__c)
);
}
}



// ------------------------------------------------------------------
// Dieser Codeschnipsel ähnlich 2313-doc, S 121

void USART_Init( unsigned int baud )

{
/* Set baud rate */
UBRRH = (unsigned char)(baud>>8);
UBRRL = (unsigned char)baud;
/* Enable receiver and transmitter */
UCSRB = (1<<RXEN)|(1<<TXEN);
/* Set frame format: 8data, 2stop bit */
UCSRC = (1<<USBS)|(3<<UCSZ0);
}

// ------------------------------------------------------------------
void sendchar(unsigned char c)
{
while(!(UCSRA & (1<<UDRE))) //Warten, bis Senden möglich ist
{
}

UDR = c; //schreibt das Zeichen aus 'c' auf die Schnittstelle
}

// ------------------------------------------------------------------
void sendUSART(char *s) //*s funktiniert wie eine Art Array - auch bei
// einem String werden die Zeichen (char)
// einzeln ausgelesen - und auf die
// Sendeschnittstelle übertragen
{
while(*s)
{
sendchar(*s);
s++;
}
}

// ------------------------------------------------------------------
/*### Hauptschleife ###*/
int main(void)
{

// for(uint8_t i=0; i<10; i++)
{
setportboff(2);
waitms(150);
setportbon(2);
}



USART_Init(9600); //USART initialisieren

/*###Text senden###*/

sendUSART("\r\n\n\n"); //Sendet Kenung und Text.
// "\r" setze Cursor auf Zeilenanfang,
// "\n" beginnt dann die nächste Zeile
sendUSART("**** ATtiny2313 *****\r\n");
sendUSART(" \r\n");
sendUSART("Hallo, Welt.\r\n");
sendUSART(" \r\n");
}


Nach einigen Mühen war der Code fertig. Die Mühen bestanden in Anpassungen an Fehlermeldungen des Compilers (AVRStudio aStudio4b528.exe mit SP 1 und WinAVR-20070525-install.exe).

Hmmm, ja, das wars dann. Der Code freut den Compiler beim Compilieren, der Maschinencode freut Ponyprog beim Flashen (Klartext - alles ohne Fehlermeldungen, nur ok-Meldungen) - aber die Reaktion der LED ist null - ebenso wie das Hyperterminal. Meine Hauptängste waren, dass die RS232 nicht läuft - aber dass nicht mal die LED mit C anzuzünden ist beschämt mich doch.

Ein Test der RS232-Verbindung zum PC mit der RN-Control 1.4 bringt die erwarteten Meldungen aufs Hyperterminal. Ich will nicht gleich den Mega32 umprogrammieren - sondern beim tiny2313 weitermachen, den habe ich ja auch mit Assembler schon etwas "im Griff" und er hat einen festen Posten im Projekt.

Kann bitte jemand sagen was an meinem ersten C-Programm falsch ist?

Hubert.G
24.11.2007, 11:37
Hast du die LED gegen VCC oder GND geschaltet, wenn gegen VCC dann geht sie nur so kurz an das du es kaum siehst, zu RS232 bin ich noch nicht gekommen "MITTAGESSEN"

robocat
24.11.2007, 12:33
den port als ausgang setzen könnte helfen:

DDRB = (1 << PB2); // Pin PB2 als ausgang

gruesse

oberallgeier
24.11.2007, 12:51
Hallo Hubert.G

hoffentlich hat´s geschmeckt :). Danke schon mal jetzt für Deine Mühe.

Ich habe das natürlich in Assembler getestet (mit demselben Aufbau :) ) - weil ich mir nicht über den Weg traue:


;================================================= ==================================
;* Schaltung ZU Test "erstes C-Programm" ###>>> t2313, auszugsweise
;
; Vcc -----------t2313-----+------------Vcc
; |
; | +------+ rLED|\ |
; +---+ 100R +-------| >+---+
; +------+ |/ | |
; |
; t2313-PB1=pin13---------------------+
;
;
; GND-------------------------------------------------GND
;
;================================================= ==================================
; Speicherbelegung
;r16 Mehrzweck, high-Byte in Pausen "pause_an", "pause_aus", "led_ende" u.ä.
;
;================================================= ==================================
; Deklarationen und Konstanten für den Praeprozessor
#define a r16 ;Kurzbezeichung für Allzweckregister r16
;
;================================================= ==================================

#include "tn2313def.inc"

; Interrupthandler-Tabelle (aus AT2313_doc2535.pdf, Seite 42)
; Address Code Labels ;Comments
.org 0x0000 rjmp reset ;Reset Handler

.org 0x0001 reti ; INT0 ;External Interrupt0 Handler
.org 0x0002 reti ; INT1 ;External Interrupt1 Handler
.org 0x0003 reti ; TIM1_CAPT ;Timer1 Capture Handler
.org 0x0004 reti ; TIM1_COMPA ;Timer1 CompareA Handler
.org 0x0005 reti ; TIM1_OVF ;Timer1 Overflow Handler
.org 0x0006 reti ; TIM0_OVF ;Timer0 Overflow Handler
.org 0x0007 reti ; USART0_RXC ;USART0 rX Complete Handler
.org 0x0008 reti ; USART0_DRE ;USART0,UDR Empty Handler
.org 0x0009 reti ; USART0_TXC ;USART0 TX Complete Handler
.org 0x000A reti ; ANA_COMP ;Analog Comparator Handler
.org 0x000B reti ; PCINT ;Pin Change Interrupt
.org 0x000C reti ; TIMER1_COMPB ;Timer1 Compare B Handler
.org 0x000D reti ;IRS für Timer0 CompareA Handler (t2313)
.org 0x000E reti ; TIMER0_COMPB ;Timer0 Compare B Handler
.org 0x000F reti ; USI_START ;USI Start Handler
.org 0x0010 reti ; USI_OVERFLOW ;USI Overflow Handler
.org 0x0011 reti ; EE_READY ;EEPROM Ready Handler
.org 0x0012 reti ; WDT_OVERFLOW ;Watchdog Overflow Handler
;
;================================================= ==================================
; Hauptprogramm
;================================================= ==================================
;
reset: ;=== Generelle Initialisierung
; Zuerst RAMEND und Stack definieren;
ldi a,RAMEND ;Ram Ende des tiny2313
out SPL,a ;Stack Pointer tiny2313 setzen
;
anfang: ;=== Nur ein Dummy-Hauptprogramm mit einer leeren Schleife
;
rcall mc_init ;Initialisiere den Mikrocontroller
;
sbi portb,2
;
anfang2:
rjmp anfang2
;
;================================================= ==================================
; Prozeduren
;================================================= ==================================
;
;
;================================================= ==================================
; Initialisierungprozeduren, für µC, ADC und Timer-ISR
;================================================= ==================================
;
mc_init: ;=== Initialisiere Mikrocontroller
;ALLE Register initialisieren hier := pull-ups einschalten
;
ldi a,0b11111111 ;
;Datenrichtung "Ausgänge" für ports 0 - 7
out ddrb,a
ldi a,0b00000000
out portb,a ; ports aus-(=) oder ein(1)schalten; low = sink
ret ;=====----->>>>>
;
;================================================= ==================================
; Interrupt-Service-Routine
;================================================= ==================================
;
;================================================= ==================================
; Ende des Quellcodes
;================================================= ==================================

.. da geht die Leuchte an - und bleibt es auch.

Hubert.G
24.11.2007, 13:33
Dieser Code läuft bei mir:
/*
================================================== =========
Aufgabe:

Sende "Hallo Welt" über die RS232 UND
LED auf PB2 anzünden

Autor: JWT
================================================== =========
*/

#include <stdlib.h>
#include <avr/io.h>
/* #include <avr/iotn2313.h> <<< das is ja wohl nix */

//#define MCU = attiny2313

// ### NEIN ### Mit Quarz 16 Mhz-CPU
// Interner Oszillator, 8 MHz
#define F_CPU 8000000
#define BAUD 9600
#define UBRR (unsigned int)(F_CPU / BAUD / 16 - 0.5)


// ### Portinitialisierung und waitms aus RNContr Demo C

// *### Ports setzen ###
// Ports auf HIGH/LOW setzen

static inline void setportbon(const uint8_t n)
{PORTB |= (1<<n);} //set PORTB.n high
static inline void setportboff(const uint8_t n)
{PORTB &= ~(1<<n);} //set PORTB.n low

/*### Programm pausieren lassen ###*/
/*Pausenwert ist nur experimentell !*/

void waitms(uint16_t ms)
{
for(; ms>0; ms--)
{
uint16_t __c = 4000;
__asm__ volatile (
"1: sbiw %0,1" "\n\t"
"brne 1b"
: "=w" (__c)
: "0" (__c)
);
}
}



// ------------------------------------------------------------------
// Dieser Codeschnipsel ähnlich 2313-doc, S 121

void USART_Init( unsigned int baud )

{
/* Set baud rate */
UBRRH = (unsigned char)(baud>>8);
UBRRL = (unsigned char)baud;
/* Enable receiver and transmitter */
UCSRB = (1<<RXEN)|(1<<TXEN);
/* Set frame format: 8data, 2stop bit */
UCSRC = (3<<UCSZ0);
}

// ------------------------------------------------------------------
void sendchar(unsigned char c)
{
while(!(UCSRA & (1<<UDRE))) //Warten, bis Senden möglich ist
{
}

UDR = c; //schreibt das Zeichen aus 'c' auf die Schnittstelle
}

// ------------------------------------------------------------------
void sendUSART(char *s) //*s funktiniert wie eine Art Array - auch bei
// einem String werden die Zeichen (char)
// einzeln ausgelesen - und auf die
// Sendeschnittstelle übertragen
{
while(*s)
{
sendchar(*s);
s++;
}
}

// ------------------------------------------------------------------
/*### Hauptschleife ###*/
int main(void)
{
USART_Init(UBRR); //USART initialisieren
DDRB=0xff;
// for(uint8_t i=0; i<10; i++)

for(;;){

setportboff(2);
waitms(150);
setportbon(2);






/*###Text senden###*/

sendUSART("\r\n\n\n"); //Sendet Kenung und Text.
// "\r" setze Cursor auf Zeilenanfang,
// "\n" beginnt dann die nächste Zeile
sendUSART("**** ATtiny2313 *****\r\n");
sendUSART(" \r\n");
sendUSART("Hallo, Welt.\r\n");
sendUSART(" \r\n");
}
}


Wie schon erwähnt PORTB als Ausgang definieren und den UART richtig einstellen, du hast die Baudrate in den UBRRL und H geschrieben.

Edit: Ich habe auf 1Stopbit geändert

oberallgeier
24.11.2007, 13:44
Erstmal vielen Dank. Ich "muss noch was tun" - und gehe es später ausprobieren, korrigieren :( und Fehlerdiskussion :(

Danke

oberallgeier
24.11.2007, 18:31
Hallo Hubert.G, hei robocat,

nochmals vielen Dank, Euch beiden. Ich habe den Code von Hubert.G 1:1 übernommen: Die LED blinkt :) - das Hyperterminal zeigt GARNIX an :( :( - der RS232-Monitor in DASYLab (ein kleiner Verwandter von LabView) zeigt folgenden Text:

Aufgenommen mit einem RS232-Monitor (DASYLab)

<LF>**** ÁÔôiny2313 ****ªŠ€Š¨±¼ï Welt.<CR><LF>
<CR><LF>
<CR><LF>

<LF>
<LF>**** ATôiþ<CR><LF>

<LF>
<LF>**** ATtiny2313 *****Š ŠÈallo, Welt.<CR><LF>
<CR><LF>

andere Sequenz (später) bei gleicher Hardware

<LF>
<LF>**** ÁÔ´éîy2313 ****ªŠ‚¤±´´•”§µ´¼ž…†‡‚<CR><LF>

<LF>
<LF>**** Á”´©®¹2³13 *****Š‚¤±´•”§µ´¼–…„Cá<CR><LF>

<LF>
<LF>**** Á”´©®ù2313 *****ŠŠ ±´¼¿œ€—¥ô®Š…Š<CR><LF>

<LF>
<LF>**** ATôiny2313 *****þ

Da ich als elektro(schaltungs)technisches Wickelkind die ganze Schaltung mit dem MAX232 selbst aufgebaut habe (angelehnt an hiesige Threads und RN-Control) könnte es an der Elektronik liegen. Der Oskar (leider kein DSO :( ) zeigt bei der RN-Control +/- 8V an, bei meinem Oevre -9V und zwei positive "Spuren" irgendwo in der Nähe von +3 bzw +8 V (siehe Bild).

Nach Umlöten des Elko von max232_2 nach Vcc kam dann das:

Š
**** ATôiny2313 *****

Hallo, Welt.

¹



aber nur ein Mal.

Nun sind die Schaltvorschläge zum max232 natürlich nicht eindeutig. Das Beispiel https://www.roboternetz.de/wissen/images/c/c6/Rncontrol1.4schaltplan.gif
zeigt mir beim max232_2 einen Elko der mit dem (-)-Anschluss nach Vcc geht ?? Die Bestückung an 1, 2, 3, 4, 5 und 6 sieht 4,7 müF vor. Dagegen sind bei den Thread von pmaler, bzw. bei http://www.pherzog.de/streifenrastermega32/ am max232 22 müF gesetzt, der max232_2 geht mit (+) nach Vcc. Ich hatte mich an der Streifenrasterplatine orientiert, meine Bauteile sind nach dieser Stückliste. Das Datenblatt zu dem von mir verwendeten MAX 232 CPE http://www.reichelt.de/?;ACTION=7;LA=6;OPEN=1;INDEX=0;FILENAME=A200%252FM AX232CWE.pdf;SID=25XRR1mawQARkAAD4icFI73c565f9b0b9 3135ba5caa274be49a9d sieht aber andere Kapazitäten vor :(.

Mein Signalausgang am 2313 sieht recht gut aus, sauber zwischen 0V und +5V. Dieses Spannungsplateau bei +3V nach dem max232 sollte also irgendwo zwischen 2313 und RS232-Stecker passieren :(. Der Oskar zeigt die Pegel bei der RN-Control sauber und eindeutig zwischen -8V und +8V.

Ich muss mir die Hardware mal durch den Kopf gehen lassen.

Das Dümmste ist, dass ich mir diese Schnittstelle für die Erprobung von Teilprojekten in den Kopf gesetzt hatte - später sollte ich dann I2C nehmen (dann gibts wohl neue Probleme).

robocat
24.11.2007, 19:12
hi joe,
der elko an pin 2 vom max muss mit (-) an die 5V versorgung. und der an pin 6 mit (+) auf masse. das liegt daran, dass -10V gegenüber 0V negativer sind, und die 5V negativer als +10V. im zweifelsfall ins datenblatt gucken http://www.ortodoxism.ro/datasheets/maxim/MAX220-MAX249.pdf. die elkos sind normalerweise nicht kritisch, bei mir hat bisher alles zwischen 1µF und 4,7µF klaglos dienst getan.

windows verwendet normal \r\n als zeilenumbruch, manche programme (dasylab?) wollen aber nur ein \n.

gruesse von der katz

Hubert.G
24.11.2007, 19:26
Hast du im Hyperterminal auf 1Stopbit geändert, sonst kann noch sein das die Frequenz den internen Oszillator nicht stimmt. Die ist etwas Spannungs- und Temperaturabhängig.
Bei mir läuft es auch im Hyperterminal einwandfrei.
Ob diese beiden Elkos gegen + oder - geschalten sind ist egal solange die Spannungsfestigkeit stimmt.

oberallgeier
24.11.2007, 20:56
Schönen Abend, Hubert.G


... auf 1Stopbit geändert ...Ja, 1, 1 1/2 und 2. Was man halt so tut, wenn man nix Genaues nicht weiss.


... das die Frequenz den internen Oszillator nicht stimmt ...Da bin ich grad dran. Bei meinem tiny13 hatte ich mit einer (Assembler-) Soft-RS232 mit dem internen Oszillator GELEGENTLICH mal einen Treffer :(. Aber ich hab die Sachen zusammengesucht und löte mir die notwendigen Kondensatoren rein und stecke einen Quarz dazu. Steht sowieso auf der Liste.


... Ob diese beiden Elkos gegen + oder - geschalten sind ist egal solange die Spannungsfestigkeit stimmt.Ohhh - danke.

Hubert.G
24.11.2007, 21:30
Nachtrag zu den Elkos, die Polarität gehört natürlich schon eingehalten, die ändert sich nicht.
Mit den Kapazitäten von 4µ7 bist du bei einem MAX232 gut dabei. Meist genügt 1µ oder sogar 0,1µ, da ist allerdings ein Blick ins Datenblatt angesagt und dabei genau auf die Bezeichnung achten.

oberallgeier
24.11.2007, 22:20
N´Abend, Huberg.G, hallo robocat,

Hei - was habe ich für einen artigen Controller.

Er meldet sich artig mit Namen (Typenbezeichnung) und ruft dann klar und deutlich - aber lest selbst:

**** ATtiny2313 *****

Hallo, Welt.

Was so ein bisschen trigonal symmetrisches Siliziumdioxyd an der richtigen Stelle ausmacht :). Na ja, er hat bisher noch nicht mehr geäussert - und es ist ja gut, dass er das nicht gleich mit 16 MHz macht :).

Danke Hubert.G für die Hinweise zu den Elko´s.

Danke für die ganze, super Hilfe!

Hubert.G
25.11.2007, 08:46
Da sieht man die Unterschiede, ich könnte jetzt sagen es funktioniert mit den internen Oszillator einwandfrei, tut es bei mir auch, aber man kann es nun mal nicht verallgemeinern. Bei Verwendung des UART ist ein Quarz, am besten ein Baudratenquarz die beste Lösung.
Ich hoffe du hast weiterhin so viel Erfolg.

oberallgeier
28.11.2007, 19:01
Schönen Abend,

nun habe ich vor Freude über die Funktion der RS232-Ausgabe (mit späterem Abkokeln des max232 UND des tiny2313 und Koma eines zweiten tiny mit lock1 und lock2) und anschliessendem Netzteilausfall am PC etwas übersehen.

Schaltung der LED´s und Code "an/aus" entsprechen der RN-Control. Aber die LED geht bei mir sofort an und mit "setportbon(2)" aus - und danach kommt das "Hallo, Welt."

/* >> Diese ersten 2 Zeilen können zum Assemblieren entfernt werden (muss nicht)
Sicherung vom 28nov07, 1734 nach Datei ..C1\hello-world\he-wo_x90.asm
================================================== =================================
========== Beachte: printout aus AVRStudio geht (nur) bis col 85 ==================
Target MCU : ATtiny2313
Target Hardware : Servos auf PB5 und 6, LED auf PB4
Target cpu-frequ. : 16 MHz, externer Quarzoszillator
================================================== =================================
*** Versionsgeschichte:
====================
x91 28nov07 17:34 === Läuft mit 2-sec-Takt (LED), noch ohne Terminalaufruf
#####>>>>> ABER : LED geht SOFORT an, obwohl Schaltung und Code wie in
RNControl 1.4 :((
x90 24nov07 23:ff === Läuft erst nach Einbau des Quarzes
x10 23nov07 16:ff Erster Aufbau, u.a. zum Test der Flash- und Experimentier-
Platine für tiny2313 mit RS232
*** Aufgabenstellung (erweitert für x91):
Sende wiederholt "Hallo, Welt." über die RS232 UND LED auf PB2 anzünden.
Abstand der Abläufe: 2 sec LED leuchten, Textausgabe und danach 2 sec Pause.
offen: Start dann, wenn Taste 1 gedrückt, läuft durch wenn gedrückt bleibt
später: einlesen 100 ==> Programm startet mit 1sec-Takt, evtl. Erweiterung
einlesen 200 ==> startet mit 2 sek-Takt; Einlesen über Terminal
Autor: JWT
Läuft, ABER erst mit Quarz. Hilfe von Hubert.G und robocat
Portbelegung, Schaltung auszugsweise
VAP = LED an, wenn ddrb=1 + portb=0
Vcc ---------+-----t2313-Vcc
| +------+ rLED|\ |
+-------------------+ 100R +----------| >+------+
| +------+ |/ | |
| t2313-PB2---------------------------------+
|
+-----------------------------------------------+
Taste1 \ |
t2313-PB4----------------+-------+ |------+
+------+ |
+-------------------+ 10 K +---+
| +------+
|
GND-----------+---------------------------------------GND
================================================== =================================
*/
#include <stdlib.h>
#include <avr/io.h>
#include <avr/iotn2313.h> //<<< das is ja wohl nix

//#define MCU = attiny2313

// Mit Quarz 16 Mhz-CPU
#define F_CPU 16000000
#define BAUD 9600
#define UBRR (unsigned int)(F_CPU / BAUD / 16 - 0.5)

// ### Portinitialisierung und waitms aus RNContr Demo C
// *### Ports setzen auf HIGH/LOW ###

static inline void setportbon(const uint8_t n)
{PORTB |= (1<<n);} //set PORTB.n high
static inline void setportboff(const uint8_t n)
{PORTB &= ~(1<<n);} //set PORTB.n low

/*### Programm pausieren lassen ###*/
/*Pausenwert ist nur experimentell !*/

void waitms(uint16_t ms)
{
for(; ms>0; ms--)
{
uint16_t __c = 4000;
__asm__ volatile (
"1: sbiw %0,1" "\n\t"
"brne 1b"
: "=w" (__c)
: "0" (__c)
);
}
}


// ------------------------------------------------------------------
// Dieser Codeschnipsel ähnlich 2313-doc, S 121
void USART_Init( unsigned int baud )
{
/* Set baud rate */
UBRRH = (unsigned char)(baud>>8);
UBRRL = (unsigned char)baud;
/* Enable receiver and transmitter */
UCSRB = (1<<RXEN)|(1<<TXEN);
/* Set frame format: 8data, 2stop bit */
UCSRC = (3<<UCSZ0);
}

// ------------------------------------------------------------------
void sendchar(unsigned char c)
{
while(!(UCSRA & (1<<UDRE))) //Warten, bis Senden möglich ist
{
}
UDR = c; //schreibt das Zeichen aus 'c' auf die Schnittstelle
}

// ------------------------------------------------------------------
void sendUSART(char *s) //*s funktiniert wie eine Art Array - auch bei
// einem String werden die Zeichen (char)
// einzeln ausgelesen - und auf die
// Sendeschnittstelle übertragen
{
while(*s)
{
sendchar(*s);
s++;
}
}

// ------------------------------------------------------------------
/*### Hauptschleife ###*/
int main(void)
{
USART_Init(UBRR); //USART initialisieren
DDRB=0xff;
PORTB=0;
// for(uint8_t i=0; i<10; i++)

for(;;){

setportboff(2);
waitms(2000);
setportbon(2);

/*###Text senden###*/
sendUSART("\r\n\n\n"); //Sendet Kennung und Text.
// "\r" setze Cursor auf Zeilenanfang,
// "\n" beginnt dann die nächste Zeile
sendUSART("**** ATtiny2313 *****\r\n");
sendUSART(" \r\n");
sendUSART("Hallo, Welt.\r\n");
sendUSART(" \r\n");

waitms(2000);

}
}


Und ich komm wirklich nicht darauf, was daran falsch sein sollte. Vielleicht könnte mal jemand bitte drüber gucken?
Danke.

Hubert.G
28.11.2007, 20:27
Ich weiss auch nicht was daran falsch ist.
Die Led ist gegen VCC geschalten, Ausgang µC ist 0, dann setzt du den Ausgang auf 1 und die Led geht aus. Ist doch OK so.
Oder habe ich in deiner Ausführung etwas falsch verstanden.

oberallgeier
28.11.2007, 21:37
Hallo, Hubert.G

... Oder habe ich in deiner Ausführung etwas falsch verstanden.
Nein, hast Du nicht - ICH habe, wenn überhaupt, falsch gedacht. Ich dachte eben (wie schon manchmal, leider) - wenn "Ausgang = 0" dann ist auch die LED aus :-b, aber vielleicht stolper ich über diesen Fallstrick nicht mehr allzu oft. Ok, wenn hier "Ausgang = 0" dann ist er eine Senke und es fliesst Strom von Vcc zum Ausgang - und dann ist die LED eine Leuchte - blos ich bins eben nicht (immer).

Meine Denkweise ist erst gültig, wenn ich die LED gegen GND schalte. Aber nun stell ich fest, dass sie nicht mehr so hell leuchtet :-k

Da habe ich also noch etwas dabei gelernt: Weil die "Null" am freien Ausgang bei mir nicht null Volt bedeutet - sondern etwa +2,1 - leuchtet die LED gegen Vcc heller als gegen GND :(. Und das suche ich gerade in der Dokumentation - warum der Port nicht ganz auf Null geht.

Danke jedenfalls für den geduldigen Kommentar

Hubert.G
29.11.2007, 10:06
Bei meinem 2313 ist 0 am Ausgang auch 0V. Da muss bei dir ein Wurm drinnen sein.

oberallgeier
29.11.2007, 16:58
Bei meinem 2313 ist 0 am Ausgang auch 0V. Da muss bei dir ein Wurm drinnen sein.Ach - eine schrecklich klare und wahre Analyse. Na ja, Du hattest zwar nicht WIRKLICH geschrieben: "... Da muss bei dir ein Wurm drinnen sein..." aber es könnte so gedeutet werden - und wäre auch wahr. Ich habe es heute sauber aufgebaut (na ja, das war es gestern schon auch - hab mir ja ne neue, hübsche Experimentier- und Flashplatine aufgebaut). Aber ich konnte das gestrige Ergebnis einfach nicht wiederholen. Dabei trinke ich nie beim Löten oder so. Es muss gestern irgendein seltsamer Kontakt da gewesen sein - auch das "halbe Leuchten" ist heute total weg, und die LED leuchtet gleich hell - ob gegen Vcc oder GND. Sorry für den falschen Alarm.

FAZIT: Bei "0" am Ausgang ist auch bei meinem 2313 0V.

oberallgeier
30.11.2007, 23:27
Hallo Hubert.G,


... ein Wurm drinnen ...
ein bisschen was zu meiner Entschuldigung: Es lag am Netzteil - ein prächtiges Teil für meinen Bedarf, klein und schick - das aus einem alten Industrierechner stammte. 30 W +5 V, je 1A bei +12 V und -12 V. Aber was ich nicht betrachtet hatte, war die Welligkeit - schauderhaft und eben absolut störend beim µC. Und ich hatte mich so über das Ding gefreut :( Nachträglich erinnere ich mich, dass einige Probleme auftraten [-o< seit ich diese Stromquelle gelegentlich benutzte.

oberallgeier
06.12.2007, 23:30
Hei Hubert.G,

vielleicht stolperst Du noch mal hier drüber. Ich hätte schon wieder (99, will aber klein anfangen) Fragen. Ich sehe nicht richtig durch die Befehle. Ok, ist sowieso klar ;-). Aber im Ernst:

Im Tutorial C in RNWissen (und im K&R - :) hat die Nikolaus-in gebracht) steht nur das printf als Ausgabe und das scanf... Frage: die Eingaberoutinen - so nach dem Muster "readUSART" oder "getUSART" muss ich mir dann selber schreiben!? Oder gibts dazu wieder so praktische "Spickzettel" - sprich libraries? Die sendUSART habe ich ja aus der rncontrol.h geklaut.

Ich will nämlich jetzt Werte EINLESEN - als Zahl, nicht als Text/Ziffer (sollen als PWM-Sollwert dienen), und da fehlt mir einfach das Vokabular :(. Ich komme mir reichlich blind vor im Moment, sorry.

Danke im Voraus,

Nachtrag: Sorry, es steht ja im *2313_doc2543 - das hatte ich irgendwie übersehen :(

Hubert.G
07.12.2007, 09:44
Ich verwende gerne die UART-Lib von P.Fleury http://jump.to/fleury

robocat
07.12.2007, 10:09
hallo oberallgeier,
stell ruhig hier weiterhin deine fragen. der nächste, der c lernen will und diesen thread findet (leider ist die forums-suchmaschine nicht gerade toll im auffinden älterer threads) wird sich evtl. freuen :)

im K&R wird ja (soweit ich weiss, hatte das buch nur vor ewigkeiten mal aus der bibliothek hier) von ansi-c ausgegangen, mit stdio.h, also einer standardein- und ausgabe. microcontroller haben so etwas nicht, deshalb wirst du dir solche (und viele andere funktionen) woanders suchen oder selbstschreiben müssen.

um die beispiele im buch schöner durcharbeiten zu können, würde ich einen compiler installieren, der executables für windows (oder linux, wenn du das verwendest) erzeugen kann. von dev-c(++) http://de.wikipedia.org/wiki/Dev-C++ habe ich viel gutes gehört, ich selbst verwende bcc32 (mit einer selbstgestrickten entwicklungsumgebung) und es gibt noch eine ganze reihe weiterer compiler/IDE´s.

microcontroller darfst du schon weiterhin programmieren ;) aber den K&R sollte man wohl doch besser mit einem pc angehen.

also viel erfolg, und immer raus mit den fragen :)

gruesse

oberallgeier
07.12.2007, 10:36
Vielen Dank Hubert.G und robocat,

für die prompten Antworten. Danke Hubert.G - die lib´s von P.Fleury habe ich seit Tagen am PC - und wollte sie sowieso heute durchgehen. Ich glaube aber, ich lerne bei meinem derzeitigen Wissensstand (so etwa Elementar-Stufe) mehr, wenn ich auch mal was selber schreibe oder im *doc abschreibe. Daher popel ich lieber selbst mal so chaotisch rum. Aber danke für den Hinweis.

@robocat - Nach zwei Abstürzen meines (bisher relativ stabilen) Computers in den letzten beiden Wochen habe ich erstmal etwas Bange Programme zu schreiben, mit denen ich bei ausreichender Unachtsamkeit ins Betriebssystem komme - ich kenne meine Experimentierfreude. Da programmiere ich lieber erstmal einfache Dinge für meine Tinys und den mega16/32 - dabei hatte ich bisher nur zwei Billigservos, einen tiny2313 und einen max232 verheizt - und gute Erfahrung gewonnen. Bei den Servos, um die ICs war es blos schade :(.

Dann danke - und bis zu den nächsten 98 Fragen

robocat
07.12.2007, 11:27
also am pc mit software etwas kaputtzubekommen ist nicht so einfach. die erstsemester-studenten werden im rechenzentrum normalerweise auch auf PCs losgelassen, ohne dass die alle in rauch aufgehen.
man kann mit einigem aufwand die festplatte unbrauchbar machen, das geschieht aber nicht "mal eben so" sondern man muss schon ungefähr wissen, was man tut. ansonsten kriegt man unter windows irgendwelche hardware höchstens auf driver-level kaputt, und auch das geschieht nicht versehentlich, sondern höchstens wenn man mit dem DDK treiber entwickelt.
ich programmiere ja schon länger, und habe schon einiges an abstürzen (im sinne eines plötzlichen reboots, ohne defekte), BSODs und exceptions erlebt - aber kaputtbekommen habe ich noch nichts, und wenn mein fehlerhafter code nicht mehr ausgeführt wurde, war auch das problem gegessen.
ich vermute also stark, dass deine programme nichts mit den defekten zu tun haben.

seh es einfach so: wenn windows hardware zerstören könnte, dann hätte es das längst getan! ;)

gruesse

oberallgeier
07.12.2007, 12:06
... die erstsemester-studenten werden im rechenzentrum normalerweise auch auf PCs losgelassen, ohne dass die alle in rauch aufgehen.... :) :) da fällt mir spontan eines meiner studentischen Erlebnisse ein: zweimal das Betriebssystem ner Cray rausgeworfen (die war damals Oberstufe in DE), weil die Matritze so gross war und das Ganze nicht sooo pfiffig programmierte war. Beim ersten Mal gabs nen allgemeinen Aufruf vom RZ, beim zweiten Mal hatten sie gemerkt wer das war und uns verwarnt - daher gabs dann kein drittes Mal.

Aber Du hast schon recht - ich glaub auch nicht, dass meine AVRStudio-Gänge der Grund für die Defekte war - nur eben das Kräuseln der Nackenhaare ist da . . .

oberallgeier
15.12.2007, 17:26
Also R&K ist EINE Sache. Und ich gehe den auch immer wieder mal ein Stück durch. Aber AVRGCC ist eben eine andere. Und für die ist meiner Meinung nach die Einarbeitung deutlich schwerer - es ist zwar im Prinzip alles da, aber ICH brauch das bestimmt ein klitzekleines Stück anders - und schon läuft wieder nix :(.

Ich bin ja schon mit der RS232-Ausgabe aufgelaufen, weil der AVR kein printf kennt. Mir ist mittlerweile auch klar warum - weil das printf eben die Ausgabe an eine Betriebssystem-Standardkonsole ist oder so - und Hubert.G nochmal danke. Damit läuft ein Motortest - und ich kann mittlerweile recht genau feststellen, bei welchem Ausgabewert an die PWM ("setPWM..") ein Motor anläuft und wo er bei steigendem Ansteuerungswert nicht mehr weiter hochdreht . . .

Da ich vorerst ausschließlich meine µC´s in C programmieren will, hilft aber der R&K mitunter eingeschränkt oder garnicht (ich hänge derzeit seit Tagen an I2C - die Libs bin ich immer wieder durchgegangen, aber ich krieg sie nicht angewendet... :( ). Und ISR in C sieht dem Assemblercode ähnlich - auch das kann ich nicht mit einem "üblichen" Compiler trainieren. Also muss ich schon beim AVRGCC/WINAvr bleiben, wenn ich mit den AVR-Controllern arbeiten möchte.

Was eigentlich fehlt (für mich als Anfänger) sind solche kurzen Stücke wie im C-Tutorial
https://www.roboternetz.de/wissen/index.php/C-Tutorial

das mit "Aufbau eines C-Programmes" ein kurzes Codestück mit einem SEHR ausführlichen Kommentar hat. Das bisschen hatte mir einen sehr guten Einblick gegeben. Ich meine, wenn man solche Anwendungshinweise zu einzelnen Themen schreiben könnte (ok, es ist grad Weihnachten, da neigt man zu Wünschen oder Wunschlisten), dann könnte es manchem Anfänger helfen. So brüte ich schon den ganzen Nachmittag mit meiner Counter-Routine (100 - 1000 Hz - Impulse von zwei Portpins vom 2313 oder mega16/32 in C erfassen :( ), die ich in Assembler in der Zeit wohl schon hingekriegt hätte.

Aber ich werd noch am Wochenende selber dran popeln und dann einen problemspezifischen Hilferuf ausstossen.

oberallgeier
17.01.2008, 13:21
Neuerliche Bitte um Hilfe bei C, diesmal geht es um Optimierung des Datenbereiches. Ich glaube, das passt hier unter diesen Titel; ein neuer Thread scheint mir nicht nötig.

Aufgabe: RAM im mega168 optimieren bei AVR-Studio/WINAvr.
Grund: die derzeitige Memoryaufteilung:
AVR Memory Usage
----------------
Device: atmega168

Program: 4324 bytes (26.4% Full)
(.text + .data + .bootloader)

Data: 782 bytes (76.4% Full)
(.data + .bss + .noinit)
benötigt 76 % des Datenbereichs. Da ich noch einige Variablen für die Programmerweiterung einbringen muss, ist eine Optimierung erforderlich.

Was habe ich bisher getan?
Mir schien der File *.map

Archive member included because of file (symbol)

c:/programme/winavr-20070525/bin/../lib/gcc/avr/4.1.2/avr5\libgcc.a(_exit.o)

Rest gestrichen - wegen zu großer Länge des postings und weil es nicht mehr relevant ist, siehe Nachtrag

.debug_macinfo
*(.debug_macinfo)
OUTPUT(2drehzmess-168.elf elf32-avr)
LOAD linker stubs

am vielversprechendsten. Leider verstehe nicht nicht alles (das ist leicht übertrieben - sollte heissen: verstehe fast nix).

Ich erkenne

Memory Configuration

Name Origin Length Attributes
text 0x00000000 0x00020000 xr
data 0x00800060 0x0000ffa0 rw !x
eeprom 0x00810000 0x00010000 rw !x
*default* 0x00000000 0xffffffff

diesen Memory-Abschnitt. Offenbar geht der Datenbereich ab 0x00800060 los. Geht der bis 0x00810000?? Vermutlich ist die 0x0081 ein compilerinterner offset. Trotzdem - das wären ja 64 KByte data :o [-X das stimmt doch nicht - das Datenblatt sagt, dass das SRAM von 0x0100 bis 0x04FF geht - und das sind die 1024 Bytes :) die ich im Kopf habe (nein, das ist nicht die Anzahl meiner Synapsen, sondern die Anzahl der SRAM-Bytes des m168).

Ok, dann gibt es den Bereich "COMMON". In diesem Abschnitt der map stehen dann auch die Variablennamen drinnen, von denen ich denke, dass sie optimierbar sind. Statt int16 eben int8 - wenn das geht. Aber ich brauche auch Werte +/- 64000 (wenn ich beim Überlauf den int16 auf Null setze und den neuen Wert vom alten abziehe - bekomme ich etwas zwischen minus64000 und minus63000, so in der Art) für meine Zeitrechnung. Und dann komme ich leider auf die speicherfressenden signed long :(

Die Wertebereiche entnehme ich dem C-Tutorial (https://www.roboternetz.de/wissen/index.php/C-Tutorial#int.2C_char.2C_short.2C_long_.28ganze_Zah len.29). Daraus entnehme ich, dass uint16_t eben ein unsigned short ist und int16 ein signed short - entsprechend den Angaben im AVR-GCC-Tutorial (http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Ganzzahlige_.28Integer.29_Datentypen).

BEVOR ich die Schere (und mein analytisches Gehirn) hier ansetze, wollte ich wissen, woran ich wirklich bin. Daher diese ausführliche Beschreibung.

Meine Fragen:
1) Kann ich Daten NUR im SRAM ablegen (doch wohl nicht)?
2) Kann ich es steuern, ob Daten im SRAM abgelegt werden?
3) Kann ich Daten ins Flash bringen?
4) Wie kann ich Daten (Zahlenwerte) in den Flashbereich bringen? Sind die dort langsamer zugreifbar? Mir ist klar, dass im Datenblatt steht: "– Write/Erase cyles: 10,000 Flash/100,000 EEPROM".
5) Vermutlich ist es unsinnig, Daten für ISR ins EEPROM zu schreiben, weil das Schreiben und wieder holen zeitaufwendig ist ! ? ! ?

Danke im Voraus,

Nachtrag : Mi.. - ich war schon wieder viel zu voreilig. Hab mal die ganzen

sendUSART("Motor dreht links, Drehzahl läuft hoch.\r\n");
sendUSART("PWM-Stellwerte\r\n");
sendUSART("_n__li__re\r\n");
und

utoa(Izeit_1, wortiz1, 10);
sendUSART(wortiz1);sendUSART(" ");
utoa(Iz_diff1, wortzd1, 10);
sendUSART(wortzd1);sendUSART(" ");
sendUSART(worti);sendUSART(" "); //PWM-Stellwerte
sendUSART(wortkli);sendUSART(" ");
sendUSART(wortkre);sendUSART("\r\n");
auskommentiert. Und ein erfrischendes Ergebnis nach dem Compilieren bekommen:

AVR Memory Usage
Device: atmega168
Program: 2522 bytes (15.4% Full) (.text + .data + .bootloader)
Data: 36 bytes (3.5% Full) (.data + .bss + .noinit)

Sorry, das hätte ich wirklich vor dem Fragen machen können.