⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcd.c

📁 基于AVR制作的电话语音录制系统
💻 C
字号:
/* vim: set sw=8 ts=8 si : *//****************************************************************************Title	:   HD44780U LCD libraryAuthors:   Based on Volker Oth's lcd library (http://members.xoom.com/volkeroth)modified by Peter Fleury's (http://jump.to/fleury). Flexible pinconfiguration by Markus Ermert. Adapted for the linuxfocus LCD displayby Guido Socher.Software:  AVR-GCC with AVR-ASTarget:    any AVR deviceCopyright: GPL       *****************************************************************************/#include <avr/io.h>#include <avr/pgmspace.h>#include "lcd_hw.h"#include "lcd.h"#include "avr_compat.h"/* ** constants/macros *///#define lcd_e_delay()   delay_us(1) #define lcd_e_delay() asm("nop"); asm("nop");#define lcd_e_high()    sbi(LCD_E_PORT, LCD_E_PIN)#define lcd_e_low()     cbi(LCD_E_PORT, LCD_E_PIN)#define lcd_e_toggle()  toggle_e()#define lcd_cmd_mode()	cbi(LCD_RS_PORT, LCD_RS_PIN)	/* RS=0  command mode   */#define lcd_data_mode()	sbi(LCD_RS_PORT, LCD_RS_PIN)	/* RS=1  data mode      */#define lcd_wr_mode()		cbi(LCD_RW_PORT, LCD_RW_PIN)	/* RW=0  write mode     */#define lcd_rd_mode()		sbi(LCD_RW_PORT, LCD_RW_PIN)	/* RW=1  read mode      */#ifdef OLD#define lcd_data_port_in()	{	/* defines all data pins as input */ \					cbi(LCD_DATA_DDR_D7,LCD_DATA_PIN_D7);\					cbi(LCD_DATA_DDR_D6,LCD_DATA_PIN_D6);\					cbi(LCD_DATA_DDR_D5,LCD_DATA_PIN_D5);\					cbi(LCD_DATA_DDR_D4,LCD_DATA_PIN_D4);\				}#define lcd_data_port_out()	{	/* defines all data pins as output */ \					sbi(LCD_DATA_DDR_D7,LCD_DATA_PIN_D7);\					sbi(LCD_DATA_DDR_D6,LCD_DATA_PIN_D6);\				 	sbi(LCD_DATA_DDR_D5,LCD_DATA_PIN_D5);\				 	sbi(LCD_DATA_DDR_D4,LCD_DATA_PIN_D4);\				}#else#define lcd_data_port_in()  (DDRC&=0xF0)#define lcd_data_port_out() (DDRC|=0x0F)#endif // OLD#if LCD_LINES==1#define LCD_FUNCTION_DEFAULT    LCD_FUNCTION_4BIT_1LINE#else#define LCD_FUNCTION_DEFAULT    LCD_FUNCTION_4BIT_2LINES#endif/* ** function prototypes */static void toggle_e(void);static void lcd_out_high(u08 d);static void lcd_out_low(u08 d);/*** local functions*/void delay_us(unsigned int us)/* delay for a minimum of <us> microseconds    *//* with a 4Mhz crystal, the resolution is 1 us */{    while ( us ) us--;}static void lcd_out_low(u08 d){	/* output low nibble *//*	if (d&0x08)  sbi(LCD_DATA_PORT_D7,LCD_DATA_PIN_D7);		else cbi(LCD_DATA_PORT_D7,LCD_DATA_PIN_D7);	if (d&0x04)  sbi(LCD_DATA_PORT_D6,LCD_DATA_PIN_D6);		else cbi(LCD_DATA_PORT_D6,LCD_DATA_PIN_D6);	if (d&0x02)  sbi(LCD_DATA_PORT_D5,LCD_DATA_PIN_D5);		else cbi(LCD_DATA_PORT_D5,LCD_DATA_PIN_D5);	if (d&0x01)  sbi(LCD_DATA_PORT_D4,LCD_DATA_PIN_D4);		else cbi(LCD_DATA_PORT_D4,LCD_DATA_PIN_D4); */    PORTC = (PORTC &0xF0) | (d&0xF);}static void lcd_out_high(u08 d){	/* output high nibble */ /*	if (d&0x80)  sbi(LCD_DATA_PORT_D7,LCD_DATA_PIN_D7);		else cbi(LCD_DATA_PORT_D7,LCD_DATA_PIN_D7);	if (d&0x40)  sbi(LCD_DATA_PORT_D6,LCD_DATA_PIN_D6);		else cbi(LCD_DATA_PORT_D6,LCD_DATA_PIN_D6);	if (d&0x20)  sbi(LCD_DATA_PORT_D5,LCD_DATA_PIN_D5);		else cbi(LCD_DATA_PORT_D5,LCD_DATA_PIN_D5);	if (d&0x10)  sbi(LCD_DATA_PORT_D4,LCD_DATA_PIN_D4);		else cbi(LCD_DATA_PORT_D4,LCD_DATA_PIN_D4);  */    PORTC = (PORTC & 0xF0) | ((d>>4)&0xF);}static void inline toggle_e(void)/* toggle Enable Pin */{	lcd_e_high();	lcd_e_delay();	lcd_e_low();}static void inline lcd_write(u08 data, u08 rs){	/* configure data pins as output */	lcd_data_port_out();	/* output high nibble first */	lcd_out_high(data);	if (rs)		lcd_data_mode();	/* RS=1: write data            */	else		lcd_cmd_mode();	/* RS=0: write instruction     */	lcd_wr_mode();		/* RW=0  write mode         */	lcd_e_toggle();	/* output low nibble */	lcd_out_low(data);	if (rs)		lcd_data_mode();	/* RS=1: write data            */	else		lcd_cmd_mode();	/* RS=0: write instruction     */	lcd_wr_mode();		/* RW=0  write mode         */	lcd_e_toggle();	/* all data pins high (inactive) */	lcd_data_port_in();}static inline u08 lcd_read(u08 rs){	register u08 data;	/* configure data pins as input */	lcd_data_port_in();	if (rs)		lcd_data_mode();	/* RS=1: read data      */	else		lcd_cmd_mode();	/* RS=0: read busy flag */	lcd_rd_mode();		/* RW=1  read mode      */	lcd_e_high();	lcd_e_delay();	/* read high nibble first */    /*	data =	    bit_is_set(LCD_DATA_PINR_D7, LCD_DATA_PIN_D7) ? 0x80 : 0;	data |=	    bit_is_set(LCD_DATA_PINR_D6, LCD_DATA_PIN_D6) ? 0x40 : 0;	data |=	    bit_is_set(LCD_DATA_PINR_D5, LCD_DATA_PIN_D5) ? 0x20 : 0;	data |=	    bit_is_set(LCD_DATA_PINR_D4, LCD_DATA_PIN_D4) ? 0x10 : 0; */            data = (PINC<<4)&0xF0;	lcd_e_low();	lcd_e_delay();		/* Enable low       */	lcd_e_high();	lcd_e_delay();	/* read low nibble        */	/*data |=	    bit_is_set(LCD_DATA_PINR_D7, LCD_DATA_PIN_D7) ? 0x08 : 0;	data |=	    bit_is_set(LCD_DATA_PINR_D6, LCD_DATA_PIN_D6) ? 0x04 : 0;	data |=	    bit_is_set(LCD_DATA_PINR_D5, LCD_DATA_PIN_D5) ? 0x02 : 0;	data |=	    bit_is_set(LCD_DATA_PINR_D4, LCD_DATA_PIN_D4) ? 0x01 : 0;*/    data |= (PINC & 0xF);	lcd_e_low();	return (data);}static inline unsigned char lcd_waitbusy(void)/* loops while lcd is busy, reads address counter */{	register unsigned char c;	while ((c = lcd_read(0)) & (1 << LCD_BUSY)) {	}	return (c); // return address counter=position}/*** PUBLIC FUNCTIONS */void lcd_command(u08 cmd)/* send commando <cmd> to LCD */{	lcd_waitbusy();	lcd_write(cmd, 0);}void lcd_gotoxy(u08 x, u08 y)/* goto position (x,y) */{#if LCD_LINES==1	lcd_command((1 << LCD_DDRAM) + LCD_START_LINE1 + x);#endif#if LCD_LINES==2	if (y == 0)		lcd_command((1 << LCD_DDRAM) + LCD_START_LINE1 + x);	else		lcd_command((1 << LCD_DDRAM) + LCD_START_LINE2 + x);#endif#if LCD_LINES==3	if (y == 0)		lcd_command((1 << LCD_DDRAM) + LCD_START_LINE1 + x);	else if (y == 1)		lcd_command((1 << LCD_DDRAM) + LCD_START_LINE2 + x);	else if (y == 2)		lcd_command((1 << LCD_DDRAM) + LCD_START_LINE3 + x);#endif#if LCD_LINES==4	if (y == 0)		lcd_command((1 << LCD_DDRAM) + LCD_START_LINE1 + x);	else if (y == 1)		lcd_command((1 << LCD_DDRAM) + LCD_START_LINE2 + x);	else if (y == 2)		lcd_command((1 << LCD_DDRAM) + LCD_START_LINE3 + x);	else			/* y==3 */		lcd_command((1 << LCD_DDRAM) + LCD_START_LINE4 + x);#endif}				/* lcd_gotoxy */void lcd_clrscr(void)/* clear lcd and set cursor to home position */{	lcd_command(1 << LCD_CLR);}void lcd_home(void)/* set cursor to home position */{	lcd_command(1 << LCD_HOME);}void lcd_putc(char c)/* print character at current cursor position */{	lcd_waitbusy();	// read busy-flag and address counter	lcd_write((unsigned char)c, 1);}void rolltext_lcd_p(prog_char *text, int shiftlen){        unsigned char i;        unsigned char j;        unsigned char textlen=0;        while (pgm_read_byte(text+textlen)){                textlen++;        }        if (shiftlen <= ROLLLEN){		i=0;                j=ROLLLEN-shiftlen + 1;                while(i < j){                        lcd_putc(' ');                        i++;                }		j=0;        }else{                j=shiftlen-ROLLLEN;		i=0;        }        if (j <= textlen) {                while(i < ROLLLEN){                        if (pgm_read_byte(text+j)=='\0') break;                        lcd_putc(pgm_read_byte(text+j));                        j++;                        i++;                }        }}void lcd_puts(const char *s)/* print string on lcd  */{	while (*s) {		lcd_putc(*s);		s++;	}}void lcd_puts_p(const prog_char *progmem_s)/* print string from program memory on lcd  */{	register char c;	while ((c = pgm_read_byte(progmem_s++))) {		lcd_putc(c);	}}void lcd_init(u08 dispAttr)/* initialize display and select type of cursor *//* dispAttr: LCD_DISP_OFF, LCD_DISP_ON, LCD_DISP_ON_CURSOR, LCD_DISP_CURSOR_BLINK */{    /*------ Initialize lcd to 4 bit i/o mode -------*/	lcd_data_port_out();	/* all data port bits as output */	sbi(LCD_RS_DDR, LCD_RS_PIN);	/* RS pin as output */	sbi(LCD_RW_DDR, LCD_RW_PIN);	/* RW pin as output */	sbi(LCD_E_DDR, LCD_E_PIN);	/* E  pin as output */	delay_us(16000);	/* wait 16ms or more after power-on       */	/* initial write to lcd is 8bit */	lcd_out_high(LCD_FUNCTION_8BIT_1LINE);	lcd_e_toggle();	delay_us(4992);		/* delay, busy flag can't be checked here */	lcd_out_high(LCD_FUNCTION_8BIT_1LINE);	lcd_e_toggle();	delay_us(64);		/* delay, busy flag can't be checked here */	lcd_out_high(LCD_FUNCTION_8BIT_1LINE);	lcd_e_toggle();	delay_us(64);		/* delay, busy flag can't be checked here */	lcd_out_high(LCD_FUNCTION_4BIT_1LINE);	/* set IO mode to 4bit */	lcd_e_toggle();	/* from now the lcd only accepts 4 bit I/O, we can use lcd_command() */	lcd_command(LCD_FUNCTION_DEFAULT);	/* function set: display lines  */	lcd_command(LCD_DISP_OFF);	/* display off                  */	lcd_clrscr();		/* display clear                */	lcd_command(LCD_MODE_DEFAULT);	/* set entry mode               */	lcd_command(dispAttr);	/* display/cursor control       */}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -