基于C8051F410的矩阵键盘设计

这个也是在暑假电子设计竞赛培训时自己做的,运行结果还可以。

引脚是交叉的,因为用的是P2口,硬件设计时P2的0,2,4,6为行,1,3,5,7为纵(错了就反过来)。

因为从示例程序复制了不少东西,所以有些量是不用的,大家自己斟酌吧。


// 键盘程序,通过P2口接4*4键盘,用扫描法得键值
// 最后通过串口发送该键值。
// EDIT by lineter
// QQ:542375845


#include <c8051f410.h>                 // SFR declarations
#include <stdio.h>

#define SYSCLK      24500000           // SYSCLK frequency in Hz
#define BAUDRATE        9600           // Baud rate of UART in bps

#define keyport P2

void SYSCLK_Init (void);
void UART0_Init (void);
void PORT_Init (void);
void Timer2_Init (int);

void delay(unsigned int m);
void uart_send(unsigned char m);

unsigned char read_key(void);	//返回0xff则表示没有按键按下
void key_up(void);				//检测是否按键松开

//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------

#define UART_BUFFERSIZE 64
unsigned char UART_Buffer[UART_BUFFERSIZE];
unsigned char UART_Buffer_Size = 0;
unsigned char UART_Input_First = 0;
unsigned char UART_Output_First = 0;
unsigned char TX_Ready =1;
static char Byte;

//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------

void main (void)
{
	unsigned char key_value;
	
   PCA0MD &= ~0x40;                    // WDTE = 0 (clear watchdog timer
                                       // enable)
   PORT_Init();                        // Initialize Port I/O
   SYSCLK_Init ();                     // Initialize Oscillator
   UART0_Init();

   EA = 1;


	while(1)
	{
		key_value=read_key();
		if(key_value!=0xff)				//若有按键按下发送
		{
			key_up();
			uart_send(key_value);
		}
	}
}

void PORT_Init (void)
{
   P0MDOUT |= 0x10;                    // Enable UTX as push-pull output
   P2MDIN = 0xFF;
   P2MDOUT = 0x00;
   P2SKIP = 0xFF;
   XBR0     = 0x01;                    // Enable UART on P0.4(TX) and P0.5(RX)
   XBR1     = 0x40;                    // Enable crossbar and weak pull-ups
}

void SYSCLK_Init (void)
{
   OSCICN = 0x87;                      // configure internal oscillator for
                                       // 24.5MHz
   RSTSRC = 0x04;                      // enable missing clock detector
}

void UART0_Init (void)
{
   SCON0 = 0x10;                       // SCON0: 8-bit variable bit rate
                                       //        level of STOP bit is ignored
                                       //        RX enabled
                                       //        ninth bits are zeros
                                       //        clear RI0 and TI0 bits
   if (SYSCLK/BAUDRATE/2/256 < 1) {
      TH1 = -(SYSCLK/BAUDRATE/2);
      CKCON |=  0x08;                  // T1M = 1; SCA1:0 = xx
   } else if (SYSCLK/BAUDRATE/2/256 < 4) {
      TH1 = -(SYSCLK/BAUDRATE/2/4);
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 01
      CKCON |=  0x01;
   } else if (SYSCLK/BAUDRATE/2/256 < 12) {
      TH1 = -(SYSCLK/BAUDRATE/2/12);
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 00
   } else if (SYSCLK/BAUDRATE/2/256 < 48) {
      TH1 = -(SYSCLK/BAUDRATE/2/48);
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 10
      CKCON |=  0x02;
   } else {
      while (1);                       // Error.  Unsupported baud rate
   }

   TL1 = TH1;                          // init Timer1
   TMOD &= ~0xf0;                      // TMOD: timer 1 in 8-bit autoreload
   TMOD |=  0x20;
   TR1 = 1;                            // START Timer1
   TX_Ready = 1;                       // Flag showing that UART can transmit
   IP |= 0x10;                         // Make UART high priority
   ES0 = 1;                            // Enable UART0 interrupts
}

void UART0_Interrupt (void) interrupt 4
{
	if (TI0 == 1)                   // Check if transmit flag is set
	{
		TI0 = 0;                           // Clear interrupt flag
	}
}

void delay(unsigned int m)
{
	while(m--);
}
//
// 行列对应P2口的偶数位和奇数位,通过反转法得键值。
// 对应返回值为00~0f,若返回0xff则无按键按下。
// 注,若有按键按下,则必须立刻调用key_up()函数等待按键松开。
/
unsigned char read_key(void)
{
	unsigned char p,q;
	unsigned char tmp1,tmp2;
	P2MDOUT = ~0x55;
	keyport=0x55;
	p=keyport;
	if(p!=0x55)
	{
		delay(10000);
		P2MDOUT = ~0x55;
		keyport=0x55;
		delay(100);
		p=keyport;
			if (p == 0x55)
				return 0xff;
		P2MDOUT = ~0xaa;
		keyport=0xaa;
		delay(100);
		q=keyport;
			if (q == 0xaa)
				return 0xff;
		P2MDOUT = 0x00;
		
		tmp1=0;
		tmp2=0;
		while(q%4)
		{
			tmp1++;
			q/=4;
		}
		while(p%4)
		{
			tmp2++;
			p/=4;
		}
		return tmp1+tmp2*4;
	}
	return 0xff;
}

void key_up(void)
{
	unsigned char p;
	keyport=0x55;
	p=keyport;
	while(p!=0x55)
	{
		p=keyport;
	}
	delay(10000);
}

void uart_send(unsigned char m)
{
	while(TI0==1);
	SBUF0=m;
}








  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值