搜索
bottom↓
回复: 6

关于贴片4x4键盘液晶输入

[复制链接]

出0入0汤圆

发表于 2012-8-26 16:11:34 | 显示全部楼层 |阅读模式
     我写的程序向液晶写数字,键盘第一列反应很好,按一下就显示,但是其他列要按好几次才可能显示出来      大神帮忙看看原因




               



#include <c8051f020.h>                 // SFR declarations
#include <intrins.h>
#include <stdio.h>

#define uchar unsigned char         
#define uint  unsigned int

#define Lcd_Bus    P5
#define ScanKeyPort P2

#define SYSCLK       22118400          // SYSCLK frequency in Hz
#define INT_DEC      256               // integrate and decimate ratio
#define _Nop() _nop_()
//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F02x
//-----------------------------------------------------------------------------

sfr16 DP       = 0x82;                 // data pointer
sfr16 TMR3RL   = 0x92;                 // Timer3 reload value
sfr16 TMR3     = 0x94;                 // Timer3 counter
sfr16 ADC0     = 0xbe;                 // ADC0 data
sfr16 ADC0GT   = 0xc4;                 // ADC0 greater than window
sfr16 ADC0LT   = 0xc6;                 // ADC0 less than window
sfr16 RCAP2    = 0xca;                 // Timer2 capture/reload
sfr16 T2       = 0xcc;                 // Timer2
sfr16 RCAP4    = 0xe4;                 // Timer4 capture/reload
sfr16 T4       = 0xf4;                 // Timer4
sfr16 DAC0     = 0xd2;                 // DAC0 data
sfr16 DAC1     = 0xd5;                 // DAC1 data

unsigned char keydata;
unsigned char keyvalue;
//--------------------------------------------------------------------
// 延时
//--------------------------------------------------------------------


void delay(unsigned int t)
{    unsigned int k,j;
     for(k=0;k<t;k++)
     for(j=0;j<10;j++) ;
}


//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------


//--------------------------------------------------------------------
// 按键扫描
//
//--------------------------------------------------------------------
unsigned char key_in(void)
{
    uchar keytemp,scancode,tmpcode;
        ScanKeyPort=0xf0;
    keytemp=ScanKeyPort;
    if ((keytemp&0xf0)^0xf0)
                {
        //        delay(50);       
                keytemp=ScanKeyPort;
                if ((keytemp&0xf0)^0xf0)
                        {
                         scancode = 0xfe;
                             while((scancode&0x10)!=0) // 逐行扫描
                                   {
                            ScanKeyPort= scancode;         // 输出行扫描码
                            if ((ScanKeyPort&0xf0)!=0xf0)   // 本行有键按下
                                    {
                                     tmpcode = (ScanKeyPort&0xf0)|0x0f;                            
                                     return((~scancode)+(~tmpcode));        /* 返回特征字节码,为1的位即对应于行和列 */
                                    }
                            else
                                        {
                                        scancode = (scancode<<1)|0x01;  // 行扫描码左移一位
                                        }                               
                                   }
                        }
                }
        return(0);//返回0,表示没有按键按xia
        }

//-----------------------------------------------------------------------------
// 液晶接口定义
//-----------------------------------------------------------------------------

//#define LEDCTL0Low  P4&=~0x01;
//#define LEDCTL0High P4|=0x01;

#define LCDELow   P4&=~0x02;
#define LCDEHigh P4|=0x02;

#define LCDRWLow  P4&=~0x04;
#define LCDRWHigh P4|=0x04;

#define LCDRSLow  P4&=~0x08;
#define LCDRSHigh P4|=0x08;

#define LCDPSBLow  P4&=~0x10;
#define LCDPSBHigh P4|=0x10;
//==============================//
uchar num;
uint delay_time;
/*-----------------------------------------------------*/

void SYSCLK_Init (void);
void PORT_Init (void);




//-----------------------------------------------------------------------------
// 液晶显示写命令
//-----------------------------------------------------------------------------
void write_com(unsigned char cmdcode)
{
        LCDRSLow;                    
        LCDRWLow;
        LCDEHigh;
        Lcd_Bus=cmdcode;
        delay(50);delay(60);                           //在数据写入的时候加入适当的延时
        LCDELow;
        delay(50);delay(60);
}
//-----------------------------------------------------------------------------
// 液晶显示写数据
//-----------------------------------------------------------------------------
void write_data(unsigned char Dispdata)
{
        LCDRSHigh;
        LCDRWLow;
        LCDEHigh;
        Lcd_Bus=Dispdata;
        delay(50);delay(60);                            // 在数据写入的时候加入适当的延时
        LCDELow;
        delay(50);delay(60);
}
//-----------------------------------------------------------------------------
// 液晶显示,复位初始
//-----------------------------------------------------------------------------
void lcdreset()
{
     delay(200);delay(250);
     write_com(0x30);
     delay(100);delay(250);                           //选择基本指令集
     write_com(0x30);                     //选择8bit数据流
     delay(50);delay(250);
     write_com(0x0c);                     //开显示(无游标、不反白)
     delay(50);delay(250);
     write_com(0x01);                       //清除显示,并且设定地址指针为00H
     delay(50);delay(250);
     write_com(0x06);                      //指定在资料的读取及写入时,设定游标的移动方向及指定显示的移位

}
//-----------------------------------------------------------------------------
// 液晶显示
//-----------------------------------------------------------------------------
void display(unsigned char code *s)
{
      while(*s>0)
      {  write_data(*s);
         s++;
         delay(50);delay(100);
      }
}
//-----------------------------------------------------------------------------
// 液晶显示内容
//-----------------------------------------------------------------------------

void zero_screen()
{  uint a;
        a=0x30;
  write_com(0x30);
  delay(10000);
write_com(0x80);
write_data(a+keyvalue);

}
//-----------------------------------------------------------------------------
// 通用I/O口及交叉开关初始化
//-----------------------------------------------------------------------------
void PORT_Init (void)
{            
  XBR2     = 0x40;               // 交叉开关使能  
  P2MDOUT=0x00;
  P74OUT=0xff;                                         
}
//-----------------------------------------------------------------------------
// 系统时钟初始化
//-----------------------------------------------------------------------------

/*
void SYSCLK_Init()
{   
  OSCICN =0x87; //使用内部时钟16M
  while((OSCICN & 0x10)==0);//内部时钟按设定频率运行
}
*/
// 配置系统时钟使用外部晶振11.0592MHz

void SYSCLK_Init (void)
{
   int i;                              // delay counter

   OSCXCN = 0x67;                      // start external oscillator with
                                       // 22.1184MHz crystal
   for (i=0; i < 256; i++) ;           // XTLVLD blanking interval (>1ms)

   while (!(OSCXCN & 0x80)) ;          // Wait for crystal osc. to settle

   OSCICN = 0x88;                      // select external oscillator as SYSCLK
                                       // source and enable missing clock
                                       // detector
}

//-----------------------------------------------------------------------------
// 系统初始化
//-----------------------------------------------------------------------------
void init()
{
   SYSCLK_Init();
   PORT_Init ();
   lcdreset();
   zero_screen();   
}
//-----------------------------------------------------------------------------
// 主程序
//-----------------------------------------------------------------------------

void main()
{

  WDTCN = 0xde;
  WDTCN = 0xad;                //禁止看门狗定时器  

  SYSCLK_Init ();       
           PORT_Init();
          init();       
    //SFRPAGE = LEGACY_PAGE;
        while(1)
        {        
        keydata=key_in();                                                //读按键
                if(keydata!=0)                                                //有按键按下,显示对应的按键
                {
                 switch(keydata)
                         {
                         case 0x14: keyvalue=0;break;
                         case 0x88: keyvalue=1;break;
                         case 0x84: keyvalue=2;break;

                         case 0x82: keyvalue=3;break;
                         case 0x48: keyvalue=4;break;
                         case 0x44: keyvalue=5;break;

                         case 0x42: keyvalue=6;break;
                         case 0x28: keyvalue=7;break;
                         case 0x24: keyvalue=8;break;

                         case 0x22: keyvalue=9;break;
                         //case 0x14: keyvalue=10;break;
                         //case 0x48: keyvalue=11;break;
                                }
  zero_screen();

}
}
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

 楼主| 发表于 2012-8-26 16:18:11 | 显示全部楼层
大神速度出现啊     帮忙看看啊

出0入0汤圆

 楼主| 发表于 2012-8-26 16:49:06 | 显示全部楼层
好吧   大神持续的繁忙.............

出0入0汤圆

发表于 2012-8-27 10:32:48 来自手机 | 显示全部楼层
你这读按键没去抖吗?

出0入0汤圆

发表于 2012-8-27 11:03:44 | 显示全部楼层
    if ((keytemp&0xf0)^0xf0)
                {
        // (这)       delay(50);        
                keytemp=ScanKeyPort;
                if ((keytemp&0xf0)^0xf0)
我也觉得是去抖的问题,把//去了, 试试呗。


就是反应慢,应该也不用按好几下吧,按住 过会就显示了吧

出0入0汤圆

发表于 2013-5-30 11:29:15 | 显示全部楼层
不错, 回头试试看

出0入0汤圆

发表于 2013-5-31 15:54:41 | 显示全部楼层
mark mark
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 12:22

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表