ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Arduino-Proteus仿真08-按键控制数码管闪烁增减显示

2021-02-02 12:29:04  阅读:455  来源: 互联网

标签:仿真 temp Arduino 08 down 数码管 Proteus 按键


Arduino-Proteus仿真08-按键控制数码管闪烁增减显示

设计者:STCode(公众号同名)

<iframe allowfullscreen="true" data-mediaembed="bilibili" id="9oLCCsEO-1612239760071" src="https://player.bilibili.com/player.html?aid=671482634"></iframe>

Arduino-Proteus仿真-按键控制数码管闪烁增减显示


在这里插入图片描述

前言:

Proteus是英国Labcenter公司开发的电路分析与实物仿真及印制电路板设计软件,它可以仿真、分析各种模拟电路和集成电路,其提供了大量模拟与数字元器件及外部设备,以及各种虚拟仪器(如电压表、电流表、示波器、逻辑分析仪、信号发生器等),特别是它具有对单片机及其外围电路组成的综合系统交互仿真功能,
目前,Proteus仿真系统支持的主流单片机有ARM7(LPC21xx)、8051/52、AVR、PIC 10/12/16/18/24、MSP430、CotexM0/M3、HC11等,其支持的开发环境有Keil u Vision2/3/4、MPLAB、Atmel Studio等。

提示:

Proteus仿真Arduino中,关于所需硬件获取、软件编译、HEX文件获取、代码导入等问题请参考文章:Arduino-Proteus仿真01-LED灯闪烁

1.练习描述

这次我们通过4个按键可分别实现数字增/减调节,确定及取消调节功能。在调节过程中数码管被设计为闪烁显示,确定后则恢复正常显示,按下取消按键时将恢复调节之前的值。

2.元器件选择

在这里插入图片描述

在元件模式中点击P选项,在元件库中搜索所需的元件名称,双击后便可添加到元件清单中。

3.电路连接

在这里插入图片描述

4.程序设计

//按键控制数码管闪烁增/减显示
//说明:通过按键加/减数码管所显示的数字,调节过程中数码管闪烁显示
//确定后恢复正常显示,按下取消时将回复到调节之前的值

#define k1_down() (digitalRead(14) == 0)  //加
#define k2_down() (digitalRead(15) == 0)  //减
#define k3_down() (digitalRead(16) == 0)  //确定
#define k4_down() (digitalRead(17) == 0)  //取消

const uint8_t CA_SEGCODE[]=   //0~9共阳数码管段码表
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uint16_t count = 2021;   //显示初始值
uint16_t temp;            //临时变量,用于存储按取消键前的已确定的值
uint8_t array[]={0,0,0,0};  //保存数位分解结果的数组
uint8_t adjust = 0;          //标识当前是否处理调节状态
uint8_t pre_key = 0xff;    //保存上次按键状态

uint8_t i,j,t;      //定义变量

void setup()
{
    DDRD = 0XFF;PORTD = 0XFF;      //数码管段码端口配置
    DDRB = 0XFF;PORTB = 0XFF;      //数码管位码端口配置
    DDRC = 0X00;PORTC = 0XFF;      //按钮输入端口端口设为内部上拉
}

void loop()
{
    for(t = 0;t<35;t++)    //正常刷新显示
    {
        INT_TO_4Digit(count);     //数为分解
        for(i = 0;i<4;i++)         //4位数码管扫描刷新显示
        {
            PORTD = 0XFF;          //先暂时关闭段码
            PORTB = 1 << i;        //输出位码
            PORTD = CA_SEGCODE[array[i]];   //发送段码
            delay(2);                         //延时
        }
        key_handle();                         //处理按键
    }
    if(adjust)                            //如果处于调节状态,脱离了扫描刷新,数码管开始闪烁
        {
            PORTD = 0XFF;                 //关闭所有数码管
            for(t = 0;t < 15;t++)         //在此循环中保持按键响应
            {
                delay(10);              //延时
                key_handle();          //处理按键
            }
        }
}

//数位分解函数
//使用循环减法分解的速度优于使用/与%分解
void INT_TO_4Digit(uint16_t n)   
{
    array[0] = 0;
    while(n >= 1000)
    {
        array[0]++;
        n -= 1000;
    }
    array[1] = 0;
    while(n >= 100)
    {
        array[1]++;
        n -= 100;
    }
    array[2] = 0;
    while(n >= 10)
    {
        array[2]++;
        n -= 10;
    }
    array[3] = n;
}

void key_handle()         //按键处理函数
{
    if(pre_key == PINC) return;     //按键状态未改变时退出
    pre_key = PINC;                  //保存当前新的按键状态
    //增按键
    if(k1_down())              //按键1按下
    {
        delay(10);
        if(k1_down())
        {
            if(temp == 0) temp = count;     //备份temp,以便按下取消时还原
            count++;                         //递增
            adjust = 1;                      //进入调节状态
        }
    }
    //减按键
    else if(k2_down())
    {
        delay(10);
        if(k2_down())
        {
            if(temp == 0) temp = count;
            count--;                          //递减
            adjust = 1;
        }
    }
    //确定按键
    else if(k3_down())
    {
        delay(10);
        if(k3_down())
        {
            adjust = 0;          
            temp = 0;
        }
    }
    //取消按键
    else if(k4_down())
    {
        delay(10);
        if(k4_down())
        {
            if(temp)
            {
                count = temp;   //还原count
            }   
            temp = 0;             //temp清零
            adjust = 0;
        }
    }
}

对于4位整数的数位分解,程序中使用了循环递减的方法(详见函数–INT_TO_4Digit(uint16_t n)),虽然代码比使用整除及取余运算的代码要复杂一些,但是其分解效果要高于后者。
对于4个按键的处理,加入了消抖语句,以防出现操作不稳定的问题(详见-- key_handle() 仿真过程不加入消抖也不会有影响,但在应用在实物上有必要加入)。
为了增/减调节时数码管出现整体闪烁效果,程序中引入了adjust变量,变量值为1时,则表示进入调节状态,主循环内第二部分的15次循环及延时在跟踪按键操作的同时,由于延时达150ms,故而使数码管出现闪烁现象;主循环第一部分循环次数设置的越大,在150ms的黑屏显示后正常稳定显示的时间就越长。
另外,示例中对于端口的配置、写入、读取这3类操作,没有使用pinMode()\digitalWrite()\digitalRead()这3个函数,而是直接针对AVR寄存器进行操作。
Arduino的核心微控制器为Atemga328,其每个IO口相关寄存器有3个,分别是:
1) 数据方向寄存器DDRx
2) 端口数据寄存器PORTx
3) 端口输入引脚地址寄存器PINx
(其中x = B\C\D)
pinMode()\digitalWrite()\digitalRead() 3个函数分别主要针对DDRx、PORTx、PINx进行操作

5.软件操作

程序编写完成后点击Arduino IDE编译器的文件—首选项,将编译选项勾选上。点击好以后进行编译,编译完成后复制HEX文件所在的路径,复制完成后返回Proteus软件,双击Arduino控制板,在Program File处粘贴HEX文件的路径。点击确定以后即可进行仿真,点击Proteus软件下方运行仿真按钮,可以看到仿真的效果。
在这里插入图片描述

源文件请关注公众号“STCode”获取~

标签:仿真,temp,Arduino,08,down,数码管,Proteus,按键
来源: https://blog.csdn.net/STCode_G/article/details/113549344

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有