前言:
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灯闪烁
关于数码管的相关知识可以参考文章:Arduino-Proteus仿真05-分立式数码管循环显示0~9
1) 练习描述
这次我们来练习一下按键的使用,配合上个文章里的数码管知识,做一个可以控制数码管显示倒计时的小实验,具体用到3个按键,按键1用来启动倒计时,按键2用来暂停倒计时,按键3用来复位倒计时。
2) 元器件选择
·ATMEGA328P
·7SEG-MPX2-CA
·BUTTON
·RX8
·LED-YELLOW
·RES(220O欧姆)
在元件模式中点击P选项,在元件库中搜索所需的元件名称,双击后便可添加到元件清单中。
3) 电路连接
从电路连接图上可以看到,两位数码管的位码1、2分别接到IO15和IO16,段码a~DP分别接到IO2~IO9,3个按键分别接到IO10~IO12,三个按键的另一端接地。
4) 程序设计
4) int num=60; //定义倒计时数字
5) int count=0; //定义计数值
6) int start_key = 10; //开始按键
7) int pause_key = 11; //暂停按键
8) int reset_key = 12; //复位按键
//0-9对应的16进制数据
9) const uint8_t CA_SEGCODE[] =
10) { 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
11) //用数组指定2位8段数码管所连接的段引脚(或称段码引脚)
12) const uint8_t ledPins_SEG[] = { 2, 3, 4, 5, 6, 7, 8, 9 };
13) //用数组指定2位8段数码管的位引脚(或称位码引脚)
14) const uint8_t ledPins_DIG[] = {15,16};
15) //待显示到数码管的2个数字
16) const uint8_t DATEx[] = {num/10,num%10};
17) uint8_t i;
18)
19) int start_flag=0; //是否开启倒计时标志位
20) int reset_flag=0; //复位倒计时数标志位
21) //-----------------------------------------------------------------
22) // 初始配置
23) //-----------------------------------------------------------------
24) void setup()
25) {
26) for(i=0;i<8;i++) //设置各引脚模式
27) pinMode(ledPins_SEG[i],OUTPUT);
28) for(i=0;i<2;i++)
29) pinMode(ledPins_DIG[i],OUTPUT);
30) for(i=10;i<13;i++)
31) {
32) pinMode(i,INPUT_PULLUP);
33) }
34) }
35) //-----------------------------------------------------------------
36) // 主循环
37) //-----------------------------------------------------------------
38) void loop()
39) {
40) const uint8_t DATEx[] = {num/10,num%10}; //待显示的两位数字
41)
42) for (i = 0; i 3; i++) //循环扫描数码管
43) {
44) DIG_OUTPUT(i); //操作位码
45) SEG_OUTPUT(CA_SEGCODE[DATEx[i]]); //操作段码
46) delay(1);
47) count++; //每延时1ms,count+1
48) key_scan(); //按键扫描子函数
49)
50) if(start_flag==1 && count>300) //当开启了倒计时,每300ms倒计时-1(本来是1000ms,这里为了演示效果调到了300)
51) {
52) num--; //倒计时数-1
53) count=0; //计数归零
54) }
55)
56) if(reset_flag==1) //当复位标志位为1
57) {
58) num=60; //倒计时数设置为60
59) reset_flag=0; //复位标志位归0
60) start_flag=0; //开始倒计时标志位归0
61) }
62)
63) if(num<0) //当倒计时完毕,倒计时数重新设置为60
64) num=60;
65) }
66)
67)
68)
69)
70) }
71) //-----------------------------------------------------------------
72) // 段码输出函数
73) //-----------------------------------------------------------------
74) void SEG_OUTPUT(uint8_t x) {
75) for (uint8_t j = 0; j 8; j++) { //发送段码
76) if((x>>j & 0x01) != 0x00)
77) digitalWrite(ledPins_SEG[j],HIGH);
78) else
79) digitalWrite(ledPins_SEG[j],LOW);
80) }
81) }
82) //-----------------------------------------------------------------
83) // 位码输出函数
84) //-----------------------------------------------------------------
85) void DIG_OUTPUT(uint8_t dx) {
86) for (uint8_t j = 0; j 2; j++) { //发送位码(2位)
87) if(dx != j)
88) digitalWrite(ledPins_DIG[j],LOW);
89) else
90) digitalWrite(ledPins_DIG[j],HIGH);
91) }
92) }
93)
94) void key_scan() //按键扫描子函数
95) {
96) if(digitalRead(start_key)==LOW) //当启动倒计时按键按下
97) {
98) delay(10); //消抖延时
99) if(digitalRead(start_key)==LOW)
100) start_flag=1; //开始倒计时标志位置位1。以下操作暂停按键、复位按键原理类似
101) }
102)
103) if(digitalRead(pause_key)==LOW)
104) {
105) delay(10);
106) if(digitalRead(pause_key)==LOW)
107) start_flag=0;
108) }
109)
110) if(digitalRead(reset_key)==LOW)
111) {
112) delay(10);
113) if(digitalRead(reset_key)==LOW)
114) reset_flag=1;
115) }
116) }
5) 软件操作
程序编写完成后点击Arduino IDE编译器的文件---首选项,将编译选项勾选上。点击好以后进行编译,编译完成后复制HEX文件所在的路径,复制完成后返回Proteus软件,双击Arduino控制板,在ProgramFile处粘贴HEX文件的路径。点击确定以后即可进行仿真,点击Proteus软件下方运行仿真按钮,可以看到仿真的效果。
源文件请关注公众号“STCode”获取~