线反转法接线图如下。其原理简单来说就是:
四个行引脚推挽输出低电平(置0), 四个列引脚上拉输入,
如果有按键按下,会连通行与列,导致某个列引脚电压被拉低,故输出寄存器不再是0X0F,而是0X0E,0X0D,0X0B,0X07,
这样就判断出了那一列被按下。
此时反转输入输出,用同样的方法监测那一行被按下。
最后返回键值。
//------------------------------header------------------------------------------
#include "iostm8s208mb.h"
//------------------------------common datatype---------------------------------
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned long uint32_t;
#define u8 uint8_t
#define u16 uint16_t
#define u32 uint32_t
//------------------------------macros------------------------------------------
#define LCDRS PF_ODR_ODR0
#define LCDRW PF_ODR_ODR3
#define LCDEN PF_ODR_ODR4
#define LCDDATA PB_ODR
#define KeyPortIn PC_IDR
#define KeyPortOut PC_ODR
//------------------------------function declare--------------------------------
void GPIO_init(void);
void delay(u16 count);
void LCD_init(void);
void LCD_write(u8 data,u8 cmd_flag);
void LCD_display(void);
void LCD_lr_DIS(u8 line,u8 row,u8 z);
u8 KEY_scan(void);
//------------------------------------------------------------------------------
u8 line1[]="==4*4 Keyboard==";
u8 line2[]="[Keynum]: ";
u8 table3[]={'0','1','2','3','4','5','6','7','8','9'};
//------------------------------main--------------------------------------------
void main( void )
{
GPIO_init();
LCD_init();
LCD_display();
u8 keydown;
while (1)
{
keydown=KEY_scan();
if(keydown!=0XFF)
{
LCD_lr_DIS(2,12,table3[keydown/10]);
LCD_lr_DIS(2,13,table3[keydown%10]);
delay(300);
}
LCD_lr_DIS(2,12,'N');
LCD_lr_DIS(2,13,'o');
}
}
//------------------------------functions---------------------------------------
void GPIO_init(void)
{
PF_DDR=0XFF;
PF_CR1=0XFF;
PF_CR2=0X00;
PF_ODR=0X00;
PB_DDR=0XFF;
PB_CR1=0XFF;
PB_CR2=0X00;
PB_ODR=0X00;
PC_DDR=0XF0;
PC_CR1=0XFF;
PC_CR2=0X0F;
}
void delay(u16 count)
{
u8 i,j;
while (count--)
{
for(i=0;i<50;i++)
for(j=0;j<50;j++);
}
}
void LCD_init(void)
{
LCD_write(0X38,0);
LCD_write(0X0E,0);
LCD_write(0X06,0);
LCD_write(0X01,0);
}
void LCD_write(u8 data,u8 cmd_flag)
{
LCDRS=cmd_flag;
LCDRW=0;
LCDEN=1;
delay(1);
LCDDATA=data;
LCDEN=0;
delay(1);
}
void LCD_display(void)
{
LCD_write(0X80,0);
for (u8 i = 0; i < 16; i++)
{
LCD_write(line1[i],1);
}
LCD_write(0XC0,0);
for (u8 i = 0; i < 16; i++)
{
LCD_write(line2[i],1);
}
}
void LCD_lr_DIS(u8 line,u8 row,u8 z)
{
switch (line)
{
case 1:
LCD_write(0X80+row,0);
LCD_write(z,1);
break;
case 2:
LCD_write(0XC0+row,0);
LCD_write(z,1);
break;
default:
break;
}
}
u8 KEY_scan(void)
{
PC_DDR=0XF0;
PC_CR1=0XFF;
PC_CR2=0X00;
KeyPortOut=0X0F;
u8 keypress=0XFF;
if(KeyPortIn != 0X0F)
{
delay(10);
switch (KeyPortIn)
{
case 0X0E:keypress=0;break;
case 0X0D:keypress=1;break;
case 0X0B:keypress=2;break;
case 0X07:keypress=3;break;
default:keypress=0XFF;break;
};
PC_DDR=0X0F;
PC_CR1=0XFF;
PC_CR2=0X00;
KeyPortOut=0XF0;
if(KeyPortIn!=0XF0)
{
delay(10);
switch (KeyPortIn)
{
case 0XE0:keypress +=0;break;
case 0XD0:keypress +=4;break;
case 0XB0:keypress +=8;break;
case 0X70:keypress +=12;break;
default:keypress=0XFF;break;
};
while(KeyPortIn!=0XF0);//按键松手检测
}
}
return keypress;
}
上一篇:STM8例程大汇集(寄存器版)
下一篇:STM8控制LCD12864液晶屏实验
推荐阅读最新更新时间:2024-11-10 11:06
设计资源 培训 开发板 精华推荐
- TA8215LQ 18W BTL x 2ch 音频功率放大器典型应用
- EVAL-ADM2582EEBZ、4 层 EN55022 B 类辐射符合评估板,用于 ADM2582E 2.5 kV rms 信号和电源隔离 RS-485/RS-422 收发器,具有 ±15 kV ESD 保护
- LTC3110EFE 500mA USB 充电/备用应用的典型应用电路,具有可变充电功率 PCHRG,取决于系统负载
- AX8052F143 SoC 超低功耗射频微控制器的典型应用单端天线和内部 TX/RX 开关,射频载波频率范围为 27 - 1050 MHz
- LT3970EMS 1.8V 降压转换器的典型应用
- 基于FE8.1—USBHUB2.0
- DC751A-L,使用 LTC2234IUK 10 位、135Msps 高速 ADC 的演示板,VDD = +3.3V,100MHz
- DC2422A-A,使用 LTC7812EUH 同步降压 + 同步升压的演示板,4 至 36V 输入电压,12V 输出电压 @ 8A
- LT1026CS8 电压四倍器的典型应用电路
- ESP32-S3-WROOM-1系列开发板