该程序功能上还有一定的缺陷,带晚上,初步实现功能
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
//
待完善
#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 -- ;); // 延时
}
#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 -- ;); // 延时
}