#include <avr/io.h>
#include "lcd1602.h"
#include <util/delay.h>
#include <avr/eeprom.h>
// sendet ein Datenbyte an das LCD
void lcd_data(unsigned char temp1){
LCD_RS_PORT |= (1<<LCD_RS); // RS auf 1 setzen PC3置1,选择数据寄存器
lcd_send(temp1);
}
// sendet einen Befehl an das LCD
void lcd_command(unsigned char temp1){ //pc3,高电平数据寄存器,低电平指令寄存器
LCD_RS_PORT &= ~(1<<LCD_RS); // RS auf 0 setzen PC3置0,选择指令寄存器
lcd_send(temp1);
}
//4-Bit-Modus
void lcd_send(unsigned char data) {
// 先高位
//LCD_DATA_PORT = (LCD_DATA_PORT & 0xF0) | ((data >> 4) & 0x0F);
LCD_DATA_PORT = (LCD_DATA_PORT & ~(LCD_DATA_MARK)) | ((data >> LCD_DATA_SHIFT) & LCD_DATA_MARK);
_delay_us(500);
lcd_enable();
// 后低位
//LCD_DATA_PORT = (LCD_DATA_PORT & 0xF0) | (data & 0x0F);
LCD_DATA_PORT = (LCD_DATA_PORT & ~(LCD_DATA_MARK)) | ((data << LCD_DATA_SHIFT) & LCD_DATA_MARK);
_delay_us(500);
lcd_enable();
_delay_us(200);
LCD_DATA_PORT &= ~(LCD_DATA_MARK);
}
// Enable-Puls
void lcd_enable(void){
LCD_EN_PORT |= (1<<LCD_EN); //PD5置1,执行指令
_delay_us(10);
LCD_EN_PORT &= ~(1<<LCD_EN); //PD5置0
}
void lcd_init(void){
// Port auf Ausgang schalten
//LCD_DDR = LCD_DDR | 0x0F | (1<<LCD_RS) | (1<<LCD_EN1);
_delay_ms(100);
LCD_DATA_DDR |= LCD_DATA_MARK; //设置DATA线的方向为输出
LCD_RS_DDR |= (1<<LCD_RS); //PC3方向寄存器置1,方向为输出.如果PC3置1,第四脚,高电平数据寄存器,低电平指令寄存器
LCD_EN_DDR |= (1<<LCD_EN); //PD5方向寄存器置1,方向为输出.PD5置1,使能端置1,可以执行指令
// muss 3mal hintereinander gesendet werden zur Initialisierung
_delay_ms(50);
//LCD_DATA_PORT = (LCD_DATA_PORT & 0xF0 & ~(1<<LCD_RS)) | 0x03;
LCD_RS_PORT &= ~(1<<LCD_RS); //PC3置0,选择指令寄存器
LCD_DATA_PORT = (LCD_DATA_PORT & ~(LCD_DATA_MARK)) | (0x03<<2); //四线高两位置0,低两位置1
lcd_enable();
_delay_ms(6);
LCD_DATA_PORT = (LCD_DATA_PORT & ~(LCD_DATA_MARK)) | (0x03<<2);
lcd_enable();
_delay_ms(1);
LCD_DATA_PORT = (LCD_DATA_PORT & ~(LCD_DATA_MARK)) | (0x03<<2);
lcd_enable();
_delay_ms(1);
//LCD_DATA_PORT = (LCD_DATA_PORT & 0xF0 & ~(1<<LCD_RS)) | 0x02;
LCD_RS_PORT &= ~(1<<LCD_RS); //PC3置0,选择指令寄存器
LCD_DATA_PORT = (LCD_DATA_PORT & ~(LCD_DATA_MARK)) | (0x02<<2); //四线高两位置0,第三位置1,末位置0
_delay_ms(1);
lcd_enable();
_delay_ms(10);
/* 4-bit interface, dual line, 5x7 dots */
lcd_command(LCD_FUNCTION_4BIT_2LINES);
/* display on, cursor off */
lcd_command(LCD_DISP_ON);
/* display shift off, inc cursor move dir 模式为光标右移,字符不移 */
lcd_command(LCD_ENTRY_INC_);
lcd_clear();
_delay_ms(20);
}
void lcd_clear(void){
lcd_command(CLEAR_DISPLAY);
_delay_ms(30); //此处的30 经验证为最小值,原值为5
}
void lcd_string(char *data){
while(*data) {
lcd_data(*data);
data++;
}
}