Hallo, ich möchte ein 4x16 LCD mit einem ATmega2560 ansteuern. Ich habe bereits ein Display mit mit einem 162 angesteuert... hierfür hatte ich 2 Ports verwendet... Da Ich aber den 4 Bit-modus verwende und nur die 3 steuerleitungen habe, habe ich das Display komplett an Port K angeschlossen... Irgendwie funktioniert jedoch die Software nicht, ich habe alles an Port K angepasst... tut sich jedoch nix
Schick doch mal Schaltplan und Programm, sonst wird dir hier wohl niemand helfen können.
Hier ist der Code:
#include <avr/interrupt.h>
#include <avr/io.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <util/crc16.h>
#include <util/delay.h>
#include "1wire.h"
#define F_CPU 14745600UL
#define nop() asm volatile("nop") //Verzögerung
//Display Clear:
#define LCD_CLEAR 0x01 //Display löschen
//Return Home:
#define LCD_RETURN_HOME 0x02 //Cursor in Grundstellung
//Eintragungsmodus:
#define LCD_DEC 0x04 //Dekrement, Displayshift aus
#define LCD_INC 0x06 //Inkrement, Displayshift aus
//Display on/off:
#define LCD_OFF 0x08 //Display aus
#define LCD_ON 0x0F //Display ein, kein Kursor, kein
blinken
//#define LCD_ 0x0D //Display ein, kein Kursor, Zeichen
blinkt
//#define LCD_ 0x0E //Display ein, Kursor aktiv, kein
blinken
//#define LCD_ 0x0F //Display ein, Kursor aktiv, Zeichen
blinkt
//Shift:
//#define LCD_ 0x10 //Cursorbewegung nach links
//#define LCD_ 0x17 //Cursorbewegung nach rechts
//#define LCD_ 0x18 //Display und Cursorbewegung nach links
//#define LCD_ 0x1F //Display und Cursorbewegung nach
rechts
//Interface:
#define LCD_4BIT_1Z_5x7 0x20 //4bit-Datenbus,einzeiliges
Disolay,5x7Punktmatrix
//Interface:
#define LCD_4BIT_1Z_5x10 0x24 //4bit-Datenbus,einzeiliges
Disolay,5x10Punktmatrix
//Interface:
#define LCD_4BIT_2Z_5x7 0x28 //4bit-Datenbus,zweizeiliges
Disolay,5x7Punktmatrix
//Interface:
#define LCD_4BIT_2Z_5x10 0x2C //4bit-Datenbus,zweizeiliges
Disolay,5x10Punktmatrix
//Interface:
#define LCD_8BIT_1Z_5x7 0x30 //8bit-Datenbus,einzeiliges
Disolay,5x7Punktmatrix
//Interface:
#define LCD_8BIT_1Z_5x10 0x34 //8bit-Datenbus,einzeiliges
Disolay,5x10Punktmatrix
//Interface:
#define LCD_8BIT_2Z_5x7 0x38 //8bit-Datenbus,zweizeiliges
Disolay,5x7Punktmatrix
//Interface:
#define LCD_8BIT_2Z_5x10 0x3C //8bit-Datenbus,zweizeiliges
Disolay,5x10Punktmatrix
//Instuction/Data
#define LCD_CTRL 0 //RS=0
#define LCD_DATA 1 //RS=1
//Charakter-RAM-Adresse 0x40..0x7F;
#define LCD_CGRAM (0 | (1<<6)) //0x40
//Anzeigen-RAM-Adresse (0x80...0xFF) für LCD4x20:
#define LCD_DDRAM_Line_1 (0 | (1<<7)) //0x80 ... 0x93
#define LCD_DDRAM_Line_2 (64 | (1<<7)) //0xC0 ... 0xD3
#define LCD_DDRAM_Line_3 (20 | (1<<7)) //0x94 ... 0xA7
#define LCD_DDRAM_Line_4 (84 | (1<<7)) //0xD4 ... 0xE7
//Ausgänge fur LCD-Steuerleitungen:
#define LCD_RS (1<<0) //Bit0
#define LCD_RW (1<<1) //Bit1
#define LCD_E (1<<2) //Bit2
#define LCD_set_RS() (PORTK |= LCD_RS)
#define LCD_set_RW() (PORTK |= LCD_RW)
#define LCD_set_E() (PORTK |= LCD_E)
#define LCD_clear_RS() (PORTK &= ~LCD_RS)
#define LCD_clear_RW() (PORTK &= ~LCD_RW)
#define LCD_clear_E() (PORTK &= ~LCD_E)
//Definitionen für serielle Schnittstelle
#define CLOCK 14745600 //Oszillatorfrequenz 14,7456MHz
//Globale Variablendeklaration***********************************
unsigned int Time1=0;
static volatile unsigned char RxIndex;
//Temperaturwert Variablen*************************************
uint8_t temp_lsb,temp_msb;//Byte0 und 1 Scratchpad (MSB und LSB)
uint8_t cr; //Byte6 Scratchpad (Count Remain)
int dezist,absst; //Vor- und Nachkommastelle Tempwert
bool vorzeichen; //Vorzeichen der Temperatur "0" = + / "1" = -
//Funktionsprototypen für wichtige Funktionen********************
void Init_Devices(void);//Initialisierung CPU
void LCD_enable(void);//Enable-Impuls
void LCD_busy(void);//Warten solange LCD-Display Busy
void Put_char_to_LCD(char Data,char RS);//Zeichen auf LCD-Display
ausgeben
void LCD_init(void);//Initialisierung LCD-Display
void LCD_special_sign (void);//8 benutzerdefinierte Sonderzeichen
schreiben
void Transmit_string_to_LCD(unsigned char row_adress,unsigned char
*buffer);//LCD
void Delay (unsigned int time);//Zeitverzögerung, Wert in ms
//Interrupt Vectoren********************************************
ISR(INT0_vect)
{
//Taste 4
}
ISR(INT1_vect)
{
//Taste 1
}
ISR(INT2_vect)
{
}
ISR(INT3_vect)
{
}
ISR(INT4_vect)
{
}
ISR(INT5_vect)
{
}
ISR(INT6_vect)
{
}
ISR(INT7_vect)
{
}
ISR(PCINT0_vect)
{
}
ISR(PCINT1_vect)
{
}
ISR(PCINT2_vect)
{
}
ISR(WDT_vect)
{
}
ISR(TIMER2_COMPA_vect)
{
}
ISR(TIMER2_COMPB_vect)
{
}
ISR(TIMER2_OVF_vect)
{
}
ISR(TIMER1_CAPT_vect)
{
}
ISR(TIMER1_COMPA_vect)
{
}
ISR(TIMER1_COMPB_vect)
{
}
ISR(TIMER1_COMPC_vect)
{
}
ISR(TIMER1_OVF_vect)
{
//TIMER1 has overflowed
TCNT1H= 0xF8; //reload counter high value
TCNT1L= 0xCD; //reload counter low value
++Time1;
}
ISR(TIMER0_COMPA_vect)
{
}
ISR(TIMER0_COMPB_vect)
{
}
ISR(TIMER0_OVF_vect)
{
}
ISR(SPI_STC_vect)
{
}
ISR(USART0_RX_vect)
{
}
ISR(USART0_UDRE_vect)
{
}
ISR(USART0_TX_vect)
{
}
ISR(ANALOG_COMP_vect)
{
}
ISR(ADC_vect)
{
}
ISR(EE_READY_vect)
{
}
ISR(TIMER3_CAPT_vect)
{
}
ISR(TIMER3_COMPA_vect)
{
}
ISR(TIMER3_COMPB_vect)
{
}
ISR(TIMER3_COMPC_vect)
{
}
ISR(TIMER3_OVF_vect)
{
}
ISR(USART1_RX_vect)
{
}
ISR(USART1_UDRE_vect)
{
}
ISR(USART1_TX_vect)
{
}
ISR(TWI_vect)
{
}
ISR(SPM_READY_vect)
{
}
ISR(TIMER4_CAPT_vect)
{
}
ISR(TIMER4_COMPA_vect)
{
}
ISR(TIMER4_COMPB_vect)
{
}
ISR(TIMER4_COMPC_vect)
{
}
ISR(TIMER4_OVF_vect)
{
}
ISR(TIMER5_CAPT_vect)
{
}
ISR(TIMER5_COMPA_vect)
{
}
ISR(TIMER5_COMPB_vect)
{
}
ISR(TIMER5_COMPC_vect)
{
}
ISR(TIMER5_OVF_vect)
{
}
ISR(USART2_RX_vect)
{
}
ISR(USART2_UDRE_vect)
{
}
ISR(USART2_TX_vect)
{
}
ISR(USART3_RX_vect)
{
}
ISR(USART3_UDRE_vect)
{
}
ISR(USART3_TX_vect)
{
}
//Zeitverzögerung**********************************************
//ms-----------------------------------------------------------
void delay_ms(unsigned int ms)
{
unsigned int zaehler;
while (ms) {
zaehler = F_CPU / 5000;
while (zaehler) {
asm volatile("nop");
zaehler--;
}
ms--;
}
}
//Initialisierung der Ports***************************************
void port_init(void) //Ports für Kommunikation, Tastatur, Display,
Tempsensor setzen
//Nicht verwendete Ports Ausgang "low"
{
DDRA = (1 << DDA3) | (1 << DDA4) | (1 << DDA5) | (1 << DDA6) | (1 <<
DDA7);
//PortA Eingang/Ausgang setzen
PORTA &= ~( (1<<PA3) | (1<<PA4) | (1<<PA5) | (1<<PA6) | (1<<PA7));
//PortB Pullup/Pegel setzen
DDRB = (1 << DDB4) | (1 << DDB5) | (1 << DDB6) | (1 << DDB7);
//PortB Eingang/Ausgang setzen
PORTB &= ~( (1<<PB4) | (1<<PB5) | (1<<PB6) | (1<<PB7) );
//PortB Pullup/Pegel setzen
DDRC = 0b11110000; //PortC Eingang/Ausgang
PORTC = 0b00000000; //Pullup/Pegel setzen
DDRD = (0 << DDD0) | (0 << DDD1) | (0 << DDD4) | (0 << DDD5) | (0 <<
DDD6) | (0 << DDD7);
//PortD Eingang/Ausgang setzen
PORTD &= ~( (1<<PD0) | (1<<PD1) | (1<<PD4) | (1<<PD5) | (1<<PD6) |
(1<<PD7) );
//PortD Pullup/Pegel setzen
DDRE = (1 << DDE2) | (1 << DDE3) | (1 << DDE4) | (1 << DDE5) | (1 <<
DDE6) | (1 << DDE7);
//PortE Eingang/Ausgang setzen
PORTE &= ~( (1<<PE2) | (1<<PE3) | (1<<PE4) | (1<<PE5) | (1<<PE6) |
(1<<PE7) );
//PortE Pullup/Pegel setzen
DDRF = (1 << DDF0) | (1 << DDF1) | (1 << DDF2) | (1 << DDF3);
//PortF Eingang/Ausgang setzen
PORTF &= ~( (1<<PF0) | (1<<PF1) | (1<<PF2) | (1<<PF3) );
//PortF Pullup/Pegel setzen
DDRG = 0b111111; //PortG Eingang/Ausgang
PORTG = 0b000000; //Pullup/Pegel setzen
DDRH = (1 << DDH2) | (1 << DDH3) | (1 << DDH4) | (1 << DDH5) | (1 <<
DDH6) | (1 << DDH7);
//PortH Eingang/Ausgang setzen
PORTH &= ~( (1<<PH2) | (1<<PH3) | (1<<PH4) | (1<<PH5) | (1<<PH6) |
(1<<PH7) );
//PortH Pullup/Pegel setzen
DDRJ = (1 << DDJ2) | (1 << DDJ3) | (1 << DDJ4) | (1 << DDJ5) | (1 <<
DDJ6) | (1 << DDJ7);
//PortJ Eingang/Ausgang setzen
PORTJ &= ~( (1<<PJ2) | (1<<PJ3) | (1<<PJ4) | (1<<PJ5) | (1<<PJ6) |
(1<<PJ7) );
//PortJ Pullup/Pegel setzen
DDRK = 0b11111111; //PortK Eingang/Ausgang
PORTK = 0b00000000; //Pullup/Pegel setzen
DDRL = 0b00111111; //PortL Eingang/Ausgang
PORTL = 0b00000000; //Pullup/Pegel setzen
}
//***************************************************************
//*********************** D I S P L A Y**************************
//***************************************************************
//Chattabelle zur Erzeugung eigener benutzerdefinierter Zeichen
unsigned char chartab[64] = {0x11,0x04,0x0A,0x11,0x1F,0x11,0x11,0x00,//Ä
0x11,0x0E,0x11,0x11,0x11,0x11,0x0E,0x00,//Ö
0x11,0x00,0x11,0x11,0x11,0x11,0x0E,0x00,//Ü
0x00,0x00,0x00,0x15,0x00,0x00,0x00,0x00,//"Strichpunktlinie"
0x00,0x00,0x1F,0x1F,0x1F,0x00,0x00,0x00,//"Strich
fett"
0x00,0x1F,0x11,0x11,0x11,0x1F,0x00,0x00,//Kästchen
leer
0x00,0x1F,0x1F,0x1F,0x1F,0x1F,0x00,0x00,//Kästchen
voll
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};//leer
//siehe mehrdimensionale Vectoren [S. 107 Programmieren in C
Kerninghan/Ritchie]
//**********************************************************************
****
//TIMER1 initialize - prescale:8
// WGM: 0) Normal, TOP=0xFFFF
// desired value: 1mSec
// actual value: 1,000mSec (0,0%)
void timer1_init(void)
{
//TCCR1B = 0x01; //start
TCNT1H = 0xF8; //setup
TCNT1L = 0xCD;
OCR1AH = 0x07;
OCR1AL = 0x33;
OCR1BH = 0x07;
OCR1BL = 0x33;
OCR1CH = 0x07;
OCR1CL = 0x33;
ICR1H = 0x07;
ICR1L = 0x33;
TCCR1A = 0x00;
TCCR1B = 0x00; //stop Timer
}
//----------------------------------------------------------------------
---------
void Init_Devices(void)
{
//stop errant interrupts until set up
cli(); //disable all interrupts
// XDIV = 0x00; //xtal divider
XMCRA = 0x00; //external memory
port_init();
timer1_init();
MCUCR = 0x00;
EICRA = 0x00; //extended ext ints
EICRB = 0x00; //extended ext ints
EIMSK = 0x00;
// TIMSK = 0x04; //timer interrupt sources
// ETIMSK = 0x00; //extended timer interrupt sources
sei(); //re-enable interrupts
//all peripherals are now initialized
}
//----------------------------------------------------------------------
---------
//----------------------------------------------------------------------
---------
//Ablauf Displaycontroller HD44780
void LCD_init(void)
{
delay_ms(16);
//SW Reset
Put_char_to_LCD(LCD_4BIT_2Z_5x7,LCD_CTRL);//4Bit Mode, 2 Zeilen, 5x7
Matrix
delay_ms(5);
Put_char_to_LCD(LCD_4BIT_2Z_5x7,LCD_CTRL);//4Bit Mode, 2 Zeilen, 5x7
Matrix
delay_ms(1);
Put_char_to_LCD(LCD_4BIT_2Z_5x7,LCD_CTRL);//4Bit Mode, 2 Zeilen, 5x7
Matrix
Put_char_to_LCD(LCD_ON,LCD_CTRL);//Display ON
Put_char_to_LCD(LCD_INC,LCD_CTRL);//Display auf Inkrement, kein
Displayshift
Put_char_to_LCD(LCD_RETURN_HOME,LCD_CTRL);//LCD_RETURN_HOME
Put_char_to_LCD(LCD_CLEAR,LCD_CTRL);//Display löschen
}
//****************************************************************
//8 benutzerdefinierte Sonderzeichen schreiben
//0x40+(0...7) Adresse CG-RAM 1.Zeichen
//0x40+(8...5) Adresse CG-RAM 2.Zeichen
//0x40+(16...23) Adresse CG-RAM 3.Zeichen
//0x40+(24...31) Adresse CG-RAM 4.Zeichen
//0x40+(32...39) Adresse CG-RAM 5.Zeichen
//0x40+(40...47) Adresse CG-RAM 6.Zeichen
//0x40+[48...55) Adresse CG-RAM 7.Zeichen
//0x40+[56...63) Adresse CG-RAM 8.Zeichen
void LCD_special_sign (void)
{
unsigned char Index=0;
Put_char_to_LCD (LCD_CGRAM,LCD_CTRL);//Display CG-RAM-Adresse für
1.Zeichen
/*Durch interne Autoincrementfunktion des CG-RAM-Adresszählers im
Display
braucht dieser nicht extra incrementiert werden!*/
do
{
Put_char_to_LCD(chartab[Index],LCD_DATA);
++Index;
}while(Index < 64);//Anzahl 8Zeichen x 8Bytes/Zeichen
}
//******************************************
// Funktion gibt ein Zeichen auf Data- oder Ctrl-Register aus
void Put_char_to_LCD(char Data, char RS)
{
LCD_clear_RW();
if(RS)//RS=1?
{//ja RS=1,RW=0 Data Register
LCD_set_RS();
}
else
{//nein RS=0,RW=0 Ctrl Register
LCD_clear_RS();
}
//4bit-Modus
PORTK = ( (Data&0xF0)|(PORTK&0x0F) );//H-Byte
LCD_enable();//H-Byte senden
PORTK = ( (((Data&0x0F)<<4)&0xF0)|(PORTK&0x0F) );//L-Byte
LCD_enable();//L-Byte senden
LCD_busy();//4bit-Modus und 8bit-Modus
}
//******************************************
void LCD_enable (void)
{
nop();//67,8ns (>60ns)
LCD_set_E();//E=1 (>300ns)
nop();//67,8ns
nop();//67,8ns
nop();//67,8ns
nop();//67,8ns
LCD_clear_E();//E=0 (>366ns)
nop();//67,8ns
nop();//67,8ns
nop();//67,8ns
nop();//67,8ns
nop();//67,8ns
nop();//67,8ns
}
//******************************************
// Funktion wartet solange Display bereit ist bzw. fertig ist
void LCD_busy(void)
{
unsigned char Busy;
LCD_clear_RS();//RS=0
LCD_set_RW();//RW=1
DDRK &= 0x0F;//4bit-Modus, PortK H-Byte Eingänge
//DDRA = 0x00;//8bit-Modus, PortK Eingänge
do
{
nop();//67,8ns bei 14,7456MHz (>60ns)
LCD_set_E();//E=1
nop();//67,8ns (>300ns)
nop();//67,8ns
nop();//67,8ns
nop();//67,8ns
Busy = PINK;//PortK einlesen,Busyflag lesen (>190ns)
nop();//67,8ns
LCD_clear_E();//E=0 (>366ns)
nop();//67,8ns
nop();//67,8ns
nop();//67,8ns
nop();//67,8ns
nop();//67,8ns
nop();//67,8ns
//noch einen Enable-Impuls senden, keine Busy-Flag Auswertung
LCD_enable ();//4bit-Modus
}while(Busy & 0x80);//Busy-Flag auswerten
DDRK |= 0xF0;//4bit-Modus, PortK H-Byte Ausgänge
LCD_clear_RW();//RW=0
}
//******************************************
void Transmit_string_to_LCD (unsigned char row_adress,unsigned char
*buffer)//Info
{
Put_char_to_LCD(row_adress,LCD_CTRL);//Display Zeile 1
while (*buffer != '\0')//NULL, 0x00, 0, '\0' Endmarkierung eines
Strings,
//oder EOF, 0xFF, -1 (End of a File)
{
Put_char_to_LCD(*buffer++,LCD_DATA);
}
}
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.
