MAX7359智能按键管理芯片编程

MAX7349和MAX7359均可管理多达64个按键,采用Maxim专有的低电压、低EMI静态按键扫描技术,并将去抖后的扫描结果编成键值,依据按键的键序将键值消息存放在FIFO中,手机处理器在适当的时候读取FIFO中的键值消息,即使处理器没有及时处理按键事件,按键消息也不会丢失,这对通常采用非实时操作系统的智能手机来说非常重要。与MAX7349相比,MAX7359增加了按键释放检测功能,即每次按下和释放按键都会生成一个键值消息,可更简便实现多键同时输入及组合键功能。另外,该系列器件优化了控制寄存器并增加存储键值消息的FIFO空间,即由MAX7349的存储8次按键增加到存储16次按键。

  MAX7359还具有自动休眠和自动唤醒功能,以使器件的功耗最低。一个休眠周期后,自动休眠功能将器件置于低功耗状态(典型值1μA)。发生按键事件时,自动唤醒功能设置MAX7359返回至正常工作模式。

FIFO消息的处理  处理读到的FIFO字节变量(假设变量名为:FIFO_BYTE)后,软件处理方法如下:  (1)将从FIFO收到的非0x3f的字节变量FIFO_BYTE和0x3f取与(AND 0x3f),结果值为按键值(即0至63号键中某一个被按下或释放)。  (2)再将该FIFO_BYTE和0x40取与(AND 0x40),结果为0则说明按键被按下,结果非0则说明按键被释放。如果硬件布线时使用了63号和62号键,FIFO_BYTE处理复杂,请软件设计工程师参考MAX7359编程指南的62号和63号键处理方法。  (3)通常需要起一个定时器,定时检查还未收到键盘释放信息的键盘按下信息都是何时发生的,如果是当前时间减去按键按下的时间满足长按键时间,就可向上层软件发长按键消息。

//max7359.h
#ifndef _MAX7359_H_
#define _MAX7359_H_

#include "stm32f10x.h"

//max7359寄存器

#define     MAX7359_KEYS_FIFO_REG         0x00          //上电默认为0x3F
#define     MAX7359_CONFIGURATION_REG     0x01 		//上电默认为0x0A
#define     MAX7359_DEBOUNCE_REG          0x02 		//上电默认为0xFF
#define     MAX7359_INTERRUPT_REG         0x03  	//上电默认为0x00		
#define     MAX7359_PORTS_REG             0x04 		//上电默认为0xFE
#define     MAX7359_KEY_REPEAT_REG        0x05 		//上电默认为0x00
#define     MAX7359_SLEEP_REG             0x06 		//上电默认为0x07

//MAX7359读取结束键值
#define ENDofKEYNUM 63

//功能键宏定义

#define  KEY_UP        16  //上
#define  KEY_DOWN      17  //下
#define  KEY_LEFT      18  //左
#define  KEY_RIGHT     19  //右
#define  KEY_CERTAIN   24  //确定
#define  KEY_QUIT      25  //退出、删除


char KeyScan(void);
void MAX7359Init(void);
void ReadMAX7359(u8 *pBuffer);

#endif  //_MAX7359_H_

//max7359.c
#include "MAX7359.h"
#include "i2c_ee.h"
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "stdio.h"

char bKeyFlag=0;

void MAX7359Init()
{
		u8   MAX7359_CONFIGURATION_REG_Data=0x83; 
		u8   MAX7359_DEBOUNCE_REG_Data=0x0b;   
		u8   MAX7359_INTERRUPT_REG_Data=0x01; 
		u8   MAX7359_PORTS_REG_Data=0x40;          
		u8   MAX7359_KEY_REPEAT_REG_Data=0x0;
		u8   MAX7359_SLEEP_REG_Data=0x03;  
	
		GPIO_InitTypeDef GPIO_InitStructure;
		EXTI_InitTypeDef EXTI_InitStructure;
		NVIC_InitTypeDef NVIC_InitStructure;


		I2C_EE_ByteWrite(&MAX7359_DEBOUNCE_REG_Data,MAX7359_DEBOUNCE_REG); 
		//I2C_EE_ByteWrite((u8**)(0x4f),MAX7359_DEBOUNCE_REG);
		I2C_EE_ByteWrite(&MAX7359_INTERRUPT_REG_Data,MAX7359_INTERRUPT_REG);
		I2C_EE_ByteWrite(&MAX7359_PORTS_REG_Data,MAX7359_PORTS_REG);
		I2C_EE_ByteWrite(&MAX7359_KEY_REPEAT_REG_Data,MAX7359_KEY_REPEAT_REG);
		I2C_EE_ByteWrite(&MAX7359_SLEEP_REG_Data,MAX7359_SLEEP_REG);
		I2C_EE_ByteWrite(&MAX7359_CONFIGURATION_REG_Data,MAX7359_CONFIGURATION_REG);
	
	  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);
//----PA2作为外部中断线2输入时,一定要配置为上拉输入模式、或者浮动输入模式、下拉输入模式 
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;				     //指定要以下边参数设置PA2,
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//GPIO_Mode_IN_FLOATING:引脚浮动输入模式、GPIO_Mode_IPU引脚上拉输入模式;GPIO_Mode_IPD引脚下拉输入模式
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;						 //引脚允许的最大频率是50MHZ
		GPIO_Init(GPIOA, &GPIO_InitStructure);
		//--将PA2配置成外部中断2输入,外部中断信号在上升沿相应中断 --//
		GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource2);//将PA2与外中断线2连接起来						    
		EXTI_InitStructure.EXTI_Line = EXTI_Line2;  				//所设置的外中断信号线的选择(0~15)
		EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  		//选择触发中断模式,还是事件模式
		EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//EXTI_Trigger_Rising;  	//外中断触发方式					 
		EXTI_InitStructure.EXTI_LineCmd = ENABLE;  				//使能外中断
		EXTI_Init(&EXTI_InitStructure); 
		
		NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;			//使能按键所在的外部中断通道
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	//抢占优先级2 
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;					//子优先级2 
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;								//使能外部中断通道
  	NVIC_Init(&NVIC_InitStructure);  	  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
}

void ReadMAX7359(u8 *pBuffer) //测试时一般读出来是两个字节;第二个字节舍弃
{
		int i;
		for(i=0;;i++)
		{
			I2C_EE_BufferRead(&pBuffer[i], MAX7359_KEYS_FIFO_REG, 1);
			//pBuffer[i]&=0x3f;
			if(pBuffer[i]==ENDofKEYNUM) break;//ENDofKEYNUM=63,0x3f
		}
}

void EXTI2_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line2) != RESET)	  //检查指定的EXTI0线路触发请求发生与否
	{	  
		LED0=!LED0;
		LED1=!LED1;	
		TIM3->CNT=0;
		TIM_Cmd(TIM3, ENABLE);  //使能TIMx外设
		printf("%c",KeyScan());
		if(++bKeyFlag>=4) bKeyFlag=0;
	}
	EXTI_ClearITPendingBit(EXTI_Line2);  //清除EXTI0线路挂起位
}

char KeyScan()
{
	int i=0;
	u8 cKeyData=0;
	u8 rKeyBuffer[2]={0};
	const u8 FunKeyData[6]={16,17,18,19,24,25};//功能键值数组
	static vu8 OldKeyData=0x3f;
	ReadMAX7359(rKeyBuffer);
	//先判断功能键
	for(i=0;i<6;i++)
	{
		if(FunKeyData[i]==rKeyBuffer[0]) {OldKeyData=0x3f; return FunKeyData[i];}
	}
	if(0==bKeyFlag)
	{
		switch(rKeyBuffer[0])
		{
			case 0: 			cKeyData='0'; break;
			case 1:				cKeyData='1'; break;
			case 2:				cKeyData='2'; break;
			case 3:				cKeyData='3'; break;
			case 4:				cKeyData='4'; break;
			case 8:				cKeyData='5'; break;
			case 9:				cKeyData='6'; break;
			case 10:			cKeyData='7'; break;
			case 11:			cKeyData='8'; break;
			case 12:			cKeyData='9'; break;
			case 26:			cKeyData='.'; break;
			case 27:			cKeyData='+';	break;
			default:      break;
		}

	}
	if(1==bKeyFlag)
	{
		switch(rKeyBuffer[0])
		{
			case 0: 			cKeyData=' '; break;
			case 1:				cKeyData='q'; break;
			case 2:				cKeyData='a'; break;
			case 3:				cKeyData='d'; break;
			case 4:				cKeyData='g'; break;
			case 8:				cKeyData='j'; break;
			case 9:				cKeyData='m'; break;
			case 10:			cKeyData='p'; break;
			case 11:			cKeyData='t'; break;
			case 12:			cKeyData='w'; break;
			case 26:			cKeyData='.'; break;
			case 27:			cKeyData='-';	break;
			default:      break;
		}

	}
		
	if(2==bKeyFlag)
	{
		switch(rKeyBuffer[0])
		{
			case 0: 			cKeyData='0'; break;
			case 1:				cKeyData='z'; break;
			case 2:				cKeyData='b'; break;
			case 3:				cKeyData='e'; break;
			case 4:				cKeyData='h'; break;
			case 8:				cKeyData='k'; break;
			case 9:				cKeyData='n'; break;
			case 10:			cKeyData='r'; break;
			case 11:			cKeyData='u'; break;
			case 12:			cKeyData='x'; break;
			case 26:			cKeyData='.'; break;
			case 27:			cKeyData='+';	break;
			default:      break;
		}

	}
		
	if(3==bKeyFlag)
	{
		switch(rKeyBuffer[0])
		{
			case 0: 			cKeyData=' '; break;
			case 1:				cKeyData=','; break;
			case 2:				cKeyData='c'; break;
			case 3:				cKeyData='f'; break;
			case 4:				cKeyData='i'; break;
			case 8:				cKeyData='l'; break;
			case 9:				cKeyData='o'; break;
			case 10:			cKeyData='s'; break;
			case 11:			cKeyData='v'; break;
			case 12:			cKeyData='y'; break;
			case 26:			cKeyData='.'; break;
			case 27:			cKeyData='-';	break;
			default:      break;
		}

	}
	OldKeyData=rKeyBuffer[0];
	return cKeyData;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值