super_castle
11.02.2006, 21:50
hallo, ich befasse mich wieder mit winavr-c.
habe mal für den anfang zum lernen für mich ein einfaches lcd-programm geschrieben. dazu auch eine eigene delay, die delay ist supergenau, (getestet mit avrstudio).
das lcd programm kann mit diesen befehlen erweitert werden:
www.elektronik-projekt.de/include.php?path=content/overview.php&catid=18&type=4
im testprogramm wird von a-z und von A-Z hochgezählt und angezeigt.
wenn EN und RS umgelegt werden, brauchen nur diese daten geändert werden: PC4 (EN) und der wert 0x20 in der temp (PC5=RS).
// LCD HD44780 <4BIT> 2x16, PORTC 0-3 Daten, 4=EN, 5=RS, RW=Masse , AVR 16-8MHZ
#include <inttypes.h>
#include <avr/io.h>
#include <avr/signal.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#define delay_us_(us) _delayFourCycles_( ( ( 1*(F_CPU/4000) )*us)/1500 )
uint8_t temp1, temp2, lcd_daten;
static inline void _delayFourCycles_(uint16_t z)
{
uint16_t i;
for (i=0; i<z; i++)
asm volatile("nop");
}
static inline void delay_ms_(uint16_t z)
{
uint16_t i;
for (i=0; i<z; i++)
delay_us_(999);
}
void lcd_enable()
{
PORTC|=(1<<PC4);
asm volatile("nop");
asm volatile("nop");
PORTC&=~(1<<PC4);
}
void lcd_char(void)
{
temp1=lcd_daten;
temp2=lcd_daten;
temp1= (temp1 << 4) | (temp1 >> 4);
temp1= temp1 & 0x0f;
temp1=temp1 | 0x20;
PORTC=temp1;
lcd_enable();
temp2=temp2 & 0x0f;
temp2=temp2 | 0x20;
PORTC=temp2;
lcd_enable();
delay_us_(50);
}
void lcd_command(void)
{
temp1=lcd_daten;
temp2=lcd_daten;
temp1= (temp1 << 4) | (temp1 >> 4);
temp1=temp1 & 0x0f;
PORTC=temp1;
lcd_enable();
temp2=temp2 & 0x0f;
PORTC=temp2;
lcd_enable();
delay_us_(50);
}
void lcd_init(void)
{
PORTC=3;
lcd_enable();
delay_ms_(5);
lcd_enable();
delay_ms_(5);
lcd_enable();
delay_ms_(5);
PORTC=2;
lcd_enable();
delay_ms_(5);
lcd_daten=0x18;
lcd_command();
lcd_daten=0x0c;
lcd_command();
lcd_daten=4;
lcd_command();
}
void lcd_clear(void)
{
lcd_daten=1;
lcd_command();
delay_ms_(5);
}
int main(void)
{
uint8_t zaehler;
DDRC=0xff;
PORTC=0;
delay_ms_(1000);
lcd_init();
lcd_clear();
zaehler=65;
while(zaehler<123)
{
lcd_clear();
lcd_daten=zaehler;
lcd_char();
zaehler++;
delay_ms_(500);
}
}
Castle
habe mal für den anfang zum lernen für mich ein einfaches lcd-programm geschrieben. dazu auch eine eigene delay, die delay ist supergenau, (getestet mit avrstudio).
das lcd programm kann mit diesen befehlen erweitert werden:
www.elektronik-projekt.de/include.php?path=content/overview.php&catid=18&type=4
im testprogramm wird von a-z und von A-Z hochgezählt und angezeigt.
wenn EN und RS umgelegt werden, brauchen nur diese daten geändert werden: PC4 (EN) und der wert 0x20 in der temp (PC5=RS).
// LCD HD44780 <4BIT> 2x16, PORTC 0-3 Daten, 4=EN, 5=RS, RW=Masse , AVR 16-8MHZ
#include <inttypes.h>
#include <avr/io.h>
#include <avr/signal.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#define delay_us_(us) _delayFourCycles_( ( ( 1*(F_CPU/4000) )*us)/1500 )
uint8_t temp1, temp2, lcd_daten;
static inline void _delayFourCycles_(uint16_t z)
{
uint16_t i;
for (i=0; i<z; i++)
asm volatile("nop");
}
static inline void delay_ms_(uint16_t z)
{
uint16_t i;
for (i=0; i<z; i++)
delay_us_(999);
}
void lcd_enable()
{
PORTC|=(1<<PC4);
asm volatile("nop");
asm volatile("nop");
PORTC&=~(1<<PC4);
}
void lcd_char(void)
{
temp1=lcd_daten;
temp2=lcd_daten;
temp1= (temp1 << 4) | (temp1 >> 4);
temp1= temp1 & 0x0f;
temp1=temp1 | 0x20;
PORTC=temp1;
lcd_enable();
temp2=temp2 & 0x0f;
temp2=temp2 | 0x20;
PORTC=temp2;
lcd_enable();
delay_us_(50);
}
void lcd_command(void)
{
temp1=lcd_daten;
temp2=lcd_daten;
temp1= (temp1 << 4) | (temp1 >> 4);
temp1=temp1 & 0x0f;
PORTC=temp1;
lcd_enable();
temp2=temp2 & 0x0f;
PORTC=temp2;
lcd_enable();
delay_us_(50);
}
void lcd_init(void)
{
PORTC=3;
lcd_enable();
delay_ms_(5);
lcd_enable();
delay_ms_(5);
lcd_enable();
delay_ms_(5);
PORTC=2;
lcd_enable();
delay_ms_(5);
lcd_daten=0x18;
lcd_command();
lcd_daten=0x0c;
lcd_command();
lcd_daten=4;
lcd_command();
}
void lcd_clear(void)
{
lcd_daten=1;
lcd_command();
delay_ms_(5);
}
int main(void)
{
uint8_t zaehler;
DDRC=0xff;
PORTC=0;
delay_ms_(1000);
lcd_init();
lcd_clear();
zaehler=65;
while(zaehler<123)
{
lcd_clear();
lcd_daten=zaehler;
lcd_char();
zaehler++;
delay_ms_(500);
}
}
Castle