原创 AVR8515 +LCD+ 4X4按键

2008-11-8 13:04 2481 3 3 分类: MCU/ 嵌入式


b.gif
b.gif/*  连接情况
            RS----PD0
            RW----PD1
            E-----PD2
        数据位---(PA0~PA7)
*/
/*           1 / 0
    RS-------数据/指令
    RW------读/写
    E--------高脉冲(输出)/高电平(输入)
*/
#include <mega8515.h>
#include <delay.h>
#define uchar unsigned char
#define uint   unsigned int
//---------------------------------------------------------
#define LCD_RS      PORTD.0
#define LCD_RS_DDR  DDRD.0
#define LCD_RW      PORTD.1
#define LCD_RW_DDR  DDRD.1
//########################
//#define LCD_E       PORTD.2
//#define LCD_E_DDR  DDRD.2
#define LCD_E       PORTC.2
#define LCD_E_DDR  DDRC.2
//#########################
#define LCD_DATA  PORTA
#define LCD_DATA_DDR  DDRA
#define LCD_DATA_READ  PINA
#define busy 0x80
//----------------------------------------------------------

//调用函数声明
//-----LCD----------------------------
void W_CMD(unsigned int  cmd,unsigned int  busyC);
void W_DATA(unsigned int data);
unsigned int lcd_busy();
void LCD_init();
void lcd_clear();
void lcd_move();
//-----KEY-------
uchar key_scan();
void key_value();
//////////////////////////////////////////////////////////////////////
//定义变量
unsigned int key_down,key_row;
//unsigned int key_sign;  //案件标志
//-------------------------------------------------------
flash char table[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
flash char table2[]={"CHINESE     "};
//-------------------------------------------------------
void main()
{
unsigned int  i=0,j=0;
delay_ms(15);//开机延迟
//-----LCD---------------
LCD_DATA_DDR=0xff;
LCD_E_DDR=1;
LCD_RS_DDR=1;
LCD_RW_DDR=1;
     //全部输出
    //////////////////
LCD_DATA=0x00;
LCD_E=1;
LCD_RS=1;
LCD_RW=1;
//-----KEY--------------
//---------------------
//-------led-----------
//--------------------
LCD_init();
lcd_clear();//清屏
    delay_ms(5);
lcd_move();//光标移动
lcd_clear();//清屏
    delay_ms(5);
//------初始化显示字符---
W_CMD(0x80,1);
     while(table2!='\0')
        {
        W_DATA(table2);
        i++;
        }
    delay_ms(200);
//---------------------
//换一行
//----------------------
W_CMD(0xc0,1);
  while(table[j]!='\0')
   {
   W_DATA(table[j]);
   j++;
   }
//初始化结束
//判断按键或中断
while(1)
{
  key_value();
}
}



void LCD_init()
{
//三次显示模式设置,不检测忙信号
W_CMD(0x38,0);
delay_ms(5);
W_CMD(0x38,0);
delay_ms(5);
W_CMD(0x38,0);
delay_ms(5);
//-----------------------------------------------
W_CMD(0x38,1);
//显示模式设置,开始要求每次检测忙信号
W_CMD(0x08,1);
//关闭显示
W_CMD(0x01,1);
//显示清屏
W_CMD(0x06,1);
// 显示光标移动设置
W_CMD(0x0C,1);
// 显示开及光标设置
}
/*写命令  ----RS=L;RW=L;E=高脉冲;D0~D7指令*/
void W_CMD(unsigned int  cmd,unsigned int  busyC)
{
if(busyC)
  {
  while(lcd_busy());
  }
LCD_RS=0; //指令
LCD_RW=0;
LCD_E=0;
LCD_DATA=cmd;
    #asm("nop");
    #asm("nop");
    #asm("nop");
    #asm("nop");
LCD_E=1;
    #asm("nop");
    #asm("nop");
    #asm("nop");
    #asm("nop");
LCD_E=0;
//高脉冲
}
void W_DATA(unsigned int data)
{
while(lcd_busy());
LCD_RS=1;//数据
LCD_RW=0;
LCD_E=0;
LCD_DATA=data;
    #asm("nop");
    #asm("nop");
    #asm("nop");
    #asm("nop");
LCD_E=1;
    #asm("nop");
    #asm("nop");
    #asm("nop");
    #asm("nop");
LCD_E=0;
//搞脉冲
}

/*忙检测子程序*/
unsigned int lcd_busy()
{
    unsigned int result;
LCD_DATA_DDR=0x00;//输入
LCD_RS=0;
LCD_RW=1;
LCD_E=1;
#asm("nop");
#asm("nop");
#asm("nop");
#asm("nop");
result=(LCD_DATA_READ&0x80)>>7;
//忙检测
LCD_E=0;   //高电平
LCD_DATA_DDR=0xff;//输出
//------------------------------------
return  result;
}
void lcd_clear()
{
W_CMD(0x01,1);
delay_ms(5);
}

//光标移动
void lcd_move()
{
W_CMD(0x80,1);
W_CMD(0x0f,1);
     delay_ms(100);
W_CMD(0x81,1);
W_CMD(0x0f,1);
delay_ms(100);
W_CMD(0x82,1);
W_CMD(0x0f,1);
delay_ms(100);
W_CMD(0x83,1);
W_CMD(0x0f,1);
delay_ms(100);
W_CMD(0x84,1);
W_CMD(0x0f,1);
delay_ms(100);
}
//---------------KEY  程序部分-----------------------------------
uchar key_scan()
{
    unsigned int i;
    PORTB=0x0f;
DDRB=0xf0;  //////////PB--PB3上拉输入
//延迟要足够,需要有足够的时间读取端口数据
//########################
for(i=0;i<10;i++)
{
  #asm("nop");
}
//########################
key_down=PINB;//读取端口
key_down&=0x0f;
if(key_down==0x0f)
  {
  return 0;
  }
else
  {
  return 1;
  }


}
void key_value()
{
unsigned int i;
while(key_scan());  //有按键来
delay_ms(10);
//---------可以省略
DDRB=0X00;
PORTB=0XFF;
//--------
DDRB=0x0f;
PORTB=0xf0;
//延迟要足够,需要有足够的时间读取端口数据
//###################
for(i=0;i<10;i++)
{
  #asm("nop");
}
//###################
key_row=PINB;
key_row&=0xf0;
//---------可以省略
DDRB=0X00;
PORTB=0XFF;
//------------------
if(key_row!=0xf0)   //防抖
  {
   while(!key_scan());  //按键释放
   key_row|=key_down;
   switch(key_row)
    {
    case 0xee:   //KEY1
        lcd_clear();

     break;
    case 0xde:
     lcd_move();

     break;
    case 0xbe:
     PORTA="0xbe";
     break;
    case 0x7e:
     PORTA="0x7e";
     break;
    //---------------
    case 0xed:
        PORTA=0xed;
     break;
    case 0xdd:
     PORTA="0xdd";
     break;
    case 0xbd:
     PORTA="0xbd";
     break;
    case 0x7d:
     PORTA="0x7d";
     break;
    //---------------
    case 0xeb:
        PORTA=0xeb;
     break;
    case 0xdb:
     PORTA="0xdb";
     break;
    case 0xbb:
     PORTA="0xbb";
     break;
    case 0x7b:
     PORTA="0x7b";
     break;
    //----------------
    case 0xe7:
        PORTA=0xe7;
     break;
    case 0xd7:
     PORTA="0xd7";
     break;
    case 0xb7:
     PORTA="0xb7";
     break;
    case 0x77:
     PORTA="0x77";
     break;
    }
  }
}
PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
3
关闭 站长推荐上一条 /3 下一条