在线时间613 小时
UID252169
注册时间2010-12-5
NXP金币0
TA的每日心情 | 开心 2019-2-14 16:49 |
---|
签到天数: 296 天 连续签到: 1 天 [LV.8]以坛为家I
金牌会员
 
- 积分
- 4473
- 最后登录
- 2020-4-14
|
本帖最后由 zhjb1 于 2019-3-28 16:42 编辑
此文已改,数据和照片都准确了。
为了测试键盘I2C,先测试中断口,查图为P2_12是中断,因此定义中断对象:
InterruptIn i2c40(P2_12);//键盘中断
定义一个中断函数为控制LED乒乓亮暗,延时10mS:
void i2c40Int(void){wait(0.01);if(P2_12)led=!led;}//i2c40 Interupt fuction
定义中断模式和触发方式:
i2c40.mode(PullUp);
i2c40.rise(&i2c40Int);
这两句在循环外,因为是中断,所以循环函数中没有有关I2C40的语句。
开始先看手册PCA9555D。这个手册看起来颇有点难度,不过化简后主要就是图表0_90。这个表中表明了命令寄存器的控制方式,以后的实验都是针对这8个寄存器进行。模块试验在mbed下可能较为简单。
按照此芯片为内部PORT0用作键盘输入端,PORT1作为键盘输出端,连着之间的电平为1表示对应的按键按下。键盘共有27个按键,6x6的IO卡片足够用了。看手册,好像芯片的寄存器都是独立的,只需要初始化设置寄存器6,7就可以了。因为6和7的高2位分别控制了LED,所以寄存器6是高位输出,低6为输入,寄存器7全部为输出。setI2c40()函数:
//Intial Temp
void setI2c40(void){
char kTemp[2];
kTemp[0]=0x06;
kTemp[1]=0x3F;
i2c.write(taddr[3],kTemp,2,true);
kTemp[0]=0x07;
kTemp[1]=0x00;
i2c.write(taddr[3],kTemp,2,true);
}
这个不是主要问题,首先来测试Keyboard上的3个LED,按照键盘原理图,可以看到当PORT0高2位输出,并且低电平是红黄LED点亮,而PORT1高1位低电平,绿LED点亮。
先定义一个整形变量和数组:
int kl,kled[]={0x7F,0xBF,0xFF,0x7F,0xFF};
下边是测试3个LED的代码,void testKled(int kl):
//Test Keyboard LED
void testKled(int kl){
char data[2];
if(kl<3){
data[0]=0x03;//Set Addr
data[1]=kled[kl];//
i2c.write(taddr[3],data,2,true);
}else{
data[0]=0x02;//Set Addr
data[1]=kled[kl];//
i2c.write(taddr[3],data,2,true);
}
}
在主函数中加入:
int i=0;
在循环函数中加入以下函数:
if(i<4){i++;}else{i=0;}
testKled(i);
调用这个函数即可,结果见照片0_91。在程序中设置了按键中断检测,驱动乒乓LED闪亮,没有任何问题。
按照键盘原理图IRD KeypadSchematics.pdf,如果是无源的,那么可以扫描键盘实现按键判别:
假设,PORT0的0~5为输入端,PORT1的0~5为输出端,轮流输出为高电平,扫面PORT0接收到高电平对应的引脚就可以知道按键值了。这只是按照原理图的设想,需要实践检测是否思路合理。
下边测试键盘,按照PORT0低6为位为输入,PORT1低6位为输出,构成键盘。为了完成扫描按键,需要将PORT1逐位设高,测试PORT0的哪一位拉高了就可以了。想想是这样,设置代码来试试。大致思路:
先设置PORT1_n[n=0~5],为高电平,而后检测PORT0的输入信号,那个为高,没有,n+1;重复测试直到n=5,完成一轮。如果检测到有高电平,则将PORT1的数值和PORT0的数值送LCD显示。按键检测可以走中断方式,因为案件中断信号有效。
看寄存器表,这个操作应该比较简单:每改变一个PORT1_n的值——寄存器3的0~5位输出一个高电平,延时,测试PORT0输入——寄存器0的值有无高。先关掉keyLed函数。
首先增加一个关闭按键函数——按键没有松开,此变量为固定值,松开后还原:
koff=1;
为1是,表示按键开放,为0时,等待按键松开。此变量由按键中断函数控制。此函数仅仅记录PORT1输出的值[1,2,4,8,16,32]
//i2c40 Interupt fuction
void i2c40Int(void){
wait(0.05);
if(P2_12){
tempT[0]=kl&0x3f;
led=!led;
koff=1;
}
}
键盘测试函数testI2c40():
//Test Keyboard I2C40
void testI2c40(int kCol){
char data[2];
data[0]=0x03;//Set Addr
data[1]=0xC0 || kCol;
i2c.write(taddr[3],data,1,true);
i2c.write(taddr[3],data,2,true);
data[0]=0x00;//Set Addr
i2c.write(taddr[3],data,1,true);
//wait(0.00001);
i2c.read(taddr[3]+1,data,2,rd);
tempT[1]=data[0]&0x3F;
koff=1;
}
循环函数中增加:
if(koff){
testI2c40(kl);
if(kl<0x20){kl=kl<<1;}else{kl=0x01;}
}
结果还不错,测试照片见0_92~0_95。
需要讨论的问题是,在向PORT1中输出的是从0x01,0x02,0x04,0x08,0x10,0x20循环数,按道理读出PORT0输入的按键值是对应的为1的值,但实际得到的结果是十进制的:31,47,55,59,61,62这六个值,默认为63。换成二进制为:0x1F,0x2F,0x37,0x3B,0x3E,无按键为0x3F。按键是将对应按键的键值拉低,由于这个数值是正确的,按键关系可以得到,也可以区分按键的不同了,直接自己定义就可以了。其中还有两个按键的值很有意思:键盘上menu和F4的那2个键,按下时,列扫的数值锁不住,一直在变,在从0x01~0x20变化。可以查看后来江苏局导出到串口的截图0_96。照片0_97是将测温小数部分加到芯片上显示到LCD和输出到串口。稳定后看来测温还是较准的,基本不变。采用哈气的方法,可以看到最小的变化为0.125度。
至此基础测试已经完成。所有测试都是看手册,写函数逐步测试成功的。
当然,在I2C的地址的错误是借鉴了网友的文章,改过来才成功的,在此一并致谢。
实际上还有一个读取串口ROM的玩意,省略了。
|
-
0_90
-
0_91
-
0_92
-
0_93
-
0_94
-
0_95
-
0_96
-
0_97
|