哪位高手帮下忙,做一简单的单片机课题,万分感谢!!!!!!!!!!!!!急求 15
秒表系统设计:用AT89C51设计一个2位LED数码显示“秒表”,显示时间为00~99秒,每秒自动加一。另设计一个“开始”按键和一个“复位”按键。...
秒表系统设计:用AT89C51设计一个2位LED数码显示“秒表”,显示时间为00~99秒,每秒自动加一。另设计一个“开始”按键和一个“复位”按键。
展开
展开全部
/***数显秒表,范围0~99——火柴天堂作品-20120612***/
/***源程序硬件环境:51单片机,12MHz晶振,2位共阳数码管,P0 口段选,P20~P21 低电平位选(反相器),P21为高位数码管,P30~P31双独立按键***/
/***功能说明:按启动/暂停键(P30),开始/暂停计时,按 清零键(P31)清零数据***/
#include"reg51.h"//包含51头文件
#define TRUE1//定义布尔量'1':真
#define FALSE0//定义布尔量'0':假
#define uchar unsigned char//定义 无符号字符型数据 简称
#define uint unsigned int//定义 无符号整型数据 简称
#define th00x3c
#define tl00xb0//50ms at 12MHz(定时器工作模式1 状态)
#define th10xfc
#define tl10x18//1ms at 12MHz(定时器工作模式1 状态)
#define SEG_Num6//数码管位数
#define SEG_DataP0//数码管段驱动接口
#define SEG_EnP2//数码管位驱动接口
#define SEG_AllOff(SEG_En|=0x03)//关闭所有数码管(位驱动)
#define DisTimeAt1msCount8//单'位'数码管显示时间,数码管刷新频率f=1/(N×t),其中 N为数码管位数, t为单'位'数码管显示时间
#define T1sAt1msCount1000//1秒 计数值(在定时器为1ms 情况下计数)
#define TimesEnd100//显示内容范围 0~99
sbit KeyStart=
uchar code SEG_B_List[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阳数码管代码表"0-9"
ulong Sec;
uchar bdata Flag=1;
sbit DisplayFlag=Flag^0;//显示标志位
sbit TimesUpFlag=Flag^1;//时间更新标志位
sbit StartFlag=Flag^2;//开始(计时)标志位
void Timer0() interrupt 1//定时器0中断函数
{
static uchar t50ms;
TL0=tl0;
TH0=th0;
t50ms=++t50ms%T1sAt50msCount;//先对50ms计时变量加1,后对变量范围进行限制(0~19)(即对20取模)
if(!t50ms) T1sTimesUpFlag=TRUE;//若计时变量归0,表示1s计时到,则对1s计时标志位 置位
if(SetFlag && !(t50ms%T500msAt50msCount))FlickFlag=~FlickFlag;//设置中,每500ms切换显示状态一次(即1s闪一次)
}
void Timer1() interrupt 3//定时器1中断函数
{
static uchar t1ms;
TL1=tl1;
TH1=th1;
t1ms=++t1ms%DisTimeAt1msCount;//先计数值加1,后对计数范围进行限制0~(DisTimeAt1msCount-1)
if(!t1ms) DisplayFlag=TRUE;//若定时计数值归0,则表示计数值曾到达 单'位'显示时间(DisTimeAt1msCount),显示标志 置位
}
void TimerInit()
{
TMOD=0x11;//开启定时器0、定时器1,并都工作在模式1
TH0=th0;
TL0=tl0;
TR0=1;//启动T0定时器 计时
ET0=1;//允许定时器0中断
TH1=th1;
TL1=tl1;
TR1=1;//启动T1定时器 计时
ET1=1;//允许定时器1中断
EA=1;//开启系统中断功能
}
float Pow_Self(float x,uint y)//自编简易 x 的 y 次方函数,y只能是 非负整数
{
float sum;
if(x==0 && y==0) return;//0 的 0 次方无意义
else if(x==0) sum=0;//可有可无,y!=0的情况已经包含x=0,不加不影响结果,但影响运算速度
else if(y==0) sum=1;//除上述情况外,任何数的 0 次方均为 1
else if(y==1) sum=x;//任何数的 1 次方 均为 本身
else if(y>1) sum=Pow_Self(x,--y)*x;//递归调用,降幂
return sum;//返回计算结果
}
void TimesUpdata()//时间更新 函数
{
if(TimesUpFlag)//若 时间更新标志 为真
{
Sec=++Sec%TimesEnd;//Sec (秒)在 TimesEnd (0~999) 范围内加1
TimesUpFlag=FALSE;//清 时间更新标志位
}
}
void Display(ulong dis_num)//显示函数,显示内容为 无符号整型数据 dis_num
{
static uchar dis_loca;//定义静态变量 显示位置
if(DisplayFlag)//若显示标志位为真(单'位'显示时间结束),则执行以下任务
{
DisplayFlag=FALSE;//清显示标志位
dis_loca=++dis_loca%SEG_Num;//先对 显示位置 加1,后对变量范围进行限制 0~(SEG_Num-1)
SEG_AllOff;//关闭所有数码管显示(位驱动)
SEG_Data=SEG_B_List[(dis_num/(ulong)(Pow_Self(10,dis_loca)))%10];//将显示内容(dis_num) 本次需显示的位(dis_loca)上的数值转成代码,并送到数据端口
SEG_En|=1<<dis_loca;//开启本次需要显示的位驱动
}
}
void SystemInit()
{
TimerInit();
KeyStart=1;
KeyClear=1;
}
void main()//主函数
{
SystemInit();//调用 系统初始化函数
while(1)//循环系统
{
TimesUpdata();//调用 时间更新函数
Display(Sec);//调用 显示函数 显示内容为 Sec
}
}
/***源程序硬件环境:51单片机,12MHz晶振,2位共阳数码管,P0 口段选,P20~P21 低电平位选(反相器),P21为高位数码管,P30~P31双独立按键***/
/***功能说明:按启动/暂停键(P30),开始/暂停计时,按 清零键(P31)清零数据***/
#include"reg51.h"//包含51头文件
#define TRUE1//定义布尔量'1':真
#define FALSE0//定义布尔量'0':假
#define uchar unsigned char//定义 无符号字符型数据 简称
#define uint unsigned int//定义 无符号整型数据 简称
#define th00x3c
#define tl00xb0//50ms at 12MHz(定时器工作模式1 状态)
#define th10xfc
#define tl10x18//1ms at 12MHz(定时器工作模式1 状态)
#define SEG_Num6//数码管位数
#define SEG_DataP0//数码管段驱动接口
#define SEG_EnP2//数码管位驱动接口
#define SEG_AllOff(SEG_En|=0x03)//关闭所有数码管(位驱动)
#define DisTimeAt1msCount8//单'位'数码管显示时间,数码管刷新频率f=1/(N×t),其中 N为数码管位数, t为单'位'数码管显示时间
#define T1sAt1msCount1000//1秒 计数值(在定时器为1ms 情况下计数)
#define TimesEnd100//显示内容范围 0~99
sbit KeyStart=
uchar code SEG_B_List[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阳数码管代码表"0-9"
ulong Sec;
uchar bdata Flag=1;
sbit DisplayFlag=Flag^0;//显示标志位
sbit TimesUpFlag=Flag^1;//时间更新标志位
sbit StartFlag=Flag^2;//开始(计时)标志位
void Timer0() interrupt 1//定时器0中断函数
{
static uchar t50ms;
TL0=tl0;
TH0=th0;
t50ms=++t50ms%T1sAt50msCount;//先对50ms计时变量加1,后对变量范围进行限制(0~19)(即对20取模)
if(!t50ms) T1sTimesUpFlag=TRUE;//若计时变量归0,表示1s计时到,则对1s计时标志位 置位
if(SetFlag && !(t50ms%T500msAt50msCount))FlickFlag=~FlickFlag;//设置中,每500ms切换显示状态一次(即1s闪一次)
}
void Timer1() interrupt 3//定时器1中断函数
{
static uchar t1ms;
TL1=tl1;
TH1=th1;
t1ms=++t1ms%DisTimeAt1msCount;//先计数值加1,后对计数范围进行限制0~(DisTimeAt1msCount-1)
if(!t1ms) DisplayFlag=TRUE;//若定时计数值归0,则表示计数值曾到达 单'位'显示时间(DisTimeAt1msCount),显示标志 置位
}
void TimerInit()
{
TMOD=0x11;//开启定时器0、定时器1,并都工作在模式1
TH0=th0;
TL0=tl0;
TR0=1;//启动T0定时器 计时
ET0=1;//允许定时器0中断
TH1=th1;
TL1=tl1;
TR1=1;//启动T1定时器 计时
ET1=1;//允许定时器1中断
EA=1;//开启系统中断功能
}
float Pow_Self(float x,uint y)//自编简易 x 的 y 次方函数,y只能是 非负整数
{
float sum;
if(x==0 && y==0) return;//0 的 0 次方无意义
else if(x==0) sum=0;//可有可无,y!=0的情况已经包含x=0,不加不影响结果,但影响运算速度
else if(y==0) sum=1;//除上述情况外,任何数的 0 次方均为 1
else if(y==1) sum=x;//任何数的 1 次方 均为 本身
else if(y>1) sum=Pow_Self(x,--y)*x;//递归调用,降幂
return sum;//返回计算结果
}
void TimesUpdata()//时间更新 函数
{
if(TimesUpFlag)//若 时间更新标志 为真
{
Sec=++Sec%TimesEnd;//Sec (秒)在 TimesEnd (0~999) 范围内加1
TimesUpFlag=FALSE;//清 时间更新标志位
}
}
void Display(ulong dis_num)//显示函数,显示内容为 无符号整型数据 dis_num
{
static uchar dis_loca;//定义静态变量 显示位置
if(DisplayFlag)//若显示标志位为真(单'位'显示时间结束),则执行以下任务
{
DisplayFlag=FALSE;//清显示标志位
dis_loca=++dis_loca%SEG_Num;//先对 显示位置 加1,后对变量范围进行限制 0~(SEG_Num-1)
SEG_AllOff;//关闭所有数码管显示(位驱动)
SEG_Data=SEG_B_List[(dis_num/(ulong)(Pow_Self(10,dis_loca)))%10];//将显示内容(dis_num) 本次需显示的位(dis_loca)上的数值转成代码,并送到数据端口
SEG_En|=1<<dis_loca;//开启本次需要显示的位驱动
}
}
void SystemInit()
{
TimerInit();
KeyStart=1;
KeyClear=1;
}
void main()//主函数
{
SystemInit();//调用 系统初始化函数
while(1)//循环系统
{
TimesUpdata();//调用 时间更新函数
Display(Sec);//调用 显示函数 显示内容为 Sec
}
}
追问
亲,你那有没有C语言的程序加仿真,是PROTUES
追答
亲,俺从不玩 软件仿真!
意法半导体(中国)投资有限公司
2021-01-14 广告
2021-01-14 广告
可以写对它写程序,让它听从你的安排,你让它实现什么功能它就能实现,比如电子钟、电子琴、打印机、手机、电梯控制,智能家具如:空调、冰箱、洗衣机等,如果这些家电没有它,什么都不能工作。单片机内部很复杂,你研究的越深你就会越爱上它,它可以帮你实现...
点击进入详情页
本回答由意法半导体(中国)投资有限公司提供
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询