基于Proteus和keil 5的计数器

计数器

(此计数器创意源自别的课题,C语言代码由本人自行查询资料完成,proteus仿真查询普中系列单片机电路设计)

一.功能设计说明

本次实验拟用proteus和keil5仿真实现一个计数器

计数器有复位功能,按下该按键,计数器清零

暂停和继续计数功能,按下按键实现计数停止和开始计数的功能

正反计数功能,按下按键后,计数器在当前数字开始反计数,再次按下回到正计数

长短按功能,长按按键3秒后(近似),计数器计数在快计数和慢计数挡切换

计数保护功能,正计数达到上限200或者反计数达到0后,计数停止,保留当前值

二.代码功能实现

2.1变量和函数说明

sec是当前计数值

Flag:加减计数转换标志位

Buttongflag:快计数和慢计数的标识

CF:P0端口

K1:K1复位 就是将运行的程序结束 然后重新开始运行

K2:暂停和开始    ,长按进入快慢计数模式切换

K3:正反计数切换

K4:模式切换

Triggercount:长短按的触发条件

数码管的位选由P2引脚控制,命名为LED1~4,方便表示位选数组为disbuff[],数字0到9段选控制由num[]数组给定控制计数

基于Proteus和keil 5的计数器_第1张图片

计数每次步进一,采用除以10的方法来确定计数值的百位,十位和个位

基于Proteus和keil 5的计数器_第2张图片

简单的延时函数:ms为1代表延时1ms,用于按键消抖

基于Proteus和keil 5的计数器_第3张图片

显示函数:为了显示舒适不闪动,令CF=0x00消隐

基于Proteus和keil 5的计数器_第4张图片

2.2辅助计数软件

计数采用定时器1,设定50ms进入一次中断,每进入10次中断sec加一(慢计数,正计数模式下)

初始值高位和低位计算用辅助软件,

基于Proteus和keil 5的计数器_第5张图片

2.3主函数和中断说明

设定工作模式TM0D=0x11,初始值设定,开启中断,启动定时器。

基于Proteus和keil 5的计数器_第6张图片

每次进入中断,重新赋值,启动定时器10次中断后,sec值加一。

至此简单的计数功能已经实现。

2.4其余功能设计

按键K1控制复位,只需要在K1按下的松开后,sec=0,TR0=1;重新开始计数。当然按键的消抖也是必不可少的。这里按键触发采用上升沿触发,按键松开后才会计数

基于Proteus和keil 5的计数器_第7张图片

K2按键按下,消抖后就只需要对TR0取反,就能停止计数和开始计数。

对快慢计数切换也在K2进行操作,当K2按下不松开,一直进入到while(!K2)循环中,循环每1ms延时给triggercount加一,直到松开,松开后判断triggercount的值,如果大于2200则认为是长按了,先triggercount置零,然后切换buttonflag的值在5和10变化,调整要进入多少次中断才给sec值加一。然后开始计数,TR0=1

如果triggercount的值小于2200,认为短按,给triggercount置零,依旧维持开始和暂停功能。

基于Proteus和keil 5的计数器_第8张图片

对正计数和反计数设计,按下K3,消抖处理后让flag取反。

基于Proteus和keil 5的计数器_第9张图片

Flag是进入buttonflag次中断后,判断flag是否为True,让sec加一或者减一。

基于Proteus和keil 5的计数器_第10张图片

计数保护设计,只需要在中断判断sec的值是否为200或者0,这里注意判断顺序应该为sec加减后判断,否则开机或者复位会触发保护。然后TR0=0关闭定时器。

基于Proteus和keil 5的计数器_第11张图片

三.仿真设计

采用AT89C51的MCU,独立按键K1~K4连接P3.0~P3.3,

8位共阴极数码管,数码管的位选由74LS138译码器实现,段选用74HC573

独立按键K1~K4接引脚P3.0-P3.3

总体仿真电路设计如下:

基于Proteus和keil 5的计数器_第12张图片

实物验证:使用stc89c52rc,验证与仿真一致

基于Proteus和keil 5的计数器_第13张图片

四.心得体会:

在此之前我没有使用过proteus进行单片机的仿真验证,所以这次使用proteus还是很吃力的,尤其是对51MCU的外围电路配置,比如说晶振的配置,使能的配置此次仿真实验,让我体会到了嵌入式系统的学习不仅仅是代码语言的编写,首先得在实际电路中还搭建好,

此次proteus的仿真电路我参考了经典普中51单片机的原理。

此次我最印象深刻的地方就是长按功能的实现,因为我无论是单片机上和仿真上都不能实现长按,我反复检查代码逻辑,始终发现不了问题。最后终于是明白,问题出在triggercount的定义,我需要让triggercount大于2200才能进入长按功能,所以我对triggercount的类型不能是char,无符号的字符类型只能0~255,就是这个问题让我至少花费了2个小时。最后改为无符号int类型,长按终于实现,功能圆满。

此次作业仍有许多不足的地方,例如对代码结构还是比较混乱的,不易读,执行效率不高。代码没有分块编写,不方便移植。希望能够继续改进

你可能感兴趣的:(c语言,vscode,嵌入式硬件,proteus)