(姑且让我使用这一个土得掉渣的名字)
下周的20号就是移动信息工程导论 Project 的 deadline。于是一鼓作气克服了种种困难,做出了一个贪吃蛇的小游戏。
本 Project 用到了以下模块:
- MSP-EXP430F5529LP 开发板
- 8×8 LED点阵模块,采用 MAX7219 芯片驱动
- 16路触摸感应模块,采用 TTP229 芯片
首先要了解一下 MAX7219 这个驱动芯片。此芯片可驱动最多8位的8段数码管,当然也可以驱动8×8的 LED 点阵。
上图即为本 Project 用到的点阵模块。图中有两个相同的模块。左侧的排针是输入接口,右边的排针是输出接口,可以连接下一级点阵模块做级联。排针由上至下定义为:VCC、GND、DIN、CS、CLK。右边排针与 DIN 对应的是 DOUT,连接下一级 DIN,其余与左侧定义相同。
当 CS 端口为低电平时,模块进入接收信号的状态。CLK 每置高一次接收一位由 DIN 传入的数据。每个模块每次需接收16位数据,前8位为地址位,后8位为数据位。当读取了新的数据时,旧的数据将从 DOUT 转发至下一级。
以下为模块的初始化函数:
void init_MAX7219() { /*设置输出端口*/ P6DIR |= BIT0 + BIT1 + BIT2; /*显示测试*/ WRITE_2(0x0F, 0x01); //0x0F 是测试功能的地址,0x01 表示打开测试功能 _delay_cycles(500000); //延迟0.5秒 WRITE_2(0x0F, 0x00); //关闭测试功能 /*设置为普通操作模式*/ WRITE_2(0x0C, 0x01); /*设置显示的位数*/ WRITE_2(0x0B, 0x07); //全部显示 /*设置亮度*/ WRITE_2(0x0A, 0x01); //0x01为最暗,0x0F 为最亮 /*设置译码模式*/ WRITE_2(0x09, 0x00); //0x00为不译码,0xFF 为全译码。点阵应选择不译码 int i; for (i = 1; i < 9; i++) { WRITE_2(i, 0x00); //使点阵全灭 } }
其中,WRITE_2(unsigned char add, unsigned char DATA); 函数给两个模块写入相同的数据。
地址位的部分定义如下(大写 X 表示忽略此位):
- 0xX0:无操作,即忽略数据位的内容;
- 0xX1~0xX8:第一位数码管/第一行点阵~第八位数码管/第八行点阵;
- 0xX9:设置解码模式;
- 0xXA:设置亮度;
- 0xXF:设置测试模式。
对于数据位,只要了解点阵/数码管的亮灭与二进制数据有关即可:某位为高位则点亮对应点/段。其他操作的定义可查看芯片说明书。
以下是写入数据的函数:
/*以下可根据实际连接的管脚自行定义*/ #define CS_1 P6OUT |= BIT1 #define CS_0 P6OUT &= ~BIT1 #define CLK_1 P6OUT |= BIT2 #define CLK_0 P6OUT &= ~BIT2 #define DIO_1 P6OUT |= BIT0 #define DIO_0 P6OUT &= ~BIT0 /*按位写入一个字节的数据*/ void WRITE_MAX7219_byte(unsigned char temd) { unsigned char i; for (i = 0; i < 8; i++) { CLK_0; //CLK 置低电平 if (0x80 & temd) { //若最高位为1 DIO_1; } else { //若最高位为0 DIO_0; } temd <<= 1; //左移一位 CLK_1; //CLK 置高电平 } } /*写入两组不同的数据*/ void WRITE_2D(unsigned char add1, unsigned char DATA1, unsigned char add2, unsigned char DATA2) { CS_0; //拉低电平传输数据 WRITE_MAX7219_byte(add1); WRITE_MAX7219_byte(DATA1); WRITE_MAX7219_byte(add2); WRITE_MAX7219_byte(DATA2); CS_1; //拉高电平停止传输 }
在使用时,每次给两个模块的一行写入数据。
16路感应触摸模块比较简单,当触摸按键1~8时,对应的 OUT1~8 即置高电平。一次只能有一路输出。当要用到9~16号按键时,需要参考原理图修改。
按键输入检测这一部分比较简单,只需要检测相应 IO 接口是否有高电平输入。
贪吃蛇的实现请见下篇文章。