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

📄 lcd-162.c

📁 avr1602源程序 avr1602源程序
💻 C
字号:
// Project:LCD-162
// CPU:Atmega48
// F_CPU: Inner clock 8M
// Build:WinAvr2006.04.21(GCC)
// Design: 楼孟杰 marginlou@sohu.com
// 2007.02.4

#include <avr/io.h> 
#include <avr/interrupt.h>
#include "avr/interrupt.h"
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <util/delay.h>
#include <stdlib.h>
#include <String.h>
//连接
// 1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16
// |  |  |  |  |  |  |__|__|__|__|__|__|__|  |  |
//GND |  VO RS |  E              |           +  -
//   VCC      R/W              PORTB
#define ON         1
#define OFF        0
#define DATA       PORTB
#define DATA_PORT  PORTB
#define DATA_DDR   DDRB
#define DATA_PIN   PINB
#define CMD_PORT   PORTD
#define CMD_DDR    DDRD
#define RS         0    //Pd0
#define RW         1   //Pd1
#define EN         2   //Pd2

#define SET_RS  CMD_PORT|=_BV(RS)
#define CLR_RS  CMD_PORT&=~_BV(RS)
#define SET_RW  CMD_PORT|=_BV(RW)
#define CLR_RW  CMD_PORT&=~_BV(RW)
#define SET_EN  CMD_PORT|=_BV(EN)
#define CLR_EN  CMD_PORT&=~_BV(EN)


void  LCD_Init(void);
void  LCD_Char(unsigned char Xpos,unsigned char Ypos,unsigned char Lchar);
void  LCD_String(unsigned char Xpos,unsigned char Ypos,unsigned char *Lstring);
void  LCD_MoveTo(unsigned char Xpos,unsigned char Ypos);
void  LCD_CurShow(unsigned char Onoff);
void  LCD_CharBlink(unsigned char Onoff);
void  LCD_Command(unsigned char command);
void  LCD_Wait(void);
char  LCD_GetAddress(void);
void  LCD_Data(unsigned char Lchar);
void  LCD_Clear(void);
void  LCD_HZ(void);
void  LCD_HZ2(void);

//定义在FLASH中
const unsigned char FONTS[4][48]PROGMEM={
				             {
							 0x00,0x00,0x0F,0x01,0x01,0x0F,0x01,0x01,//--------
                             0x02,0x1A,0x02,0x02,0x02,0x1F,0x02,0x12,//"我"的上半
                             0x00,0x10,0x18,0x08,0x00,0x1E,0x00,0x08,//--------
                             0x01,0x07,0x0D,0x01,0x01,0x01,0x03,0x00,//--------
                             0x03,0x03,0x01,0x03,0x04,0x18,0x00,0x00,//"我"的下半
                             0x10,0x10,0x00,0x02,0x12,0x1A,0x0E,0x00,//--------
                             },
							 {
							 0x03,0x03,0x02,0x0f,0x08,0x08,0x08,0x08,//---------
							 0x01,0x03,0x03,0x12,0x14,0x14,0x18,0x12,//"的"的上半
							 0x00,0x00,0x00,0x0C,0x0C,0x0C,0x0C,0x0C,//---------
							 0x0F,0x08,0x08,0x08,0x08,0x0F,0x08,0x00,//---------
							 0x13,0x11,0x10,0x10,0x10,0x11,0x10,0x00,//"的"的下半
							 0x0C,0x0C,0x0C,0x0C,0x0C,0x1C,0x18,0x00,//---------
							 },
							 {
							 0x00,0x00,0x00,0x07,0x04,0x04,0x04,0x07,//
							 0x08,0x08,0x08,0x1F,0x08,0x08,0x08,0x1F,//
							 0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,//
							 0x04,0x04,0x07,0x04,0x00,0x00,0x00,0x00,//
							 0x08,0x08,0x1F,0x08,0x08,0x08,0x0F,0x00,//
							 0x10,0x10,0x10,0x04,0x04,0x04,0x1c,0x00,//
							 },
							 {
							 0x0,0x0F,0x09,0x09,0x09,0x0F,0x09,0x09,//
							 0x03,0x01,0x01,0x1F,0x00,0x00,0x0E,0x09,//
							 0x00,0x00,0x02,0x1E,0x00,0x10,0x14,0x04,//
							 0x0F,0x09,0x09,0x09,0x09,0x09,0x13,0x00,//
							 0x09,0x09,0x0B,0x0A,0x0C,0x08,0x0F,0x00,//
							 0x04,0x14,0x14,0x14,0x0C,0x04,0x1C,0x00,//
							 }
 				             };
//定义在EEPROM 中							 
 unsigned char LOU[48] EEMEM={
				             0x03,0x03,0x03,0x03,0x0f,0x03,0x03,0x03,
                             0x01,0x0d,0x07,0x0f,0x13,0x03,0x05,0x09,
                             0x00,0x0c,0x08,0x1e,0x10,0x10,0x0c,0x06,
                             0x07,0x0f,0x0b,0x13,0x03,0x03,0x03,0x00,
                             0x03,0x1f,0x06,0x04,0x01,0x01,0x06,0x00,
                             0x00,0x1f,0x18,0x10,0x00,0x1c,0x06,0x00
                            };
							 
//函数作用:读地址和BUSY标志
char LCD_GetAddress(void)
{
 char address;
 DATA_DDR=0;
  SET_RW;
  _delay_us(5);
 SET_EN;
 _delay_us(5);
 address=DATA_PIN;
 _delay_us(5); 
  CLR_EN;
 CLR_RW;
  _delay_us(50);
 return address;
}

//函数作用:如果忙,则等待
void LCD_Wait(void)
{
 while((LCD_GetAddress())&0x80);
}

//函数作用:送命令字
void LCD_Command(unsigned char command)
{
 LCD_Wait();
 DATA_DDR=0xFF;
 DATA_PORT=command;
 CLR_RW;
  CLR_RS;//command
  _delay_us(5);
 SET_EN;
 _delay_us(5);
 CLR_EN;
 _delay_us(5);
 SET_RS;
 SET_RW;
 DATA_DDR=0x00;
  _delay_us(50);
}

//函数作用:在位置Xpos,Ypos 处显示一个字符
void LCD_Char(unsigned char Xpos,unsigned char Ypos,unsigned char Lchar)
{
LCD_MoveTo(Xpos,Ypos);
LCD_Data(Lchar);
}

//函数作用:送数据
void LCD_Data(unsigned char Lchar)
{
 LCD_Wait();
 DATA_DDR=0xFF;
 DATA_PORT=Lchar;
 _delay_us(5);
 CLR_RW;
 SET_RS; //data
 _delay_us(5);
 SET_EN;

 _delay_us(5);
 CLR_EN;
 CLR_RS;
 SET_RW;
 DATA_DDR=0x00;
  _delay_us(50);
}

//函数作用:清屏
void  LCD_Clear(void)
{
 LCD_Command(0x01);
}

//函数作用:自定义字符并显示,
//          因为一次只能定义8个,而一个汉字要占6个字符,
//          所以不能同时显示2个以上的汉字。
void LCD_HZ(void)
{
unsigned char i=0,j=0,StartX=0;
_delay_ms(10);
StartX=1;
   for(i=0;i<64;i++)
      {
       LCD_Command(0x40+i);
       LCD_Data(0);
      }
   for(j=0;j<4;j++)
   {
      LCD_Clear();
	  _delay_ms(100);
      for(i=0;i<48;i++)
      {//也是CGRAM的地址AC不能到0,进行了这样的处理
	    if(i==0)
		  LCD_Command(0x40);
		else
	      LCD_Command(0x40+i-1);
		
        LCD_Data(pgm_read_byte(FONTS[0]+i+j*48));
      }
	  _delay_ms(100);
      LCD_Char(StartX+0+j*3,0,0x00);
      LCD_Char(StartX+1+j*3,0,0x01);
      LCD_Char(StartX+2+j*3,0,0x02);
      LCD_Char(StartX+0+j*3,1,0x03);
      LCD_Char(StartX+1+j*3,1,0x04);
      LCD_Char(StartX+2+j*3,1,0x05);
       
      for(i=0;i<10;i++)_delay_ms(8);
	  
   }
}

void  LCD_HZ2(void)
{
unsigned char i=0,StartX=0;
_delay_ms(10);
StartX=1;
   for(i=0;i<64;i++)
      {
       LCD_Command(0x40+i-1);
       LCD_Data(0);
      }
      LCD_Clear();
	  _delay_ms(100);
      for(i=0;i<48;i++)
      {//也是CGRAM的地址AC不能到0,进行了这样的处理
	    if(i==0)
		  LCD_Command(0x40);
		else
	      LCD_Command(0x40+i-1);
		
        LCD_Data(eeprom_read_byte(LOU+i));
      }
	  _delay_ms(100);
      LCD_Char(StartX+0,0,0x00);
      LCD_Char(StartX+1,0,0x01);
      LCD_Char(StartX+2,0,0x02);
      LCD_Char(StartX+0,1,0x03);
      LCD_Char(StartX+1,1,0x04);
      LCD_Char(StartX+2,1,0x05);
}

//函数作用:在Xpos,Ypos处显示字符串,
//          此函数实际使用时有问题,
//          主要是光标不能回复到(0,0)
void LCD_String(unsigned char Xpos,unsigned char Ypos,unsigned char *Lstring)
{
 LCD_MoveTo(Xpos,Ypos);
 while(*Lstring) LCD_Data(*Lstring++);
}

//函数作用:把光标移动到 Xpos,Ypos
void LCD_MoveTo(unsigned char Xpos,unsigned char Ypos)
{
  unsigned char address=0;
  if(Xpos<=0) Xpos=0;
  if(Ypos<=0) Ypos=0;
  if(Xpos>=15) Xpos=15;
  if(Ypos>=1)  Ypos=1;
  address=0x80+Xpos+0x40*Ypos;
  LCD_Command(address);
  //好像有问题,MoveTo(0,0),实际在第一行第二个字符
  //一直不能定位到第一个字符处。???
}

//函数作用:光标的打开,关闭
void LCD_CurShow(unsigned char Onoff)
{
 if(Onoff==0)
   LCD_Command(0x0C);
 else
   LCD_Command(0x0E);
}

//函数作用:光标的闪烁 的 开和关
void LCD_CharBlink(unsigned char Onoff)
{
 if(Onoff==0)
   LCD_Command(0x0C);
 else
   LCD_Command(0x0D);
}

//函数作用:LCD初始化
void LCD_Init(void)
{
 
 DATA_PORT=0;
 DATA_DDR=0xFF;
 CMD_PORT=0;
 CMD_DDR=0xFF;
 //_delay_ms(100);
 LCD_Command(0x38);
 _delay_ms(5);
 LCD_Command(0x38);
 _delay_us(100);
 LCD_Command(0x38);
 _delay_us(100);
 LCD_Command(0x38);//8bit mode, 2X16, 5X7 FONTS
 LCD_Command(0x0C); //
 LCD_Command(0x01); //clear screen
 LCD_Command(0x06); //cursor shift
}



int main(void)
{
 unsigned char i=0;
 unsigned char mtimer[10]="00:00:00  ";
 unsigned char Hou=0;
 unsigned char Min=0;
 unsigned char Sec=0;
 LCD_Init();
 
  LCD_Clear();
  LCD_CharBlink(OFF);
  LCD_HZ();
  LCD_Clear();
  LCD_String(0,0,"System Init OK!");
  LCD_String(0,1,"My AVR world.");
  //LCD_CharBlink(ON);
  for(i=0;i<10;i++) _delay_ms(300);
  LCD_Clear();
  LCD_HZ2();
 _delay_ms(100);

 LCD_String(7,0,"TIME ");
 i=0;
 while(1)
 {
  if(Hou<10)
    {mtimer[0]='0';
	 mtimer[1]='0'+Hou;
	}
  else
    {
	mtimer[0]='0'+Hou/10;
	mtimer[1]='0'+Hou%10;
	}
	
  if(Min<10)
    {mtimer[3]='0';
	 mtimer[4]='0'+Min;
	}
  else
    {
	mtimer[3]='0'+Min/10;
	mtimer[4]='0'+Min%10;
	}
  if(Sec<10)
    {mtimer[6]='0';
	 mtimer[7]='0'+Sec;
	}
  else
    {
	mtimer[6]='0'+Sec/10;
	mtimer[7]='0'+Sec%10;
	}
	
  LCD_String(5,1,mtimer);
  Sec++;
  _delay_ms(200);
  if(Sec==60)
  {
   Sec=0;
   Min++;
   if(Min==60)
      {
	   Min=0;
	   if(Hou++==24)Hou=0;
	   }
   }
	  
  }
}

⌨️ 快捷键说明

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