Forum: Compiler & IDEs Hilfe Grundlagen Atmel in C


von Constantin (Gast)


Lesenswert?

Hallo AVR Freunde!

Ich habe ein großes Problem, leider habe ich nur auf der Arbeit einen 
Internetzugang so dass ich dass Forum nur auf der Arbeit nutzen kann, 
dass heißt auch das ich dort nicht programmieren kann.Des halb meine 
Frage ob jemand von euch hier in Berlin wohnt der mich vielleicht beim 
programmieren unterstützen kann. Unter der Woche habe ich frei, leider 
aber nicht am Wochenende.
Zum programmieren nutze ich das Funkboard von Pollin und das WinAVR 
Studio 4.0 über eine serielle Schnittstelle (win98).
Ich weiß auch das es hier die Grundlagen der Programmierung git aber 
leider komme ich nicht ganz klar damit.
Vielen Dank für Eure Hilfe und Unterstützung!
Constantin

von daniel (Gast)


Lesenswert?

vielleicht an der uni berlin an der pinwand eine anzeige anheften ;)

von Constantin (Gast)


Lesenswert?

Hallo Daniel!

Danke für den Tip! Wie sieht es aus, vielleicht kannst Du mir ja auch 
helfen beim Programmieren. Oder mir vielleicht auch ein tolles Skript 
von irgendeigen Prof. empfehlen.
Vielen Dank!

Constantin

von gast (Gast)


Lesenswert?


von daniel (Gast)


Lesenswert?

Hallo Constantin,

ich bin viel südlicher zu Hause^^
und im Moment am Theoriepaucken.

Mit AVR(vor allem der Peripherie) habe ich wenig Erfahrung
mit reinem C dagegen schon einige.
Dass es Uni-Skripte zu AVR gibt bezweifele ich, Bücher dazu an
der Unibib habe ich allerdings schon einige gesehen.

Als ich mich in AVR einlesen wollte, habe ich einfach die
umfangreichen Datenblätter gedruckt und nach und nach
gelesen.

Möchtest du einfach in AVR uC einsteigen (und lernen) oder hast
du schon ein bestimmtes Projekt im Auge?

Wünsche Dir viel Erfolg!

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Constantin wrote:

> Zum programmieren nutze ich das Funkboard von Pollin und das WinAVR
> Studio 4.0 über eine serielle Schnittstelle (win98).

Schon gesehen?
http://www.mikrocontroller.net/articles/Pollin_Funk-AVR-Evaluationsboard

von Constantin (Gast)


Lesenswert?

Hallo daniel, Stefan ....

Vielen Dank für die Hilfe. Da ich ja zuhause keinen Netzzugang habe 
melde ich mich jetzt erst wieder von der Arbeit.

Ich habe mit der LCD-ansteuerung folgendes Problem für die Datenbits 
benutze ich den PORTA und für RS und E die PORTadressen PD4 und PD5.
Kann ich das so schreiben als #define in die lcd.h Datei?
Zum Programmieren benutze ich das AVR-Studio 4.0 ein Notebook mit win98, 
so wie das Pollin Board mit einem Mega16 Taktung 16MHz.
Mit Basecom bekomme ich etwas aufs Display leider aber nicht in C.
Ich muß in C Programmieren, leider sonst wär einiges einfacher.
Vielen Dank
Constantin

von Mandula (Gast)


Lesenswert?

Warum MUSST du in C Programmieren?

Nimm doch die Programmiersprache die dir liegt ?!

von Constantin (Gast)


Lesenswert?

Hallo Mandula!

Ja, leider muß ich den Mega16 in C-Programmieren.

Vielen Dank!
Constantin

von Matthias L. (Gast)


Lesenswert?

>Ja, leider muß ich den Mega16 in C-Programmieren.

Das ist zweimal falsch:

Du darfst einen Atmel programmieren.
Du darfst in C programmieren.

;-)

von Hubert G. (hubertg)


Lesenswert?

Wie wäre es wenn du dir die Lib von Fleury ansiehst, ist in C und du 
musst sie ja nicht zur gänze kopieren.

von Constantin (Gast)


Lesenswert?

Danke Hubert!

Für mich stellt sich die Frage ob ich PORTA als Datenport verwenden kann
und Enable und RS an einen anderen PORT anschließen kann.
Wie würde die lib dann aus sehen?

void lcd_data(unsigned char temp1);
void lcd_string(char *data);
void lcd_command(unsigned char temp1);
void lcd_enable(void);
void lcd_init(void);
void lcd_home(void);
void lcd_clear(void);
void set_cursor(uint8_t x, uint8_t y);

// Hier die verwendete Taktfrequenz in Hz eintragen, wichtig!

#define F_CPU 16000000// Angepasst 16MHZ

// LCD Befehle

#define CLEAR_DISPLAY 0x01
#define CURSOR_HOME   0x02

// Pinbelegung für das LCD, an verwendete Pins anpassen

#define LCD_PORT      PORTA//an meine Werte angepasst
#define LCD_DDR       DDRA
#define LCD_RS        PD4
#define LCD_EN        PD5
// DB4 bis DB7 des LCD sind mit PD0 bis PD3 des AVR verbunden
Leider funtioniert die Anzeige bei mir so nicht? Wenn ich in Main siehe 
Tutorial eine Wartefunktion verwende Blinken nur die schwarzen Balken 
auf also kein Test und auch kein Hello world sind zu sehen. Wie schon 
geschrieben funktionier die Anzeige mit Basecom tadellos nur in C 
bekomme ich das irgendwie nicht hin.
Es kann auch an den Zeiten liegen die ich in der Routine anpssen muß an 
meine 16MHz.

Vielen Dank!

Constantin

von ... .. (docean) Benutzerseite


Lesenswert?

es muss immer alles an einen Port bei den libs die so rumfliegen...

von risu (Gast)


Lesenswert?

Hallo,

>es muss immer alles an einen Port bei den libs die so rumfliegen...

Zitat aus der "lcd.h" von P. Fleury:

*  The four LCD data lines and the three control lines RS, RW, E can be
*  on the same port or on different ports.
*  Change LCD_RS_PORT, LCD_RW_PORT, LCD_E_PORT if you want the control
*  lines on different ports.
*  Normally the four data lines should be mapped to bit 0..3 on one 
port,
*  but it is possible to connect these data lines in different order or
*  even on different ports by adapting the LCD_DATAx_PORT and
*  LCD_DATAx_PIN definitions.

Gruß
 risu

von Constantin (Gast)


Lesenswert?

Danke erstmal!

kann ich dann das so programmieren?
#define LCD_PORT      PORTA//an meine Werte angepasst
#define LCD_DDR       DDRA
#define LCD_RS        PD4
#define LCD_EN        PD5
danke!

Ja besser wäre es wenn alles einem PORT liegt!
Ich habe es aber beim Aufbau für besser gefunden auf ein anderes PORT 
auszuweichen.

Constantin

von T. H. (pumpkin) Benutzerseite


Lesenswert?

Constantin wrote:
> // Hier die verwendete Taktfrequenz in Hz eintragen, wichtig!
>
> #define F_CPU 16000000// Angepasst 16MHZ

Besser:
1
#define F_CPU (16000000UL)

von risu (Gast)


Lesenswert?

Hallo,

> kann ich dann das so programmieren?
> #define LCD_PORT      PORTA//an meine Werte angepasst
> #define LCD_DDR       DDRA
> #define LCD_RS        PD4
> #define LCD_EN        PD5

"PORTD" musst Du dann schon noch angeben, z.B. so:
1
#define CNT_PORT     PORTD    
2
#define LCD_RS_PORT  CNT_PORT  
3
#define LCD_RS_PIN   4            
4
//#define LCD_RW_PORT  CNT_PORT  // not in use (?) 
5
//#define LCD_RW_PIN  5          // not in use (?)
6
#define LCD_E_PORT   CNT_PORT     
7
#define LCD_E_PIN    5
Gruß
 risu

von Constantin (Gast)


Lesenswert?

Dank nochmals!

Werde ich wenn, ich zu Hause bin gleich ausprobieren.
Ich hoffe das die Anzeige dann endlich läuft.
Bis dann und ein schönes Wochenende

Constantin

von Peter D. (peda)


Lesenswert?

Constantin wrote:
> Danke erstmal!
>
> kann ich dann das so programmieren?
> #define LCD_PORT      PORTA//an meine Werte angepasst
> #define LCD_DDR       DDRA
> #define LCD_RS        PD4
> #define LCD_EN        PD5
> danke!
>
> Ja besser wäre es wenn alles einem PORT liegt!

Nö, das ist unerheblich.

Hier mal ein Beispiel, wie man beim AVR-GCC ganz elegant einzelne Bits 
definiert und verwendet (siehe Anhang):

Beitrag "Re: LCD nicht nur für einen Port in C"

Man muß nicht immmer mit großen Geschützen auf kleine Aufgaben schießen.


Peter

von Constantin (Gast)


Lesenswert?

Hallo nochmals Danke!

Das Display LCD 202A von Reichelt zeigt zwar jetzt was an,abr nicht das 
was es soll.


/* Das LCD ist folgendermaßen angeschlossen:
 * PA4     = RS
 * PA5     = Enable
 * PA0-PA3 = A4-A7
 * R/W ist n.c.
 *
 *
 */

#include <avr/io.h>
#include <util/delay.h>
#include "lcd_tools.h"


#define delay(us)  _delay_loop_2 (((F_CPU/4000)*us)/1000)    // wartet 
µs

/*
    wartet Millisekunden
    Zeit in Millisekunden

*/
void delay_ms(uint16_t ms)
{
  for(uint16_t t=0; t<=ms; t++)
  _delay_ms(10); //1
}

/**
    Enable Leitung togglen

*/
void lcd_flash_e ()
{
  PORTA = PORTA | ( 1<<DDA5 ) ;    // Enable = HIGH
  delay(200);//100          // kurz warten, damit Flanke entsteht
  PORTA = PORTA & ~( 1<<DDA5 ) ;    // Enable = LOW
  delay(200); //100          // Warten, bis der durch Enable angelegte 
Befehl hoffentlich verarbeitet wurde
}

/**
  Kommando oder Zeichen an Display senden:
  rs=0 => Kommando, rs=1 => Zeichen
*/
void lcd_write (uint16_t data, uint16_t rs)
{
  uint16_t dataBits ;

    if (rs)            // write data (RS=1, RW=0)
       dataBits=0x10;    // RS liegt an Pin 4 = B 0001 0000 = H 10
    else             // write instruction (RS=0, RW=0)
       dataBits=0;

    PORTA = dataBits | (data>>4);    // output high nibble first, zzgl. 
Zustand für RS-Leitung
  lcd_flash_e ();

  PORTA = dataBits | (data&0x0F);    // output low nibble, zzgl. 
RS-Leitung
  lcd_flash_e ();
}

/**
  Display loeschen
*/
void lcd_cls ()
{
  lcd_write(0x00,0);     // B 0000 0000 => Clear
  delay(4000);      // dauert eine Weile
  lcd_write(0x01,0);     // B 0000 0001 => Cursor Home
  delay(4000);      // dauert eine Weile, Wert ausprobiert
}

/**
  Zeichenausgabe
*/
void lcd_writechar ( char zeichen)
{
  lcd_write (zeichen, 1);
}

/**
  gibt eine Zeichenkette auf dem LCD aus
*/
void lcd_writetext ( char *text)
{
  uint16_t i = 0;
  _delay_ms(10);//neu 18:50
  while (text[i]!=0)
  {
    lcd_writechar(text[i]);
    i++;
  }
}

/**
    Zeilenwechsel
*/
void lcd_gotoline (uint16_t zeile)
{

    if (zeile == 1) lcd_write(0x80,0);       // B 1000 0000 => DD-RAM 
Adress Set 1. Zeile/1.Spalte
    if (zeile == 2) lcd_write(0x80+0x40,0);     // B 1010 0000 => DD-RAM 
Adress Set 2. Zeile/1.Spalte
    if (zeile == 3) lcd_write(0x80+0x13,0);     // B 1010 0000 => DD-RAM 
Adress Set 3. Zeile/1.Spalte
    if (zeile == 4) lcd_write(0x80+0x53,0);     // B 1010 0000 => DD-RAM 
Adress Set 4. Zeile/1.Spalte
}




/**
    Cursorpositionieren
     Zeile, Spalte
*/
void lcd_gotopos (uint16_t zeile, uint16_t spalte)
{


    if (zeile == 1) lcd_write(0x80+0x00+spalte-1,0);   // DD-RAM Adress 
1. Zeile + Spalte
    if (zeile == 2) lcd_write(0x80+0x40+spalte-1,0);   // DD-RAM Adress 
2. Zeile + Spalte
    if (zeile == 3) lcd_write(0x80+0x14+spalte-1,0);   // DD-RAM Adress 
3. Zeile + Spalte
    if (zeile == 4) lcd_write(0x80+0x54+spalte-1,0);   // DD-RAM Adress 
4. Zeile + Spalte

}

/**
  gibt eine int-Zahl auf dem Display aus.
  space=0 => führende Nullen, 1 => führende Leerzeichen
*/
void lcd_writezahl (int32_t zahl, uint16_t pos, uint16_t spacer)
{
   int32_t output;
   char sign = '0';

  pos--;       // Korrektur des Parameters

  if (spacer) sign=' ';

  // negatives Vorzeichen oder Leerzeichen
  if (zahl < 0)
  {
  lcd_writechar ('-');
  zahl *= -1;    // positive Zahl
  }

  output = zahl;

  // Hunderttausender-Dezimalstelle oder Leerzeichen (Ausblenden 
fuehrender Nullen)
  if (zahl >= 100000) lcd_writechar (0x30 + output/100000); else if (pos 
>= 5) lcd_writechar (sign);
  output = output % 100000;

  // Zehntausender-Dezimalstelle oder Leerzeichen (Ausblenden fuehrender 
Nullen)
  if (zahl >= 10000) lcd_writechar (0x30 + output/10000); else if (pos 
>= 4) lcd_writechar (sign);
  output = output % 10000;

  // Tausender-Dezimalstelle oder Leerzeichen
  if (zahl >= 1000) lcd_writechar (0x30 + output/1000); else if (pos >= 
3) lcd_writechar (sign);
  output = output % 1000;

  // Hunderter-Dezimalstelle oder Leerzeichen
  if (zahl >= 100) lcd_writechar (0x30 + output/100); else if (pos >= 2) 
lcd_writechar (sign);
  output = output % 100;

  // Zehner-Dezimalstelle oder Leerzeichen
  if (zahl >= 10) lcd_writechar (0x30 + output/10); else if (pos >= 1) 
lcd_writechar (sign);

  // einer Dezimalstelle oder Leerzeichen
  lcd_writechar (0x30 + output % 10);
}

/**
  Zuerst den 8-Bit-Modus aktivieren, Ist wichtig, falls LCD schon im 
4-Bit Modus war und dann
    nach einem Programm-Reset vergeblich versucht würde, den 4-Bit Modus 
erneut zu aktivieren.
  Dann in 4-Bit Modus umschalten.
*/
void lcd_set4bit ()
{
    PORTA = 0x03;      // 8-Bit Modus aktivieren (B 0011 0000 = H 30, 
High Nibble => B 0011 = H 03
  lcd_flash_e ();        // Datenübernahme
  delay_ms(5);      // sicherheitshalber warten da wir BUSY nicht 
überprüfen können

  // Das ganze 3x wiederholen:
  PORTA = 0x03;
  lcd_flash_e ();
  delay(200);

  PORTA = 0x03;
  lcd_flash_e ();
  delay(200);

  lcd_write(0x02,0);    // B 0000 0010 => in 4-Bit-Modus umschalten
  delay(200);
}

/**
  Portrichtung einstellen. Extern, damit man dies separat aufrufen kann, 
wenn bspw. LCD schon initialisiert ist und
    per Watchdog ein Reset ausgelöst wurde, man dann aber nicht das 
Display neu initialisieren möchte, damit es schneller weiter geht
*/
void lcd_port_ini ()
{
  DDRA = 0x3F;    // setze Portrichtung (1 = Ausgang): 0011 1111
}

/**
  Display initialisieren. Einmal als erstes aufrufen
*/
void lcd_ini ()
{
  lcd_port_ini();
  DDRA = 0x3F;      // setze Portrichtung (1 = Ausgang): 0011 1111

  delay_ms(40);      // 40ms warten bis LCD wirklich bereit keine BUSY 
Auswertung

  lcd_set4bit();      // ab jetzt 4-Bit-Modus


  lcd_write(0x28,0);    // B 0010 1000 => Function Set: 4Bit (kein 8-Bit 
Bus), zweizeiliges Display, 5x7 Dots/Zeichen RE-Bit aus
  lcd_write(0x0F,0);    // B 0000 1000 => Display On/Off: Display ein, 
Cursor an, Blinken an
//  lcd_write(0x0C,0);    // B 0000 1000 => Display On/Off: Display ein, 
Cursor aus, Blinken aus
  lcd_write(0x06,0);    // B 0000 0110 => Entry Mode Set: DD-RAM autom. 
inkr., Cursor bewegen

  lcd_cls();        // Display löschen
}

Vielen Dank!

von R.Freitag (Gast)


Lesenswert?

Was zeigt das Display denn an?
Gruss
Robert

von Falk B. (falk)


Lesenswert?

@  Constantin (Gast)

Kleiner Tip:Netiquette

Lange Quelltexte gehören in den Anhang!

von Constantin (Gast)


Lesenswert?

Hallo Robert/ Falk!

Danke erstmal für eure Beiträge zu meiner Mail!
Das Display funktioniert jetzt! Ich hatte nur einen Hardware Fehler 
gehabt.
Der Quelltext war sonst soweit ok.
Tut mir leid das ich mich jetzt erst melde aber ich habe jetzt erst 
wieder die Möglichkeit mich zu melden.
Dank!

Bis dann

Constantin

Zusammenfassung LCD-Display 202A
1. wenn im 4Bit Modus dann die Anschlüsse D7 bis D4 vom LCD Display 
nehmen!
2. Erst den 8 Bit-Modus initialisieren dann meistens den 4-Bitmodus
  2x bis 3x aufrufen
3. Hardware überprüfen!!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.