一、题目要求
在CT107D单片机综合训练平台上,通过I/O模式编写代码,实现以下功能:
- 系统上电后,关闭蜂鸣器、继电器和全部指示灯,数码管显示初始值为28,仅显示数码管最右边两位。
- 利用定时器0实现10ms间隔定时,作为长定时的基本单位,用于记录按键按下持续时间。
- 将J5的23脚短接,将S4设置为独立按键。
- 循环扫描S7按键,按下时间小于1秒为短按,数码管数字加1,超过99后恢复为00;按下时间大于1秒为长按,数码管计数清零。
- 在按键扫描和处理过程中,确保不干扰数码管正常显示,避免按键误触发和多次处理的情况发生。
二、利用烧写工具中的定时器计数器定时
记得手打打开总中断EA
三、示例代码
#include "stc15.h"void hc573(unsigned char channel, unsigned char value)
{P2 = (P2 & 0x1f) | 0x00;P0 = value;switch(channel){case 4:P2 = (P2 & 0x1f) | 0x80; //LEDbreak;case 5:P2 = (P2 & 0x1f) | 0xa0; //蜂鸣器继电器break;case 6:P2 = (P2 & 0x1f) | 0xc0; //数码管位选break;case 7:P2 = (P2 & 0x1f) | 0xe0; //数码管段选break;}P2 = (P2 & 0x1f) | 0x00;
}void delay_smg(unsigned int t)
{while(t--);
}void delay_key(unsigned int t)
{while(t--);
}#define TSMG 500
unsigned char n = 28;code unsigned char Seg_Table[] =
{0xc0, //00xf9, //10xa4, //20xb0, //30x99, //40x92, //50x82, //60xf8, //70x80, //80x90, //90x88, //A0x83, //b0xc6, //C0xa1, //d0x86, //E0x8e //F
};//控制所有数码管
void smg_all(unsigned char dat)
{hc573(6, 0xff);hc573(7, dat);
}//控制单个数码管
void smg_bit(unsigned char pos, unsigned char dat)
{hc573(6, 0x01 << pos);hc573(7, dat);delay_smg(TSMG);hc573(6, 0x01 << pos);hc573(7, 0xff);
}//数码管显示函数
void smg_display()
{smg_bit(6, Seg_Table[(n / 10)]);smg_bit(7, Seg_Table[(n % 10)]);
}unsigned int count = 0;extern unsigned char f_key;void Timer0_Init(void) //10毫秒@12.000MHz
{AUXR &= 0x7F; //定时器时钟12T模式TMOD &= 0xF0; //设置定时器模式TL0 = 0xF0; //设置定时初始值TH0 = 0xD8; //设置定时初始值TF0 = 0; //清除TF0标志TR0 = 1; //定时器0开始计时ET0 = 1;EA = 1;
}void service_timer0 () interrupt 1
{if(f_key == 1){count++;}
}#define TKEY 200sbit s7 = P3^0;
unsigned char f_key = 0;void key_scan()
{if(s7 == 0){count = 0;f_key = 1;delay_key(TKEY);if(s7 == 0){while(s7 == 0){smg_display();}f_key = 0;if(count >= 100){n = 0;count = 0;}else{n++;if(n > 99){n = 0;}count = 0;}}}f_key = 0;count = 0;}void init_sys()
{hc573(5, 0x00); //关闭所有蜂鸣器和继电器hc573(4, 0xff); //熄灭所以LEDsmg_all(0xff); //熄灭所有数码管Timer0_Init();
}void main()
{init_sys();while(1){smg_display();key_scan();}
}
-
void hc573(unsigned char channel, unsigned char value)
:定义了一个函数hc573
,用于控制573锁存器的输出。根据传入的通道号和数据值,设置相应的输出信号。 -
void delay_smg(unsigned int t)
:定义了一个延时函数delay_smg
,用于实现数码管显示的延时。 -
void delay_key(unsigned int t)
:定义了一个延时函数delay_key
,用于实现按键扫描的延时。 -
#define TSMG 500
:定义了一个宏TSMG
,值为500,用于设置数码管显示的延时时间。 -
unsigned char n = 28;
:定义了一个无符号字符型变量n
,初始值为28,用于存储数码管显示的数值。 -
code unsigned char Seg_Table[] = {...}
:定义了一个只读数据表Seg_Table
,存储了数码管显示的段选值。 -
void smg_all(unsigned char dat)
:定义了一个函数smg_all
,用于控制所有数码管的显示。 -
void smg_bit(unsigned char pos, unsigned char dat)
:定义了一个函数smg_bit
,用于控制单个数码管的显示。 -
void smg_display()
:定义了一个数码管显示函数smg_display
,在其中调用了smg_bit
函数实现数码管的显示。 -
unsigned int count = 0;
:定义了一个无符号整型变量count
,用于记录按键按下的持续时间。 -
extern unsigned char f_key;
:声明了一个外部的无符号字符型变量f_key
,用于按键扫描的标志。 -
void Timer0_Init(void)
:定义了一个定时器0初始化函数Timer0_Init
,用于设置定时器0的工作模式和初值,并开启定时器0。 -
void service_timer0 () interrupt 1
:定义了一个定时器0中断服务函数service_timer0
,用于处理定时器0的中断事件。 -
#define TKEY 200
:定义了一个宏TKEY
,值为200,用于设置按键扫描的延时时间。 -
sbit s7 = P3^0;
:定义了一个位变量s7
,表示P3口的第0位,用于表示S7按键的状态。 -
unsigned char f_key = 0;
:定义了一个无符号字符型变量f_key
,初始化为0,用于按键扫描的标志。 -
void key_scan()
:定义了一个按键扫描函数key_scan
,用于检测S7按键的按下情况并进行相应处理。 -
void init_sys()
:定义了一个系统初始化函数init_sys
,在其中关闭蜂鸣器、继电器、LED灯和数码管,并初始化定时器0。 -
void main()
:定义了主函数main
,在其中首先调用init_sys
进行系统初始化,然后进入一个无限循环,在循环中持续进行数码管显示和按键扫描的操作。