基于ZLG7290的矩阵键盘控制,适用于MSP430,采用中断模式查询按键。ZLG7290还具有数码管显示功能,本人水平有限,这里未能实现。
/*****************************************************************
//文件名 :ZLG7290.c
//描述 :该文件定义与ZLG7290有关的各种接口、函数,适用于MSP430F149
//编写人 :小邪@清水
//版本号 :1.01
*****************************************************************/
#include "msp430x14x.h"
#include "ZLG7290.h"
/*****************************************************************
//关于接口的一些定义
//需要根据实际应用做出改变
*****************************************************************/
#define IIC_Enable !(P2IN&BIT2)
#define SCL_UP PORTDIR&=~SCL
#define SDA_UP PORTDIR&=~SDA
#define SCL_DOWN PORTDIR|=SCL
#define SDA_DOWN PORTDIR|=SDA
#define PORTDIR P3DIR //设置为P3口
#define PORTIN P3IN
#define PORTOUT P3OUT
#define SDA BIT0 //设置SDA为Px.0
#define SCL BIT1 //设置SCL为Px.1
#define RES BIT2 //设置RES为P2.7(对应430的中断)
#define CHIP 0x70 //ZLG7290的IIC地址
/*************************************************************************
//名称 : IIC_delay()
//参数 : 无
//返回值: 无
//功能 : 完成IIC设置中所需要的延时
*************************************************************************/
void IIC_delay()
{
int i;
i=0xff;
while(i)
{
i--;
_NOP();
}
i=0xff;
while(i)
{
i--;
_NOP();
}
}
/*************************************************************************
//名称 : SendToBus()
//参数 : 要发送的数据
//返回值: 无
//功能 : 向线上发送数据(SCL必须在进入函数前置为低)
*************************************************************************/
void SendToBus(BYTE m)
{
BYTE i;
for(i=0;i<8;i++)
{
if(m&0x80)
SDA_UP;
else
SDA_DOWN;
SCL_UP;
IIC_delay();
SCL_DOWN;
m<<=1;
}
return;
}
/*************************************************************************
//名称 : BackAns()
//参数 : 无
//返回值: 成功标志,若成功则为1,否则为0
//功能 : 接收应答信号
*************************************************************************/
BYTE BackAns()
{
BYTE flag;
SDA_UP;
IIC_delay();
SCL_UP;
flag=0;
IIC_delay();
if((PORTIN & SDA))
{
flag=1;
}
SCL_DOWN;
return flag;
}
/*************************************************************************
//名称 : Start()
//参数 : 无
//返回值: 无
//功能 : 发送一个起始信号
*************************************************************************/
void Start()
{
PORTOUT &= (~SCL)&(~SDA) ;
SCL_UP;
IIC_delay();
SDA_UP;
IIC_delay();
SDA_DOWN; //开始位
IIC_delay();
SCL_DOWN;
IIC_delay();
}
/*************************************************************************
//名称 : Stop()
//参数 : 无
//返回值: 无
//功能 : 发送一个停止信号
*************************************************************************/
void Stop()
{
SDA_DOWN;
IIC_delay();
SCL_UP; //停止位
IIC_delay();
SDA_UP;
IIC_delay();
SCL_DOWN;
IIC_delay();
}
/*************************************************************************
//名称 : Write_IIC_Byte()
//参数 : data-待写入的数据,startaddr-待写入的首地址
//返回值: 无
//功能 : 向线上写一个字节
*************************************************************************/
void Write_IIC_Byte(BYTE data,BYTE startaddr)
{
do
{
Start();
SendToBus(CHIP); //选片地址
if(BackAns()) //从机的回答信息
continue;
SendToBus(startaddr); //选择芯片上的内在地址
if(BackAns())
continue;
SendToBus(data); //传输数据
if(!BackAns())
break;
}
while(1);
Stop();
}
/*************************************************************************
//名称 : ReadFromBus()
//参数 : 无
//返回值: 读出的数据
//功能 : 从线上读出数据
*************************************************************************/
BYTE ReadFromBus()
{
int i,temp;
temp = 0;
SDA_UP; //读取数据之前要把SDA拉高
IIC_delay();
for(i=0;i<8;i++)
{
SCL_UP;
IIC_delay();
temp<<=1;
if(PORTIN&SDA)
temp|=0x01;
else
temp&=0xfe;
SCL_DOWN;
IIC_delay();
}
return temp;
}
/*************************************************************************
//名称 : Read_IIC_Random()
//参数 : startaddr-读数据的首地址
//返回值: 读出的数据
//功能 : 读数据到微控制器
*************************************************************************/
BYTE Read_IIC_Random(BYTE startaddr)
{
BYTE temp;
do
{
Start();
SendToBus(CHIP); //选片地址
if(BackAns()) //从机的回答信息
continue;
SendToBus(startaddr); //选择芯片上的内在地址
if(BackAns())
continue;
Start();
SendToBus(CHIP + 1);
if(!BackAns())
break;
}
while(1);
temp = ReadFromBus(); //从线上读数据
NoAck();
Stop();
return temp;
}
/*************************************************************************
//名称 : AckToBus()
//参数 : 无
//返回值: 无
//功能 : 向IIC发送应答信号
*************************************************************************/
void AckToBus()
{
SDA_DOWN;
IIC_delay();
SCL_UP;
IIC_delay();
SCL_DOWN;
IIC_delay();
}
/*************************************************************************
//名称 : NoAck()
//参数 : 无
//返回值: 无
//功能 : 向IIC发送应答信号
*************************************************************************/
void NoAck()
{
SDA_UP;
IIC_delay();
SCL_UP;
IIC_delay();
SCL_DOWN;
IIC_delay();
}
/*************************************************************************
//名称 : Write_IIC_Serious()
//参数 : data-待写数据的指针,startaddr-待写数据的起始地址,len-待写数据的长度
//返回值: 无
//功能 : 连续写多个字
*************************************************************************/
void Write_IIC_Serious(char *data,BYTE startaddr,BYTE len)
{
do
{
Start();
SendToBus(CHIP); //选片地址
if(BackAns()) //从机的回答信息
continue;
SendToBus(startaddr); //选择芯片上的内在地址
if(BackAns())
continue;
SendToBus(data[0]); //传输数据
if(BackAns())
continue;
SendToBus(data[1]);
if(!BackAns())
break;
}
while(1);
Stop();
}
/*************************************************************************
//名称 : Read_IIC_Curent()
//参数 : data-待读数据存放的指针,len-待读数据的长度
//返回值: 无
//功能 : 连续读多个字
*************************************************************************/
void Read_IIC_Curent(BYTE *data,BYTE len)
{
int i;
Start();
SendToBus(CHIP+1);
BackAns(); //放松读命令
i=1;
do
{
i++;
data[i]=ReadFromBus();
if(i<len)
AckToBus();
else
break;
}
while(1);
Stop();
}
/*************************************************************************
//名称 : init_IIC()
//参数 : 无
//返回值: 无
//功能 : 初始化I2C
*************************************************************************/
void init_IIC()
{
P2IE|=BIT7;
P2IES|=BIT7;
P2IFG&=~0x80;
_EINT();
}
/*************************************************************************
//名称 : zlg7290_cmd()
//参数 : cmd-待写入的命令
//返回值: 无
//功能 : ZLG7290纯指令发送
*************************************************************************/
void zlg7290_cmd(unsigned char cmd)
{
Write_IIC_Byte(cmd,0x07);
return;
}
/*************************************************************************
//名称 : IsKeyDown()
//参数 : 无
//返回值: 1-有键按下,0-无键按下
//功能 : ZLG7290纯指令发送
*************************************************************************/
char IsKeyDown()
{
char temp;
temp=0;
temp=Read_IIC_Random(0x00);
if(temp&0x01)
{
return 1;
}
else
{
return 0;
}
}
/*************************************************************************
//名称 : ReadKey()
//参数 : 无
//返回值: 读取的键值
//功能 : 读取键值
*************************************************************************/
char ReadKey()
{
return Read_IIC_Random(0x01);
}
/*************************************************************************
//名称 : ReadCnt()
//参数 : 无
//返回值: 连击次数
//功能 : 读取连击次数
*************************************************************************/
char ReadCnt()
{
return Read_IIC_Random(0x02);
}