HCS08入门之——行列按键与4位数码管实验
0赞本实验采用分时扫描的方式读取按键并驱动8个发光二极管和4位数码管,共阴极接法,段驱动采用74HC245,位选驱动用NPN三极管。做本实验时需将拨码开关“SW2”、“SW7”和“SW5”的所有位拨到“ON”位置。现象是按SW11~SW26,数码管后2位显示按键编号(10进制“00”~“15”)。
本程序通过轮流显示各个位,即动态扫描显示数码管的数字,按建也被排在动态扫描周期中。
程序流程流程图:
程序代码:
#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
#define LED_DAT PTBD
#define LED_DIR PTBDD
#define KEY_CS0 PTCD_PTCD0
#define KEY_CS1 PTCD_PTCD1
#define LED_CS0 PTCD_PTCD3
#define LED_CS1 PTCD_PTCD4
#define LED_CS2 PTCD_PTCD5
#define LED_CS3 PTCD_PTCD6
#define LED_CS4 PTCD_PTCD7
#define CS_ON 1
#define CS_OFF 0
const uchar tab[]={
0x3F,/*0*/
0x06,/*1*/
0x5B,/*2*/
0x4F,/*3*/
0x66,/*4*/
0x6D,/*5*/
0x7D,/*6*/
0x07,/*7*/
0x7F,/*8*/
0x6F/*9*/
};//0-9,-,全灭
uchar led_buf[6];
uchar key_buf[2];
//============================
//函数名:Init_io初始化I/O
//作用:初始化I/O
//输入参数:无
//返回参数:无
//=============================
void Init_io(void)
{
//io初始值都为0
PTBD = 0x00;
//PTCD_PTCD0 = 0;
//PTCD_PTCD1 = 0;
PTCD_PTCD3=0;
PTCD_PTCD4=0;
PTCD_PTCD5=0;
PTCD_PTCD6=0;
PTCD_PTCD7=0;
//io为输出
//PTBDD = 0xFF;
PTCDD_PTCDD0 = 1;
PTCDD_PTCDD1 = 1;
PTCDD_PTCDD3=1;
PTCDD_PTCDD4=1;
PTCDD_PTCDD5=1;
PTCDD_PTCDD6=1;
PTCDD_PTCDD7=1;
PTBPE = 0xFF;//上拉
//高驱动强度
PTBDS = 0xFF;
PTCDS_PTCDS0=1;
PTCDS_PTCDS1=1;
PTCDS_PTCDS3=1;
PTCDS_PTCDS4=1;
PTCDS_PTCDS5=1;
PTCDS_PTCDS6=1;
PTCDS_PTCDS7=1;
}
//=======================================================================================================
//函数名:Init_tpm1_ch1_output
//作用:初始化TPM1;内部时钟工作于自时钟模式,总线频率8M;TPM1溢出中断禁止;通道1中断使能;
//通道引脚状态反转时间间隔=400/(8/1)近似50us
//=======================================================================================================
void Init_tpm1_ch1_output(void)
{
TPM1MODH=0x0C;
TPM1MODL=0x80;
TPM1C1VH=0x06;
TPM1C1VL=0x40;
TPM1C1SC=0x64;//通道1中断使能,边沿PWM模式,通道引脚高有效
TPM1SC=0x08;//TPM1时钟源为总线时钟;分频系数为1;溢出中断禁止
TPM1CNTH=0;//任意时刻对TPM1CNTH或TPM1CNTL的写操作将计数寄存器的计数值复位(清零)
}
//===================================================
//函数名:delay()
//作用:延时,该函数浪费CPU时间,在实际工程中酌情使用
//输入参数:无
//输出参数:无
//====================================================
void delay(void)
{
word i;
i=0x20;
while(i--)__RESET_WATCHDOG();//喂狗;
}
void main(void) {
uchar key,cnt;
EnableInterrupts; /* enable interrupts */
/* include your code here */
Init_io();
//Init_tpm1_counter();
Init_tpm1_ch1_output();
led_buf[0] = 0x55;
led_buf[1] = tab[1];
led_buf[2] = tab[2];
led_buf[3] = tab[3];
led_buf[4] = tab[4];
key_buf[0] = 0xFF;
key_buf[1] = 0xFF;
for(;;) {
if(key_buf[0]!=0xFF){
cnt = 0;
do{
if( ((key_buf[0])&0x01) != 0){
key = cnt;
key_buf[0] = 0xFF;
break;
}
cnt++;
}
while(key_buf[0]>>=1);
} else if((key_buf[1])!=0xFF){
cnt = 0;
do{
if( (key_buf[1]&0x01) != 0){
key = cnt+8;
key_buf[1] = 0xFF;
break;
}
cnt++;
}
while(key_buf[1]>>=1);
}
led_buf[1] = tab[key%10];
led_buf[2] = tab[key/10];
__RESET_WATCHDOG(); /* feeds the dog */
} /* loop forever */
/* please make sure that you never leave main */
}
//==================计数器1通道1事件中断服务程序===========================
interrupt VectorNumber_Vtpm1ch1 void TPM1_CH2OUT_ISR(void)
{
static uchar step = 0;
if((TPM1C1SC & 0x80)==0x80)
{
TPM1C1SC_CH1F=0;
switch(step){
case 0:
LED_DIR = 0xFF;
//LED_CS1 = CS_OFF;
//LED_CS2 = CS_OFF;
//LED_CS3 = CS_OFF;
LED_CS4 = CS_OFF;
LED_DAT = led_buf[0];
LED_CS0 = CS_ON;
break;
case 1:
LED_CS0 = CS_OFF;
//LED_CS2 = CS_OFF;
//LED_CS3 = CS_OFF;
//LED_CS4 = CS_OFF;
LED_DAT = led_buf[1];
LED_CS1 = CS_ON;
break;
case 2:
//LED_CS0 = CS_OFF;
LED_CS1 = CS_OFF;
//LED_CS3 = CS_OFF;
//LED_CS4 = CS_OFF;
LED_DAT = led_buf[2];
LED_CS2 = CS_ON;
break;
case 3:
//LED_CS0 = CS_OFF;
//LED_CS1 = CS_OFF;
LED_CS2 = CS_OFF;
//LED_CS4 = CS_OFF;
LED_DAT = led_buf[3];
LED_CS3 = CS_ON;
break;
case 4:
//LED_CS0 = CS_OFF;
//LED_CS1 = CS_OFF;
//LED_CS2 = CS_OFF;
LED_CS3 = CS_OFF;
LED_DAT = led_buf[4];
LED_CS4 = CS_ON;
break;
case 5:
//LED_CS0 = CS_OFF;
//LED_CS1 = CS_OFF;
//LED_CS2 = CS_OFF;
//LED_CS3 = CS_OFF;
LED_CS4 = CS_OFF;
LED_DIR = 0;
KEY_CS0 = 0;
delay();
key_buf[0] = ~LED_DAT;
break;
case 6:
//LED_CS0 = CS_OFF;
//LED_CS1 = CS_OFF;
//LED_CS2 = CS_OFF;
//LED_CS3 = CS_OFF;
//LED_CS4 = CS_OFF;
//LED_DIR = 0;
KEY_CS0 = 1;
KEY_CS1 = 0;
delay();
key_buf[1] = ~LED_DAT;
break;
default:
step = -1;
}
step++;
}
}

