Forum: Mikrocontroller und Digitale Elektronik Problem mit SMT 160-30


von Mr. Nice Guy (Gast)


Lesenswert?

Es soll die Temperatur auf ein Display ausgegeben werden.

TS: SMT 160-30
MC: ATMega 16
STK 500
Display mit HD44780 - Controller

leider gibt das Display nur hieroglyphen aus.

Kann jemand helfen, da wir den Fehler nicht finden???



    ***MAIN***

#include <stdlib.h>
#include <stdio.h>
#include <avr/io.h>
#include <inttypes.h>
#include "lcd-routines.h"
#define F_CPU 16000000
#include <util/delay.h>
// #include "lcd-routines.c"
#include <avr/interrupt.h>
#include <math.h>


uint16_t ueber_puls=0;
uint16_t ueber_per=0;
uint16_t puls=0;
uint16_t periode=0;
uint32_t puls1=0;
uint32_t periode1=0;


ISR(INT0_vect)          // Steigende Flanke
{
  periode=TCNT0+ueber_per;  // Endzeit der Periode ermitteln
  ueber_puls=0;        // Überlauf für Puls auf 0 setzen
  ueber_per=0;        // Überlauf für Periode auf 0 setzen
  TCNT0=0;          // Timer Register auf 0 setzen
}

ISR(INT1_vect)          // Fallende Flanke
{
  puls=TCNT0+ueber_puls;    // Puls Zeit berechnen
}

ISR(TIMER0_OVF_vect)        // Overflow T0
{
    ueber_puls=ueber_puls+255;  // bei überlauf von T0 ueber_puls um 255 
erhöhen
  ueber_per=ueber_per+255;    // bei überlauf von T0 ueber_per um 255 
erhöhen
}


int main(void)
{
//  DDRB= 0b00001100;      // Pin B2,B3 als Ausgang
  DDRD= 0b11110011;      // Pin D2,D3 als Eingang
  PORTD=0b00001100;      // Pull Up D2,D3 aktivieren
  lcd_init(/*LCD_DISP_ON*/);    // LCD initialisieren
  char Buffer[20];       // Zeichenkette deklarieren
  double x;          // Float Hilfsvariable x deklarieren

  MCUCR=0b00001011;      // Steigende Flanke an D2 löst Int 0 aus, 
Fallende Flanke an D3 Int 1
  GICR= 0b11000000;      // Interrupt 0 und 1 aktivieren

  TIMSK |= (1<<TOIE0);    // Timer 0 Overflow erlauben
  TCCR0 = 0b00000001;      // Teiler Timer0 auf Cpu Takt

  while(1)
    {
    _delay_ms(200);          // Wartezeit damit das LCD nicht flackert
    sei();              // Interrupts erlauben
    _delay_ms(20);          // Messzeit
    cli();              // Interrupts sperren

    x=(((float)puls/periode)-0.32)*212.765957;

    lcd_clear();


  sprintf( Buffer, "%i ",puls );
    lcd_string(puls);

  sprintf( Buffer, "%i ",periode );
  lcd_string(periode);

  lcd_data(x);

    periode=0;
    puls=0;

    }
}


************************************************************************ 
**************
    ***lcd-routines.c***


#include <avr/io.h>
#include "lcd-routines.h"
#include <util/delay.h>

// sendet ein Datenbyte an das LCD

void lcd_data(unsigned char temp1)
{
   unsigned char temp2 = temp1;

   LCD_PORT |= (1<<LCD_RS);        // RS auf 1 setzen

   temp1 = temp1 >> 4;
   temp1 = temp1 & 0x0F;
   LCD_PORT &= 0xF0;
   LCD_PORT |= temp1;               // setzen
   lcd_enable();

   temp2 = temp2 & 0x0F;
   LCD_PORT &= 0xF0;
   LCD_PORT |= temp2;               // setzen
   lcd_enable();

   _delay_us(42);
}

// sendet einen Befehl an das LCD

void lcd_command(unsigned char temp1)
{
   unsigned char temp2 = temp1;

   LCD_PORT &= ~(1<<LCD_RS);        // RS auf 0 setzen

   temp1 = temp1 >> 4;              // oberes Nibble holen
   temp1 = temp1 & 0x0F;            // maskieren
   LCD_PORT &= 0xF0;
   LCD_PORT |= temp1;               // setzen
   lcd_enable();

   temp2 = temp2 & 0x0F;            // unteres Nibble holen und 
maskieren
   LCD_PORT &= 0xF0;
   LCD_PORT |= temp2;               // setzen
   lcd_enable();

   _delay_us(42);
}

// erzeugt den Enable-Puls
void lcd_enable(void)
{
   // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers 
einfügen
   // Beitrag "Re: Bitte helft mir. Schon wieder AtMega16"
   LCD_PORT |= (1<<LCD_EN);
    _delay_us(1);                   // kurze Pause
   // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers 
verlängern
   // Beitrag "LCD -> Probleme mit Optimierungsgrad"
   LCD_PORT &= ~(1<<LCD_EN);
}

// Initialisierung:
// Muss ganz am Anfang des Programms aufgerufen werden.

void lcd_init(void)
{
   LCD_DDR = LCD_DDR | 0x0F | (1<<LCD_RS) | (1<<LCD_EN);   // Port auf 
Ausgang schalten

   // muss 3mal hintereinander gesendet werden zur Initialisierung

   _delay_ms(15);
   LCD_PORT &= 0xF0;
   LCD_PORT |= 0x03;
   LCD_PORT &= ~(1<<LCD_RS);      // RS auf 0
   lcd_enable();

   _delay_ms(5);
   lcd_enable();

   _delay_ms(1);
   lcd_enable();
   _delay_ms(1);

   // 4 Bit Modus aktivieren
   LCD_PORT &= 0xF0;
   LCD_PORT |= 0x02;
   lcd_enable();
   _delay_ms(1);

   // 4Bit  2 Zeilen  5x7
   lcd_command(0x28);

   // Display ein  Cursor aus  kein Blinken
   lcd_command(0x0C);

   // inkrement / kein Scrollen
   lcd_command(0x06);

   lcd_clear();
}

// Sendet den Befehl zur Löschung des Displays

void lcd_clear(void)
{
   lcd_command(CLEAR_DISPLAY);
   _delay_ms(5);
}

// Sendet den Befehl: Cursor Home

void lcd_home(void)
{
   lcd_command(CURSOR_HOME);
   _delay_ms(5);
}

// setzt den Cursor in Zeile y (1..4) Spalte x (0..15)

void set_cursor(uint8_t x, uint8_t y)
{
  uint8_t tmp;

  switch (y) {
    case 1: tmp=0x80+0x00+x; break;    // 1. Zeile
    case 2: tmp=0x80+0x40+x; break;    // 2. Zeile
    case 3: tmp=0x80+0x10+x; break;    // 3. Zeile
    case 4: tmp=0x80+0x50+x; break;    // 4. Zeile
    default: return;                   // für den Fall einer falschen 
Zeile
  }
  lcd_command(tmp);
}

// Schreibt einen String auf das LCD

void lcd_string(char *data)
{
    while(*data) {
        lcd_data(*data);
        data++;
    }
}



************************************************************************ 
**************
    ***lcd-routines.h***



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);

#define F_CPU 16000000

// LCD Befehle

#define CLEAR_DISPLAY 0x01
#define CURSOR_HOME   0x02

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

#define LCD_PORT      PORTB
#define LCD_DDR       DDRB
#define LCD_RS        PD4
#define LCD_EN        PD5
// DB4 bis DB7 des LCD sind mit PD0 bis PD3 des AVR verbunden

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.