本帖最后由 3DA502 于 2013-5-7 00:49 编辑
写这个程序的原因听起来很不像话,我高中同学上了研究生,老师给他布置一道作业,使用89s52和8255,搭建一个4位数码管的秒表。
秒表有一个按键,按一下开始,再按停止,再按清零,再按就又开始了。我好久没有用keil的C51编译器,也懒得安装,随手写个程序没法
编译,所以放出来让大家帮忙看看,顺便给评个分啊亲
电路很简单,8255的管脚驱动LED数码管,按键接到外部中断0,如有哪位爱好学习的同学帮忙画个protues的仿真图就太好了。
/************************************************************************************************
**
************************************************************************************************/
#include <reg52.h>
#include <absacc.h>
/************************************************************************************************
**
************************************************************************************************/
#define PORTA (*((unsigned char *)0x8000)) /* 0x8000映射到8255的PORTA*/
#define PORTB (*((unsigned char *)0x8001))
#define PORTC (*((unsigned char *)0x8002))
#define CONTROL (*((unsigned char *)0x8003))/* 0x8000映射到8255的控制字 */
/************************************************************************************************
**
************************************************************************************************/
unsigned int Second_Count;
unsigned char Step; /* 秒计数的累加步进值,为0时停止走秒*/
/************************************************************************************************
** 状态机相关变量
************************************************************************************************/
unsigned char StateChange_Flag;
unsigned char State;
/************************************************************************************************
** 显示相关变量
************************************************************************************************/
const unsigned char LED_MODE[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* 放LED字模 0~9*/
const unsigned char LED_DIGTAL_SELECT[4] = {1, 2, 4, 8}; /* 放LED位选通 */
unsigned char Display_Buff[4] ; /* 放LED 的10进制字 */
/************************************************************************************************
** 定时器初始化
************************************************************************************************/
void initTimer (void) {
TMOD=0x0;
TH1=0x83;
TL1=0x0;
TR1=1;/* 边沿中断*/
ET1=1;/* 外部中断允许*/
EA=1;
}
/************************************************************************************************
** 定时器中断线程 4ms执行一次
************************************************************************************************/
void timer1(void) interrupt3 {
static int FourMS_Count;
static char Scan_Count;
char i;
TH1=0x83;
TL1=0x0; /* Timer reload*/
Scan_Count += 1;
Scan_Count %= 4;
FourMS_Count += 1;/* every 4ms +1*/
if (FourMS_Count == 1000/4) {
FourMS_Count = 0;
Second_Count += Step;
Display_Buff[0] = Second_Count % 10;
Display_Buff[1] = (Second_Count % 100)/10;
Display_Buff[2] = (Second_Count % 1000)/100;
Display_Buff[3] = Second_Count / 1000;
}
PORTA = 0x00;
i = Display_Buff[Scan_Count];
PORTB = GigtalLED[Scan_Count];
PORTA = SevenSegLED;
}
/************************************************************************************************
** 按键中断
************************************************************************************************/
void int0(void) interrupt 0 {
/* 管脚中断 检测按键 使用硬件消除抖动 */
State += 1;
if(State >= 4) {
State = 1;
}
StateChange_Flag = 0;/* 触发状态转换的标志 */
EX0 = 0;/* Disable the extera interrupt */
}
/************************************************************************************************
** 主程序
************************************************************************************************/
void main(void)
{
IT0=1;
EX0=1;
initTimer();
CONTROL = 0x00;
StateChange_Flag = 1;
while(1) {
switch(State) {
case 0:
step = 0;
Second_Count = 0;
break;
case 1:
step = 1;
break;
case 2:
step = 0;
break;
case 3:
step = 0;
Second_Count = 0;
break;
default:
break;
}
EX0 = 1;/* 开启中断,响应按键*/
while(StateChange_Flag);
}
}
/************************************************************************************************
** END
************************************************************************************************/
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
一周热门 更多>