www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik LCD mit PIC16 ansteuern


Autor: Martin S. (drunkenmunky)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
ich versuche mit einem PIC16F887 das LCD auf dem PICDEM 2 PLUS DEMO 
BOARD anzusteuern. Habe das Programm größtenteils von dem Beispiel 
übernommen. Die Initialisierung und die Steueranweisungen für den Cursor 
funktionieren auch, nur Text schreiben mit der lcd_puts() Funktion 
funktioniert nicht. Kann mal bitte jemand drüberschauen?
/* This is a simple demo project written for use with
 * the HI-TECH Software PICC compiler. It may be compiled
 * and run on the Microchip PICDEM 2 PLUS DEMO BOARD.
 * Features demonstrated include driving the LCD display and
 * the A2D converter. 
 
 Additional files required for this demo are included in the
 PIC\SAMPLES directories:
 DELAY\delay.c
 DELAY\delay.h
 lcd.c
 lcd.h
 */

#include <htc.h>
#include <stdio.h>
//#include <pic16f887.h>
#include "lcd.h"
#include "delay.h"
//#include "picdem2_lcd_htc.h"

/* this is the maximum value of an A2D conversion. */
#define MAXVOLTAGE 5

void init(void){
  lcd_init(FOURBIT_MODE);
  ADON=1;  /* enable A2D converter */
  ADIE=0;  /* not interrupt driven */
  ADCON1=0x0E;
  ADCON0=1;
  TRISB=0x00;  // Set PORTB in output mode
  T1CON=0x31;  // turn on timer 1
  TMR1IE=1;  // timer 1 is interrupt enabled
  PEIE=1;    // enable peripheral interrupts
  GIE=1;    // turn on interrupts
}

void interrupt isr(void){
  if(TMR1IE && TMR1IF){
    PORTB++;
    TMR1IF=0;
  }
}

void main(void){
  unsigned char last_value;
  unsigned char volts;
  unsigned char decivolts;
  unsigned char outString[20];

  init();
  lcd_clear();
  DelayMs(500);
  DelayMs(500);
  DelayMs(500);
  lcd_puts("test");  
      
  while(1)
  {
    
  }
}



/*
 *  LCD interface example
 *  Uses routines from delay.c
 *  This code will interface to a standard LCD controller
 *  like the Hitachi HD44780. It uses it in 4 or 8 bit mode
 *  
 */

#include  <htc.h>
//#include <pic16f887.h>
#include  "lcd.h"
 
static bit fourbit;    // four or eight bit mode?

#ifdef CHECKBUSY

unsigned char 
lcd_read_cmd_nowait(void)
{
  unsigned char c, readc;

  LCD_DATA_TRIS   |=  ~OUTPUT_DATA;  // Set data lines to input

  LCD_RW = 1; // Read LCD
  _delay(2); // short propagation delay

  if (fourbit) {
    LCD_STROBE_READ(readc); // Read high nibble
    // Move 4 bits to high nibble while zeroing low nibble
    c = ( ( readc << 4 ) & 0xF0 ); 
    LCD_STROBE_READ(readc); // Read low nibble
        c |= ( readc & 0x0F ); // Or in 4 more bits to low nibble
  } else {
    LCD_STROBE_READ(readc); 
    c = readc;
  }
  LCD_RW = 0; // Return to default mode of writing LCD
  LCD_DATA_TRIS &= OUTPUT_DATA; // Return to default mode of writing LCD

  return(c);
}

void
lcd_check_busy(void) // Return when the LCD is no longer busy, or we've waiting long enough!
{
  // To avoid hanging forever in event there's a bad or 
  // missing LCD on hardware.  Will just run SLOW, but still run.
  unsigned int retry; 
  unsigned char c;

  for (retry=1000; retry-- > 0; ) {
    c = lcd_read_cmd_nowait();
    if (0==(c&0x80)) break; // Check busy bit.  If zero, no longer busy
  }
}

#endif

void
lcd_send(unsigned char c)
{  
  LCD_EN = 1;
  if (fourbit) {
    LCD_TX(c>>4);  // load upper nibble
    LCD_EN = 0;
    NOP();
    NOP();
    LCD_EN = 1;
    LCD_TX(c);  // load lower nibble
  } else {
    LCD_DATA = c;  // load both nibbles
  }
  LCD_EN = 0;
  
}

/* send a command to the LCD */
void
lcd_cmd(unsigned char c)
{
  LCD_WAIT; // may check LCD busy flag, or just delay a little, depending on lcd.h
  LCD_RS = 0;
  lcd_send(c);
}

/* send data to the LCD */
void
lcd_data(unsigned char c)
{
  LCD_WAIT; // may check LCD busy flag, or just delay a little, depending on lcd.h
  
  LCD_RS = 1;
  lcd_send(c);
  LCD_RS = 0;
}

/* write a string of chars to the LCD */
void
lcd_puts(const char * s)
{
  while(*s)
    lcd_data(*s++);
  
}

/* initialize the LCD */
void
lcd_init(unsigned char mode)
{
  char init_value;

  fourbit    = 0;
  if (mode == FOURBIT_MODE){
    fourbit = 1;
    init_value = 0x3;
  }else{
    init_value = 0x3F;
  }

#if (_PICDEM2_REVISION_ == 6)
  LCD_CTRL &= 0x0F;
  // All data and control lines on same TRIS register
  LCD_DATA_TRIS   &= (OUTPUT_DATA & OUTPUT_CTRL);
  LCD_VCC = 1;  // turn on the power to the LCD
#else
  LCD_RS = 0;
  LCD_EN = 0;
  LCD_RW = 0;

  // Set control lines digital
  ADCON1 = 7;

  // Set control lines to output
  LCD_RS_TRIS   = OUTPUT_PIN;
  LCD_EN_TRIS   = OUTPUT_PIN;
  LCD_RW_TRIS   = OUTPUT_PIN;
  // Set data lines to output
  LCD_DATA_TRIS   &= OUTPUT_DATA;
#endif
  __delay_ms(15);
  LCD_EN = 1;
  LCD_TX(init_value);
  LCD_EN = 0;
  __delay_ms(5);
  LCD_EN = 1;
  LCD_DATA |= init_value;
  LCD_EN = 0;
  __delay_us(200);
  LCD_EN = 1;
  LCD_DATA |= init_value;
  LCD_EN = 0;
  __delay_us(200);
  
  if (fourbit){
    LCD_WAIT;  //may check LCD busy flag, or just delay a little, depending on lcd.h
    LCD_EN = 1;
    LCD_TX(0x2);  // Set 4-bit mode
    LCD_EN = 0;
    lcd_cmd(0x28);  // Function Set
  }else{
    lcd_cmd(0x38);
  }
  lcd_cmd(0xF); //Display On, Cursor On, Cursor Blink
  lcd_clear(); //Display Clear
  lcd_cmd(0x6); //Entry Mode
  lcd_goto(0); //Initialize DDRAM address to zero
}



Autor: Martin S. (drunkenmunky)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hat niemand eine Idee? Da die Steueranweisungen funktionieren, müssten 
die richtigen Ausgänge verwendet werden.

Was kann ich noch testen? Irgendwie von Hand ein Buchstaben schreiben? 
Hat jemand einen Beispielcode dafür?

Vielen Dank im voraus

Autor: Maik Werner (werner01)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Servus,

bei einem von beiden muss das rs_signal vorm enable immer gesetzt 
werden.
Machst Du das?

Autor: Martin S. (drunkenmunky)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja das wird hier gemacht:

 LCD_RS = 1;
 lcd_send(c);
 LCD_RS = 0;

dann wird lcd_send aufgerufen und die zu übertragenden 8 Bit jeweils in 
4 Bit "zerlegt" und übertragen. Muss zwischen den einzelnen 4 Bit das 
LCD_RS Signal auch kurz auf 0 wechseln?

Autor: Martin S. (drunkenmunky)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab den Fehler gefunden... peinlich, peinlich.

Irgendwie hab ich so lang umgeändert, dass ich irgendwie den Port A und 
D nicht als Ausgang definiert habe.

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.