mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik LCD_Ansteuerungsproblem_im_Multitasking_Betrieb


Autor: caler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!
Ich benutze einen atmega32 und 1 displaytech 162 LCD-Modul.
Möchte dieses dann direkt über PORTC des avrs ansteuern.
Gleichzeitig sind an PORTC 4 Tasten angehängt. Dies bedeutet 
automatisch, dass diese PINS auf high sind.
Habe folgendes Problem:
Mein Programm sollte durch Betätigen einmalig ein "H" ausgeben.
Wenn ich "H" auf dem Display ausgeben möchte, gibt er eine 0 
(irgendwo)aus.
 siehe Code:
#include<avr/signal.h>
/// Includes //////////
#include <avr/io.h>
#include "os.h"
#include <stdbool.h>
#include <avr/interrupt.h>
#define LCD_PORT_w    PORTC
#define LCD_PORT_DDR  DDRC
#define DISPLAY_RS  (1<<3)
#define DISPLAY_EN  (1<<2)

//LCD
void    _long_delay(void);
void    _lcd_write_command(unsigned char);
void    LCD_Write(unsigned char *);
void    LCD_Init(void);
char    LCD_Putchar(char);
#define LCD_Clear  {_lcd_write_command(0x01); _long_delay();_long_delay();}
void    LCD_Gotoxy(unsigned char  , unsigned char );
void    LCD_Gotoxy2(unsigned char  , unsigned char );
void    LCD_DezAusgabe(unsigned long wert , char stellen , unsigned char punkt);
void LCD_Puts(const char *s);
 bool akku;
 float realakku;
 int intakku;

//Uservariablen
 
/// Data 
bool lcd;
///Data Types /////////
typedef unsigned char u8;
typedef unsigned int u16;
typedef struct task
{
   // pointer to a function
   void (*pfunc) (void);
   // delay before the first call
   u16 delay;
   // interval between subsequent runs
   u16 period;
   // flag indicating time to run
   u8 run;
}task;

/// Defines ///////////
// 25msec period 256-180 
// 7.3728MHz and /1024 prescaler
#define StartFrom       76
// maximum number of tasks
#define MAXnTASKS       20

/// Globals ///////////
volatile task TaskArray[MAXnTASKS];

/// Prototypes ////////
void InitUART (u16 baud);
void TransmitByte (u8 data);
void InitScheduler (void);
void UpdateScheduler(void);
void DeleteTask (u8 index);
void AddTask (void (*taskfunc)(void), u16 taskdelay, u16 taskperiod);
void DispatchTask (void);

void SPSTASK (void);
void LCDTASK (void);
void SERKOMTASK (void);

/// Main //////////////
int main(void)
{
   InitUART (23);
   InitScheduler();
   DDRB=0xFF;     
   // populate task array       
   AddTask (t0, 0, 3);
   AddTask (t1, 1, 4);
   AddTask (t2, 4, 0);
      LCD_Init();
  LCD_Clear;
  LCD_Gotoxy(0,0);
  
   // enable interrupts
   sei();
        
   while (1) 
   {
      DispatchTask();
   }            
}

void InitUART (u16 baud)
{
unsigned char x;
   UBRRH = (u8)(baud>>8);                                                        
   UBRRL = (u8)baud;
   UCSRB = (1<<RXEN)|(1<<TXEN);              
   UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
   UART.Betriebsart=true;
 // UCSRB|=(1<<RXCIE);
x=UDR;
}

void TransmitByte (u8 data)
{
   while ( !( UCSRA & (1<<UDRE)) );
   UDR = data;
}

void InitScheduler (void)
{
   u8 i;
   
   // timer prescaler clock/1024
   TCCR0 |= (1<<CS01)|(1<<CS00);
   // clear pending interrupts
   TIFR = 1<<TOV0;
   // enable timer0 overflow interrupt
   TIMSK |= 1<<TOIE0;
    // load timer0
   TCNT0 = StartFrom;

   // clear task array
   for (i=0; i<MAXnTASKS; i++) DeleteTask(i);
}

void DeleteTask (u8 j)
{
   TaskArray[j].pfunc = 0x0000;
   TaskArray[j].delay = 0;
   TaskArray[j].period = 0;
   TaskArray[j].run = 0;
}

void AddTask (void (*taskfunc)(void), u16 taskdelay, u16 taskperiod)
{
   u8 n=0;

   // find next available position
   while ((TaskArray[n].pfunc != 0) && (n < MAXnTASKS)) n++;

   // place task
   if (n < MAXnTASKS)
   {
      TaskArray[n].pfunc = taskfunc;
      TaskArray[n].delay = taskdelay;
      TaskArray[n].period = taskperiod;
      TaskArray[n].run = 0;   
   }
}

SIGNAL(SIG_OVERFLOW0)
{
   u8 m;

   // testing
  // TransmitByte(45); // (-)
   
   // load timer
   TCNT0 = StartFrom;
   
   for (m=0; m<MAXnTASKS; m++)
   {
      if (TaskArray[m].pfunc)
      {   
         if (TaskArray[m].delay == 0) 
         {
            TaskArray[m].run = 1;
            TaskArray[m].delay = TaskArray[m].period;
         }
         else TaskArray[m].delay--;
      }
   }
}

void DispatchTask (void)
{
   u8 k;
   
   for (k=0; k<MAXnTASKS; k++)
   {
      if (TaskArray[k].run == 1)
      {
         // run task
         (*TaskArray[k].pfunc)();
         // clear run flag
         TaskArray[k].run = 0;
      }
   }

}

void t0(void)

{ //nicht wichtig für diese Betrachtungen

              }
void t1(void)

{
//nicht wichtig für diese Betrachtungen
  

              }


void t2(void){
DDRC=0x00; //PORTC EINGANG-UmTasten herauszulesen
if(!(PINC&0x80)&&!lcd){LCD_Init();
LCD_Gotoxy(0,0);
LCD_Write("H");
lcd=true;
}
}


void _long_delay(void)
{
int t = 50000;
while (t--);
}

void _short_delay(void)
{
int t = 20000;
while (t--);
}


void _lcd_write_command(unsigned char data)
{
  DDRC |= (0x80+0x40+0x20+0x10+0x08);
  LCD_PORT_w = (data & 0xf0) | DISPLAY_EN;
  LCD_PORT_w = (data & 0xf0) | DISPLAY_EN;
  LCD_PORT_w = (data & 0xf0) | DISPLAY_EN;
  LCD_PORT_w = (data & 0xf0);
  LCD_PORT_w = (data & 0xf0);
  LCD_PORT_w = (data & 0xf0);
  LCD_PORT_w = (data << 4) | DISPLAY_EN;
  LCD_PORT_w = (data << 4) | DISPLAY_EN;
  LCD_PORT_w = (data << 4) | DISPLAY_EN;
  LCD_PORT_w = (data << 4);
    DDRC &= ~(0x80+0x40+0x20+0x10+0x08);
   PORTD &= ~0x08;
 
}

void _lcd_write_4bit(unsigned char data)
{
 DDRC |= (0x80+0x40+0x20+0x10+0x08);
  LCD_PORT_w = (data << 4) | DISPLAY_EN;
  LCD_PORT_w = (data << 4) | DISPLAY_EN;
  LCD_PORT_w = (data << 4) | DISPLAY_EN;
  LCD_PORT_w = (data << 4);
  LCD_PORT_w = (data << 4);
    DDRC &= ~(0x80+0x40+0x20+0x10+0x08);
 PORTD &= ~0x08;
 
}

void lcd_write_byte(unsigned char data)
{
 DDRC |= (0x80+0x40+0x20+0x10+0x08);
  LCD_PORT_w = (data & 0xf0) | DISPLAY_EN | DISPLAY_RS;
  LCD_PORT_w = (data & 0xf0) | DISPLAY_EN | DISPLAY_RS;
  LCD_PORT_w = (data & 0xf0) | DISPLAY_RS;
  LCD_PORT_w = (data & 0xf0) | DISPLAY_RS;
  LCD_PORT_w = (data << 4)   | DISPLAY_EN | DISPLAY_RS;
  LCD_PORT_w = (data << 4)   | DISPLAY_EN | DISPLAY_RS;
  LCD_PORT_w = (data << 4)   | DISPLAY_RS;
    DDRC &= ~(0x80+0x40+0x20+0x10+0x08);
 PORTD &= ~0x08;
 
}


int my_pput(int zeichen)
{
 lcd_write_byte((char) zeichen);
 return(1);
}



// getch.c
unsigned char getch(void)   // warten und Zeichen abholen
{
 loop_until_bit_is_set(UCSRA, RXC);    // warte bis Zeichen da

 return UDR;                           // Zeichen abholen
}

// getche.c warten, Zeichen abholen und im Echo senden
void getche(void)
{
 unsigned char x;
 loop_until_bit_is_set(UCSRA, RXC);
 x = UDR;
 loop_until_bit_is_set(UCSRA, TXC);
 UDR = x;
}
// initialize the LCD controller
void LCD_Init(void)
{

LCD_PORT_DDR = 0xff;// - (0x01 + 0x02) ;//0xf0 | DISPLAY_RS | DISPLAY_EN;
_long_delay();
_long_delay();
_lcd_write_4bit(0x03);     // noch 8 Bit
_long_delay();
_lcd_write_4bit(0x03);     // noch 8 Bit
_long_delay();
_lcd_write_4bit(0x03);     // noch 8 Bit
_long_delay();
_lcd_write_4bit(0x02);     // jetzt 4 Bit
_long_delay();

_lcd_write_command(0x28);     // 4 Bit Zweizeilig
//-
_long_delay();
_long_delay();
_lcd_write_command(0x1C);     
_long_delay();
_lcd_write_command(0x74);     
_long_delay();
_lcd_write_command(0x52);     // 
_long_delay();
_lcd_write_command(0x69);     // Contrast 

// ----------------------------
//-
_long_delay();
_lcd_write_command(0x08);     // Display aus
_long_delay();
_lcd_write_command(0x01);     // Clear
_long_delay();
_lcd_write_command(0x06);     //Entry mode
_long_delay();
_lcd_write_command(0x08 + 4); // Display an
_long_delay();
}


void LCD_Gotoxy(unsigned char x , unsigned char y)
 {
  _short_delay();
  switch(y)
  { case 0 : _lcd_write_command(x + 0x80); break;
    case 1 : _lcd_write_command(x + 0xC0); break;
    case 2 : _lcd_write_command(x + (0x80 + 20)); break;
    case 3 : _lcd_write_command(x + (0xC0 + 20)); break;
  }
  
}


void LCD_Write(unsigned char *this_text)
{
 unsigned char i = 0;
  
 while(this_text[i] != 0) 
  {
   lcd_write_byte(this_text[i++]);
   _long_delay();
   
  }
    
  
}

char LCD_Putchar(char zeichen)
{
_short_delay();
 lcd_write_byte((char) zeichen);
 return(1);
}

Bitte um jede Art von Hilfe.

Gruß

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>void t2(void){
>DDRC=0x00; //PORTC EINGANG-UmTasten herauszulesen

Was soll der Blödsinn hier das DDR für den kompletten Port
zu setzen? Und wieso wird das DDR für die Tasten erst hier
gesetzt? Einmal reicht. Muß man nicht dauernd machen.

>if(!(PINC&0x80)&&!lcd){LCD_Init();

Was soll der Schwachsinn mit dem LCD_Init() hier?
Einmal reicht.

>LCD_Gotoxy(0,0);
>LCD_Write("H");
>lcd=true;
>}
>}

>void LCD_Init(void)
>{
>
>LCD_PORT_DDR = 0xff;// - (0x01 + 0x02) ;//0xf0 | DISPLAY_RS | DISPLAY_EN;

Was soll der Blödsinn hier das DDR für den kompletten Port
zu setzen? Setz die Bits die du brauchst und gut.

Alles Blödsinn was du da machst. Und dann mit
Multitasking rumspielen. Ich schmeiß mich weg;)

Autor: caler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo. Nein reicht nicht, denn PORTC muss zugleich Tasteneingänge und 
als LCD-port dienen.
Das andere ist nur figurativ gesehen.
Meine Frage war andersrum, ob nämlich etwas an den LCD-funktionen falsch 
ist

gruß

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
JTAG-Interface deaktiviert?

...

Autor: Zacc (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alles Falsch. Alles in die Tonne. Ein LCD dauert seine Zeit zum 
Initialisieren. Und die Tasten duerfen die Bits kaputtmachen... Und 
Multitasking... heul. Das bringt nichts, mach was anderes.

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.