PIC矩阵键盘学习

该程序功能上还有一定的缺陷,带晚上,初步实现功能

 

代码
 
   
// 待完善
#include < pic.h >
#include
" ../head/config.h "

__CONFIG(HS
& WDTDIS & LVPDIS & PWRTEN); // 对熔丝位进行设置

// 单片机LED共阳极段码表(带小数点) 0~9
const char table1[] = { 0X0A , 0XFA , 0X8C , 0XA8 , 0X78 , 0X29 , 0X09 , 0XBA , 0X08 , 0X28 , 0x18 , 0x49 , 0x0f , 0xc8 , 0x0d , 0x1d };
// 数码管位码表
const char table[] = { 0x01 , 0x02 , 0x04 , 0x08 , 0x10 , 0x20 , 0x40 , 0x80 };

unsigned
int result = 0 ,lastresult = 0 ;
uchar data_temp
= 0 ;
void delay( void ); // delay函数申明
void init( void ); // I/O口初始化函数申明
void scan( void ); // 按键扫描程序申明
void display( void ); // 显示函数申明
void SPI_tx(uchar spi_data);
// ---------------------------------------------------
// 主程序
void main( void )
{
init();
// 调用初始化子程序

while ( 1 ) // 循环工作
{

scan();
// 调用按键扫描子程序
display(); // 调用结果显示子程序

}
}

// ---------------------------------------------------
// 初始化函数
void init()
{
PIR1
= 0x00 ; // SSPIF=0;没有中断发生
SSPCON = 0x30 ; // 主控方式,Fosc/4,CKP=1空闲时钟电平为高,SSPEN=1使能同步串行功能
SSPSTAT = 0xC0 ; // SMP=1 时序信号末尾采样输入数据,CKE=1时序信号上升沿发送数据
TRISC = 0x00 ; // SDO引脚为输出,SCK引脚为输输出,SDI引脚输出
TRISD = 0XF0 ; // 设置D口高4位为输入,低4位为输出,按键扫描

}

void SPI_tx(uchar spi_data)
{
SSPBUF
= spi_data;
do
{
;
}
while ( ! SSPIF); // 等待产生SSP中断,等待发送完成
SSPIF = 0 ;
data_temp
= SSPBUF; // 将接受到的数据放在变量中
}

// ---------------------------------------------------
// 按键扫描程序
void scan()
{
PORTD
= 0XF7 ; // C3输出低电平,其他三位输出高电平
asm( " nop " ); // 插入一定延时,确保电平稳定
result = PORTD; // 读回C口高4位结果
result = result & 0xf0 ; // 清除低4位
if (result != 0xf0 ) // 判断高4位是否为全1(全1代表没按键按下)?
{
result
= result | 0x07 ; // 否,加上低4位0x07,做为按键扫描的结果
}
else // 是,改变低4位输出,重新判断是否有按键按下
{
PORTD
= 0XFb ; // C2输出低电平,其他三位输出高电平
asm( " nop " ); // 插入一定延时,确保电平稳定
result = PORTD; // 读回C口高4位结果
result = result & 0xf0 ; // 清除低4位
if (result != 0xf0 ) // 判断高4位是否为全1(全1代表没按键按下)
{
result
= result | 0x0b ; // 否,加上低4位0xb,做为按键扫描的结果
}
else // 是,改变低4位输出,重新扫描
{
PORTD
= 0XFd ; // C1输出低电平,其他三位输出高电平
asm( " nop " ); // 插入一定延时,确保电平稳定
result = PORTD; // 读回C口高4位结果
result = result & 0xf0 ; // 清除低4位
if (result != 0xf0 ) // 判断高4位是否为全1(全1代表没按键按下)
{
result
= result | 0x0d ; // 否,加上低4位0x0d,做为按键扫描的结果
}
else // 是,改变低4位的输出,重新扫描
{
PORTD
= 0XFe ; // C0输出低电平,其他三位输出高电平
asm( " nop " ); // 插入一定延时,确保电平稳定
result = PORTD; // 读回C口高4位结果
result = result & 0xf0 ; // 清除低4位
if (result != 0xf0 ) // 判断高四位是否为全1(全1代表没有按键按下)
{
result
= result | 0x0e ; // 否,加上低4位0x0e,做为按键扫描的结果
}
else // 是,全部按键扫描结束,没有按键按下,置无按键按下标志位
{
result
= lastresult; // 扫描结果为0xff,做为没有按键按下的标志
}
}
}
}
lastresult
= result;
}

// ----------------------------------------------------------
// 显示程序
void display()
{
switch (result)
{
case 0xe7 :
RC4
= 0 ;SPI_tx(table[ 0 ]);SPI_tx(table1[ 0 ]);RC4 = 1 ;delay();RC4 = 0 ;SPI_tx(table[ 1 ]);SPI_tx(table1[ 0 ]);RC4 = 1 ;delay(); break ; // K10
case 0xeb :
RC4
= 0 ;SPI_tx(table[ 0 ]);SPI_tx(table1[ 0 ]);RC4 = 1 ;delay();RC4 = 0 ;SPI_tx(table[ 1 ]);SPI_tx(table1[ 1 ]);RC4 = 1 ;delay(); break ; // K11
case 0xed :
RC4
= 0 ;SPI_tx(table[ 0 ]);SPI_tx(table1[ 0 ]);RC4 = 1 ;delay();RC4 = 0 ;SPI_tx(table[ 1 ]);SPI_tx(table1[ 2 ]);RC4 = 1 ;delay(); break ; // K12
case 0xee :
RC4
= 0 ;SPI_tx(table[ 0 ]);SPI_tx(table1[ 0 ]);RC4 = 1 ;delay();RC4 = 0 ;SPI_tx(table[ 1 ]);SPI_tx(table1[ 3 ]);RC4 = 1 ;delay(); break ; // K13
case 0xd7 :
RC4
= 0 ;SPI_tx(table[ 0 ]);SPI_tx(table1[ 0 ]);RC4 = 1 ;delay();RC4 = 0 ;SPI_tx(table[ 1 ]);SPI_tx(table1[ 4 ]);RC4 = 1 ;delay(); break ; // K14
case 0xdb :
RC4
= 0 ;SPI_tx(table[ 0 ]);SPI_tx(table1[ 0 ]);RC4 = 1 ;delay();RC4 = 0 ;SPI_tx(table[ 1 ]);SPI_tx(table1[ 5 ]);RC4 = 1 ;delay(); break ; // K15
case 0xdd :
RC4
= 0 ;SPI_tx(table[ 0 ]);SPI_tx(table1[ 0 ]);RC4 = 1 ;delay();RC4 = 0 ;SPI_tx(table[ 1 ]);SPI_tx(table1[ 6 ]);RC4 = 1 ;delay(); break ; // K16
case 0xde :
RC4
= 0 ;SPI_tx(table[ 0 ]);SPI_tx(table1[ 0 ]);RC4 = 1 ;delay();RC4 = 0 ;SPI_tx(table[ 1 ]);SPI_tx(table1[ 7 ]);RC4 = 1 ;delay(); break ; // K17
case 0xb7 :
RC4
= 0 ;SPI_tx(table[ 0 ]);SPI_tx(table1[ 0 ]);RC4 = 1 ;delay();RC4 = 0 ;SPI_tx(table[ 1 ]);SPI_tx(table1[ 8 ]);RC4 = 1 ;delay(); break ; // K18
case 0xbb :
RC4
= 0 ;SPI_tx(table[ 0 ]);SPI_tx(table1[ 0 ]);RC4 = 1 ;delay();RC4 = 0 ;SPI_tx(table[ 1 ]);SPI_tx(table1[ 9 ]);RC4 = 1 ;delay(); break ; // K19
case 0xbd :
RC4
= 0 ;SPI_tx(table[ 0 ]);SPI_tx(table1[ 1 ]);RC4 = 1 ;delay();RC4 = 0 ;SPI_tx(table[ 1 ]);SPI_tx(table1[ 0 ]);RC4 = 1 ;delay(); break ; // K20
case 0xbe :
RC4
= 0 ;SPI_tx(table[ 0 ]);SPI_tx(table1[ 1 ]);RC4 = 1 ;delay();RC4 = 0 ;SPI_tx(table[ 1 ]);SPI_tx(table1[ 1 ]);RC4 = 1 ;delay(); break ; // K21
case 0x77 :
RC4
= 0 ;SPI_tx(table[ 0 ]);SPI_tx(table1[ 1 ]);RC4 = 1 ;delay();RC4 = 0 ;SPI_tx(table[ 1 ]);SPI_tx(table1[ 2 ]);RC4 = 1 ;delay(); break ; // K22
case 0x7b :
RC4
= 0 ;SPI_tx(table[ 0 ]);SPI_tx(table1[ 1 ]);RC4 = 1 ;delay();RC4 = 0 ;SPI_tx(table[ 1 ]);SPI_tx(table1[ 3 ]);RC4 = 1 ;delay(); break ; // K23
case 0x7d :
RC4
= 0 ;SPI_tx(table[ 0 ]);SPI_tx(table1[ 1 ]);RC4 = 1 ;delay();RC4 = 0 ;SPI_tx(table[ 1 ]);SPI_tx(table1[ 4 ]);RC4 = 1 ;delay(); break ; // K24
case 0x7e :
RC4
= 0 ;SPI_tx(table[ 0 ]);SPI_tx(table1[ 1 ]);RC4 = 1 ;delay();RC4 = 0 ;SPI_tx(table[ 1 ]);SPI_tx(table1[ 5 ]);RC4 = 1 ;delay(); break ; // K25
// case 0xff:
// RC4=0;SPI_tx(table[0]);SPI_tx(table1[15]);RC4=1;delay();RC4=0;SPI_tx(table[1]);SPI_tx(table1[15]);RC4=1;delay(); // 无按键按下
}
}

// ------------------------------------------------------------------
// 延时程序
void delay() // 延时程序
{
unsigned
int i; // 定义整形变量
for (i = 0x100 ;i -- ;); // 延时
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值