arduino秒表编程

2018-09-12 08:25:28 TonyIOT 阅读数 8649

Arduino不但有外部中断,还有定时器中断,不同Arduino开发板其定时器数量及性能也各不相同,这取决于开发板主控制器。Uno R3开发板有三个定时器,本篇通过使用定时器库「TimerOne」来更新数码管显示,制作一个数字时钟。

Arduino提供了丰富的库,关于定时器的库包括「TimerOne」、「MsTimer2」等,更多的支持库的信息可从官网获取Libraries for Arduino

1. 定时器库安装

在IDE中点击「项目」—「加载库」—「管理库」,查找「TimerOne」进行安装。

安装库

2. 实验材料

  • Uno R3开发板
  • 配套USB数据线
  • 面包板及配套连接线
  • 四位共阴极数码管
  • 4个220Ω限流电阻

3. 实验步骤

1. 根据原理图搭建电路。

根据四位数码管的引脚图,a,b,c,d,e,f,g,dp引脚分别连接开发板的数字引脚7,6,5,10,11,8,9,4。数码管的1,2,3,4引脚分别串联220Ω限流电阻,电阻另一端分别连接开发板的数字引脚2,3,12,13。

实验原理图如下图所示:

实验原理图

实物连接图如下图所示:

实物连接图

2. 新建sketch,拷贝如下代码替换自动生成的代码并进行保存。

/*
   SevTimer
   使用定时器驱动四位数码管实现数字时钟显示
*/
#include "TimerOne.h"
#include "SevSeg.h"

SevSeg sevseg;

int Fen = 0;
int Miao = 0;

byte numDigits = 4; //数码管位数
byte digitPins[] = {2, 3, 12, 13}; //数码管公共极连接Arduino的引脚
byte segmentPins[] = {7, 6, 5, 10, 11, 8, 9, 4}; //数码管a,b,c,d,e,f,g,dp对应引脚
byte hardwareConfig = COMMON_CATHODE ; // 共阴极数码管

void setup() {
  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins); //初始化数码管

  Timer1.initialize(1000000);//初始化定时器为1s
  Timer1.attachInterrupt( timerIsr );//设置中断回调函数
}

void loop() {
  sevseg.setNumber(Fen * 100 + Miao, -1); //设置要显示的数据,不显示小数点
  sevseg.refreshDisplay(); // 必须重复运行刷新数码管显示
}

void timerIsr()//定时器中断处理函数
{
  Miao++;
  if (Miao > 59)
  {
    Miao = 0;
    Fen++;
    if (Fen > 59)
      Fen = 0;
  }
}

3. 连接开发板,设置好对应端口号和开发板类型,进行程序下载。

程序下载

4. 实验现象

数码管1秒计数一次,满60秒分钟加一,实现数字时钟效果。

实验现象

5. 实验分析

数码管驱动依旧使用「SevSeg」,具体使用方法在前面文章有所介绍。在setup()中使用 Timer1.initialize(1000000)来初始化定时器,括号内为定时周期,以微妙为单位,所以这里的1000000为1秒。然后使用Timer1.attachInterrupt( timerIsr )来设置中断回调函数。我们在程序中要实现timerIsr()函数,在里面实现分钟和秒数的控制。

有了定时器,有了数码管,我们可以很方便的实现一些跟时钟有关的制作,你可以结合数码管和蜂鸣器,来实现倒计时提示的制作。

更多内容,欢迎关注我的公众号。 微信扫一扫下方二维码即可关注:
扫码加入微信公众号:TonyCode

2019-10-25 11:02:46 weixin_42761713 阅读数 237

显示自定义字符串

代码模块图如下:
显示自定义字符串功能代码模块图
代码如下:

#include <SevenSegmentTM1637.h>

SevenSegmentTM1637  display(13,12);

void setup(){
   display.begin();
}

void loop(){
  display.print("2345678");

}

显示时钟

代码模块图如下:
显示时钟功能代码模块图

#include <SevenSegmentExtended.h>
#include <SevenSegmentTM1637.h>

SevenSegmentExtended  display(13,12);
volatile int min2;
volatile int oclock;

void setup(){
  oclock = 0;
  min2 = 0;
   display.begin();
}

void loop(){
  delay(6000);
  min2 = min2 + 1;
  if (min2 > 59) {
    oclock = oclock + 1;
    min2 = 0;

  }
  if (oclock > 23) {
    oclock = oclock == 0;

  }
  display.printTime(oclock,min2,HIGH);

}

显示秒表

代码模块图如下:
显示秒表功能代码模块图
代码如下:

#include <SevenSegmentExtended.h>
#include <SevenSegmentTM1637.h>

SevenSegmentExtended  display(13,12);
volatile int m_second;
volatile int second;

void setup(){
   display.begin();
  m_second = 0;
  second = 0;
  Serial.begin(9600);
}

void loop(){
  delay(11);
  m_second = m_second + 11;
  if (m_second >= 100) {
    second = second + 1;
    m_second = m_second - 100;

  }
  Serial.println(m_second);
  display.printTime(second,m_second,HIGH);

}
2015-06-01 13:12:16 wby20030316 阅读数 2883

arduino怎么做成秒表呢?同样,我天才地带来了程序。

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
  lcd.begin(16, 2);
}
void loop() {
  lcd.setCursor(0, 1);
  lcd.print(millis() / 1000);
}

这是一个较简单的程序,上传后,lcd上会显示秒数,就可以计时了。

2015-05-27 20:09:43 judyge 阅读数 3171

图1 Arduino单片机的Proteus仿真

 我的Arduino博客:http://www.eefocus.com/zhang700309/blog/

一、前言     

     Arduino是由Massimo Banzi,David Cuartielles,Tom Igoe,Gianluca Martino,David Mellis 和Nicholas Zambetti共同开发的。据说Auduino开发团队的领袖Massimo Banzi 之前是意大利Ivrea 一家高科技设计学校的老师。他的学生们经常抱怨找不到便宜好用的微控制器。2005年冬天,Massimo Banzi 跟David Cuartielles 讨论了这个问题。David Cuartielles 是一个西班牙籍芯片工程师,当时在这所学校做访问学者。两人决定设计自己的电路板,并引入了Banzi 的学生David Mellis 为电路板设计编程语言。两天以后,David Mellis 就写出了程式码。又过了三天,电路板就完工了。这块电路板被命名为Arduino。几乎任何人,即使不懂电脑编程,也能用Arduino 做出很酷的东西,比如对传感器作出回应,闪烁灯光,还能控制马达。

 

图2  Arduino开发团队(两个意大利人、两个美国人和一个西班牙人)

    Arduino 是一款便捷灵活、方便上手的开源电子原型平台,包含硬件(各种型号的arduino板)和软件(arduino IDE)。它适用于艺术家、设计师、爱好者和对于“互动”有兴趣的朋友们。

 Arduino可以用来开发交互产品,比如它可以读取大量的开关和传感器信号,并且控制各式各样的电灯、电机和其它物理设备,Arduino也可以开发与PC相连的外围设备,能在运行时与PC上的软件(比如Flash, Processing, MaxMSP)进行通信。

    Arduino硬件电路板可以根据共享图纸,自行焊接组装,也可以购买已经组装好的,软件则可以从Arduino网站免费下载使用。

     Arduino 1.0最新版下载地址:http://arduino.cc/en/Main/Software。  

图3  Arduino软硬件原型开发平台

       Arduino为啥这么红,我想Arduino单片机较其他微控制器有以下5点优势:1、您学习Arduino单片机可以完全不需要了解其内部硬件结构和寄存器设置,仅仅知道它的端口作用即可;所以不需要硬件知识,只要会C语言,就可立即为Arduino单片机编程。2、Arduino软件语言为精简指令系统,所需掌握的指令不多,但指令的功能却很强大,往往一条指令就可以完成一整套操作,而且指令的可读性也好,属于低门槛的语言,轻松上手,快速应用。3、针对周边I/O设备的Arduino编程,由于很多I/O设备都随之带有库文件或者样例程序,所以在自己的程序中,可以引用库文件中的函数,或复制样例程序,然后修改下其中的参数,即可迅速编写出大段大段的复杂程序,从而放大了您的编程能力。4、Arduino开源硬件在创客界十分流行。所谓开源产品定义,不仅是其软硬件底层信息完全公开,而且还在于产品的应用资讯可以从Arduino相关网站、博客里的大量共享资源里获得,所以在共享资讯的辅助下,能激发出您创意作品的灵感,并加快您创作作品的效率。5、国内在开源硬件的制造能力非常强,涌现出被意大利Arduino公司认可的代理商,如DFRobot、Seeed Studio公司,这些公司提供了丰富的质优、价廉Arduino及周边产品,所以在国内学习和应用Arduino具有得天独厚的硬件资源优势。

    但是如果是初学者,想先不花钱买硬件设备,那么是否也能体验下Arduino系统呢?通过仿真的方法是可以的,目前最流行的单片机仿真软件当属Proteus了,这篇文章就介绍用Proteus软件来仿真Arduino单片机的应用。

    Proteus软件是初学者入门的首选软件,它是英国Labcenter公司的一款商业版电路设计与仿真软件。它包括ISIS、ARES等软件模块。ARES模块主要用来完成PCB的设计,ISIS模块用来完成电路原理图的布图与仿真。Proteus的软件仿真基于VSM技术,它与其他软件最大的不同也是最大的优势就在于能仿真大量的单片机芯片,比如MCS-51系列、PIC系列等等,甚至ARM处理器,以及单片机外围I/O电路,比如键盘、LED、LCD等等。

 

二、Arduino单片机的Proteus仿真方法

    Arduino单片机的Proteus仿真基本过程是:软件在Arduino IDE编程软件里编写,硬件在Proteus ISIS软件模块里通过绘制电气原理图建立。程序编写完后,选择Arduino IDE编程界面菜单栏的Tools菜单项,再选择Board→Arduino Duemilanove w/ATmega328,也可以选择Board→Arduino Uno,然后点击编译按钮,生成Hex文件(二进制机器码文件)。有了Hex文件,接着转到Proteus电气原理图,双击原理图中的型号为ATMEGA328P 单片机芯片,出现对话框,通过文件目录浏览的方法确定Hex文件存储位置,并进行一些单片机芯片工作状态参数的设置,最后点击Proteus ISIS软件界面左下方的播放按钮,就可以看到Arduino单片机在Proteus仿真环境中的运行效果了。

图4 Arduino程序的编译

        图4中显示的程序是一个最简单的Arduino单片机项目实例,任务是:连在Arduino单片机数字端口13上的LED发光二级管,让它不断闪烁。要想成功仿真这个项目,有两点要特别注意,一是Arduino程序的Hex文件生成和位置确定,二是Proteus原理图中的Atmel328P芯片中Hex文件加载和工作参数设置。

图5 Arduino项目实例LED闪烁的硬件原理图

       Arduino编译之后,Hex文件会自动删除,而在Proteus仿真的Arduino单片机中,需要使用Arduino软件产生的Hex文件,可是,Arduino  1.0默认使用完Hex文件会自动删除的,所以取不到hex文件,为了取出hex文件,加载到Porteus中的单片机ATMEGA328P,需要修改如下:

     首先要在D盘建立一个文件夹,用来专门放置Hex文件,文件名可以随便取名,我命名为Arduino_Hex,然后点击Arduino软件界面菜单栏的File->preferences,打开对话框,如图6,把Show verbose output during的两个参数项打勾,双击preferences.txt文件,找到文件所在位置,再双击,用记事本打开文件。这时要点击Arduino界面preferences对话框下方的OK按钮,接着关掉Arduino IDE编程界面。最后,在刚才打开的preferences文档的最后一行编辑加入build.path=d:\Arduino_Hex,保存文档。这样以后您再编译Arduino程序,就可以在d:\Arduino_Hex中,看到编译的Hex目标文件了。(所有图片双击,都可以放大!

图6 Arduino的Preference参数设置

     谈完了Arduino程序的Hex文件生成和位置确定,再谈谈另一个值得注意的问题,Proteus原理图中Atmel328P芯片的Hex文件加载和工作参数设置。

     双击图5中的Proteus ISIS电气原理图中ATMEGA328P单片机,出现编辑对话框,点击“Program File”参数项的“文件夹”按钮,来确定Hex文件的位置,到d:\Arduino_Hex文件夹中可以找到当前程序的Hex文件。上个程序的Hex文件会被新编译的Hex文件“冲掉”,所以您每次仿真项目时,都要编译一次Arduino程序。

 

图7 Proteus中的ATMEGA328P单片机的Hex文件加载和参数设置

      确定了Hex文件,还有三个参数项要修订,一是“CLKDIV8(Divide clock by 8)”参数项修改为“Unprogrammed”;二是“CKSEL Fuses”参数项修改为“(1111)Ext. Crystal 8.0-MHz”;三是Advanced Properties的Clock Frequency参数项设为16Mhz。最后点击编辑对话框的“确定”按钮,然后就可以仿真了。

     网络上有一个Arduino单片机的Proteus仿真视频,讲解的就是图5所示LED灯闪烁的项目,可以看看Proteus电气原理图是如何建立,Arduino程序是如何编写,以及程序编译后是如何仿真的过程。只不过这个视频中,Arduino程序编译后的Hex文件,并没有在自己指定的文件目录里找到,而是还是用老办法在默认目录里找到。

 

三、Arduino单片机的Proteus仿真项目实例

       这个仿真项目实例的任务是:分别按下K1(正转)按钮、K2(反转)按钮和K3(停止)按钮,直流电机会分别产生相应的动作,而且当调节电位计时,电机的转速也随之发生变化。(所有图片双击,都可以放大!

图8 直流电机正反转、启停和调速仿真图

    图8中的电气符号用到了芯片元件、电源终端、虚拟仪器和连线标号,它们分别从各自的模式库中提取出来。

图9 仿真图中的电气符号的提取

    仿真图中,电源终端用到了VCC电源与接地符号,虚拟仪器用到了四通道示波器和直流电压表,连线标号的作用是相同连线标号的两根线在电气意义上是相连的,如图8中的标号A、B和PWM。至于芯片元件,仿真图里用到了电阻、电容、CPU、晶振、直流电机、稳压管、L298N驱动等等,芯片元件的提取通常有两种方法,父、子类别检索方法和关键字查询法。

    父、子类别检索方法是:先选择元件模式库,再点击“P”按钮,打开元件查询提取对话框,如图10所示,例如提取的元件是单片机芯片ATMEGA328P,先在类别里找到Microprocessor ICs,在子类别里找到AVR Family,再在制造商里找到Atmel,然后在缩小了寻找范围的结果中找到这个单片机芯片ATMEGA328P,找到后双击芯片,就可以把芯片提取到ISIS界面左侧的DEVICES栏中,供原理图绘制时随时选用,如图11所示。

图10 芯片元件的父、子类别检索法

     关键字查询法是:如果事先知道要提取的元件名称,可以在元件查询提取对话框左上方的关键字输入栏里输入元件名称,如搜寻motor元件,直接输入motor,回车后,在结果中可以很容易地找到所需元件。

图11 芯片元件的关键字查询法

    按照图8所示的直流电机控制电气原理图,把硬件线路绘制完成,剩下的事就是编写程序,编译仿真了,我设计的这个仿真项目正好把数字量和模拟量输入输出都涉及到了,按钮输入和驱动芯片L298N的电机转向控制端A、B是数字量输入输出,电位计输入和L298N的转速调节控制端PWM是模拟量输入输出。

    数字量输入输出的Arduino命令分别是digitalRead(数字端口号)和digitalWrite(数字端口号,LOW或HIGH);模拟量输入输出的Arduino命令是analogRead(模拟端口号)和analogWrite(数字端口号, 0~255)。模拟端口只有输入模式,没有输出模式,Arduino模拟量输出是以PWM信号形式从具有PWM输出功能的数字端口输出的。Arduino微控制器的数字端口和模拟端口与ATMEGA 328芯片引脚的对应关系图如下。标有0~13标号的引脚对应的是数字端口,在0~13前面有符号“~”的引脚对应的端口具有PWM输出功能。标有A0~A5标号的是模拟端口。

图12  Arduino UNO端口与Atmega328P引脚对应图

   有了Arduino UNO端口与Atmega328P引脚对应图,就可以方便地利用Proteus硬件仿真图,有针对性地编写Arduino程序了。由于以下程序中有详细的注释,所以对每行Arduino程序的作用就不再累述了。

Arduino程序:

 

//任务:通过按钮控制电机启停和正反转,通过电位计调节电机转速。

int K1=5;  //把K1(正转)按钮连在数字端口5
int K2=6;  //把K2(反转)按钮连在数字端口6
int K3=7;  //把K3(停止)按钮连在数字端口7
int potpin = 3; // 把电位计连在模拟端口3
int A=2;   //数字端口2、3控制电机启停和转向
int B=3;  
int PWMpin = 9; // 数字端口9输出PWM信号,控制电机转速
//初始化
void setup() 
{
   pinMode(K1,INPUT);//把数字端口5、6、7设置输入模式
   pinMode(K2,INPUT);
   pinMode(K2,INPUT);
   pinMode(A,OUTPUT);//把数字端口2、3设置输入模式
   pinMode(B,OUTPUT);
}
//主程序
void loop() 
{
   //如果按下K1(正转)按钮
  if(digitalRead(K1)==LOW)
  {
    //电机正转
    digitalWrite(A,HIGH);
    digitalWrite(B,LOW);
  }
  //如果按下K2(反转)按钮
  if(digitalRead(K2)==LOW)
  {
    //电机反转
    digitalWrite(A,LOW);
    digitalWrite(B,HIGH);
  }
  //如果按下K3(停止)按钮
  if(digitalRead(K3)==LOW)
  {
    //电机停止
    digitalWrite(A,LOW);
    digitalWrite(B,LOW);
  }
  int sensorValue = analogRead(potpin); //读取电位计采样值     
  sensorValue = sensorValue/4; // 采样值 0-1024 转换为 0-255
  analogWrite(PWMpin, sensorValue);//把处理后的转换值以PWM信号形式输出
  delay(20);//延时
}
Arduino程序及Proteus仿真图请下载:Arduino仿真之直流电机控制.zip
 
     把程序编写完,编译Hex文件,再把Hex文件加载到Proteus仿真图中Arduino单片机芯片中,最后点击仿真图左下方的播放按钮,就可以看到基于Arduino直流电机控制项目的运行效果了。

四、结束语

    经常有对创客文化感兴趣的网友,询问这样的问题,是否可以少投入些硬件成本,而又能用Arduino单片机多多做些趣味电子项目。所以这篇文章就是谈在资金不足的情况下,如何通过仿真的方法来实现我们创意实践。

    为啥有必要学习Arduino呢?其实许多学习者曾经为了追赶电子科技的进步,也花了大量的精力去一个个地学习那些微控制器和智能逻辑部件,如51、ARM,DSP和FPGA,当初仅仅是为做一些应用,没想会消耗那么多的时间和金钱,“陷在”了冷酷的程序和无止尽的硬件原理中,最后也只是做了些走马灯和数码管秒表实验,就草草结束,而又去追新了。这样追逐哪有什么利用微控制器做应用的乐趣可谈。好在目前秉承开放式学习架构的Arduino系统越来越流行,它可以让所有乐于创作的人在短时间之内就可以完成一个作品,并且可以透过网络,获得大量共享资讯的支援。您会发现,有了Arduino,微控制器的世界不再那么的陌生和令人敬畏,微控制器就是一个易用的工具,让我们能够腾出精力全力投向作品中最能体现个人创新精神的部分。

2018-01-02 22:36:49 qq_40724865 阅读数 3468

用arduino单片机与LCD1602显示屏做一个输出程序

LCD1602显示屏

这里写图片描述
VSS/GND–电源负
VDD/+5V–电源正
其余为数据引脚

要想使LCD1602显示屏显示不同的图形与文字,需要大量的c程序控制各个引脚的电平,幸好这些c程序早已有人写好,我们只需要引用一个宏(函数库)LiquidCrystal.h即可

电路

这里写图片描述
这是一种适用于LiquidCrystal.h的电路。如果电路与函数库不对应,将会出现乱码。

试验代码

#include <LiquidCrystal.h>
LiquidCrystal LCD(12,11,5,4,3,2);  //创建一个LiquidCrystal对象
//分别连到LCD的RS,ENABLE,DB4~DB7上
void setup() 
{
  LCD.begin(16,2); //初始化
  LCD.print("Hello Word!"); //在屏幕上显示helloworld
  LCD.setCursor(0,1); //把光标放在第1行第0列
/*________________
   X_______________
   ↑就是这里*/
  LCD.print(millis()); //显示开机后的毫秒数
}
void loop() 
{
  LCD.clear(); //清屏,光标回到原点
  for(int i=0;;i++)
   {
     LCD.print("the time is ");
     LCD.print(i);
     LCD.print("s");
     delay(998);
     LCD.clear();
   }
}

我的博客里的代码并非直接从编译器上拷贝的,所以如果发现编译错误,应当自己调试一下,因为程序很简单。

loop里的程序可以自己做一下创新和改动。非常有意思。

好啦,开始你的表演吧!