freetech

HCS08入门之——行列按键与4位数码管实验

0
阅读(3149)

本实验采用分时扫描的方式读取按键并驱动8个发光二极管和4位数码管,共阴极接法,段驱动采用74HC245,位选驱动用NPN三极管。做本实验时需将拨码开关“SW2”、“SW7”和“SW5”的所有位拨到“ON”位置。现象是按SW11~SW26,数码管后2位显示按键编号(10进制“00”~“15”)。

本程序通过轮流显示各个位,即动态扫描显示数码管的数字,按建也被排在动态扫描周期中。

程序流程流程图:

clip_image002

程序代码:

#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++;
        }
}