【1.背景介绍】
使用arduino控制4段数码管显示数值,常用方法是在一个循环中不停刷新各数码管的值,使用余晖效应,显示4位数值。但是这种在循环中不停刷新的方式使得主程序很难再做别的事情,一种解决方法是使用定时中断来刷新4段数码管显示的值,这样主程序可以空闲出来处理别的事情。
【2.硬件连接】
这里的4段数码管采用的是共阳数码管,型号:MSQC6412C,采用arduino uno控制板。数码管引脚定义以及和arduino主控帮的链接方式如图1所示。
图1
【3.自定义mblock扩展】
这里使用mblock图形环境来编写程序。需要开发相应的扩展模块。此外,本程序中使用MsTimer2时钟产生定时中断,因此需要在arduino IDE中加载MsTimer2标准库。(加载方法:打开mblock自带的arduino IDE,搜搜MsTimer2标准库,然后安装)
自定义的4段数码管扩展只支持arduino模式,不支持Scratch模式,扩展压缩包中包括Seg4_led.s2e文件和src文件夹,src文件夹中包括demo.cpp,demo.h,seg4_led.c,seg4_led.h,相应的文件内容如下:
Seg4_led.s2e:
-
{
-
"extensionName": "SEG4_LED",
-
"description": "SEG4_LED for common anode",
-
"version": "1.1",
-
"author": "yoyoba(stuyou@126.com)",
-
"homepage": "youhaidong.cn",
-
"sort":0,
-
"javascriptURL":"",
-
"firmware":"1.0",
-
"extensionPort":0,
-
"tags" : "makeblock,seg4_led",
-
"blockSpecs": [
-
[
-
"w",
-
"seg4_led_init( %n , %n , %n , %n , %n , %n , %n , %n , %n , %n , %n , %n )",
-
"seg4_led_init",
-
"2",
-
"3",
-
"4",
-
"5",
-
"6",
-
"7",
-
"8",
-
"14",
-
"15",
-
"16",
-
"17",
-
"18",
-
{
-
"setup":"",
-
"inc":"#include \"demo.h\" \n #include ", //添加<MsTimer2.h>头文件
-
"def":"DemoClass demo; \n",
-
"work":"demo.seg4_led_init({0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11}); \n",
-
"loop":""
-
}
-
],
-
[
-
"w",
-
"seg4_led_display( %n )",
-
"seg4_led_display",
-
"1234",
-
{
-
"setup":"",
-
"inc":"#include \"demo.h\"",
-
"def":"DemoClass demo; \n",
-
"work":"demo.seg4_led_display({0}); \n",
-
"loop":""
-
}
-
],
-
],
-
"translators":{
-
"zh_CN":{
-
"seg4_led_init( %n , %n , %n , %n , %n , %n , %n , %n , %n , %n , %n , %n )":"4段共阳数码管初始化( %n , %n , %n , %n , %n , %n , %n , %n , %n , %n , %n , %n )",
-
"seg4_led_display( %n )":"4段共阳数码管显示数值( %n )"
-
}
-
}
-
}
demo.h文件内容:
-
#ifndef demo_h
-
#define demo_h
-
-
#include <Arduino.h>
-
///@brief Class for DemoClass
-
class DemoClass
-
{
-
public:
-
-
DemoClass();
-
~DemoClass();
-
-
// 4段LED共阳数码管引脚初始化函数
-
// con1~con4为数码管4个共阳引脚使用的arduino数字I/O口;
-
// a~dp为数码管a~dp引脚使用的arduino数字I/O口
-
void seg4_led_init(int con1,int con2,int con3,int con4,
-
int a,int b,int c,int d,int e,int f,int g,int dp);
-
-
// 4段共阳数码管显示数值num
-
void seg4_led_display(int num);
-
-
private:
-
};
-
-
#endif
demo.cpp文件内容
-
#include "demo.h"
-
#include "seg4_led.h"
-
#include <MsTimer2.h>
-
//添加arduino MsTimer2中断头文件
-
DemoClass::DemoClass(){//构造函数
-
pinMode(13,OUTPUT);
-
}
-
DemoClass::~DemoClass()//析构函数
-
{
-
MsTimer2::stop();//停止mstime2时钟中断
-
}
-
-
// 4段共阳数码管初始化函数,初始化函数完成如下功能:
-
// 1.根据硬件连接,确定4段共阳数码管12个引脚使用的arduino I/O口
-
// 这里con1/con2/con3/con4,分别对应共阳数码管的4个阳极公共端,
-
// con1对应最右边一个数码管的阳极;con4对应最左边一个数码管的阳极
-
// 2.启动mstime2 定时中断,为了实现4位数码管同时显示,这里
-
// 采用定时中断,每15ms 刷新一次4段数码管
-
void DemoClass::seg4_led_init(int con1, int con2, int con3, int con4, int a, int b, int c, int d, int e, int f, int g, int dp)
-
{
-
SEG4_con1=con1;
-
SEG4_con2=con2;
-
SEG4_con3=con3;
-
SEG4_con4=con4;
-
SEG4_a=a;
-
SEG4_b=b;
-
SEG4_c=c;
-
SEG4_d=d;
-
SEG4_e=e;
-
SEG4_f=f;
-
SEG4_g=g;
-
SEG4_dp=dp;
-
pinMode(SEG4_con1,OUTPUT);
-
pinMode(SEG4_con2,OUTPUT);
-
pinMode(SEG4_con3,OUTPUT);
-
pinMode(SEG4_con4,OUTPUT);
-
pinMode(SEG4_a,OUTPUT);
-
pinMode(SEG4_b,OUTPUT);
-
pinMode(SEG4_c,OUTPUT);
-
pinMode(SEG4_d,OUTPUT);
-
pinMode(SEG4_e,OUTPUT);
-
pinMode(SEG4_f,OUTPUT);
-
pinMode(SEG4_g,OUTPUT);
-
pinMode(SEG4_dp,OUTPUT);
-
// 设置mstime2时钟中断的刷新频率和ISR
-
MsTimer2::set(15,isr_led8_4seg);
-
// 启动mstime2中断。
-
MsTimer2::start();
-
}
-
-
// 数码管显示函数,计算num的千位、百位、十位和个位。
-
void DemoClass::seg4_led_display(int num)
-
{
-
k_num=num/1000;
-
h_num=(num/100)%10;
-
d_num=(num/10)%10;
-
g_num=(num)%10;
-
}
seg4_led.h文件内容
-
#ifndef SEG4_LED__H__
-
#define SEG4_LED__H__
-
-
#ifdef __cplusplus
-
extern "C"
-
{
-
#endif//__cplusplus
-
-
// 声明使用的全局变量和数码管显示码表
-
extern int k_num,h_num,d_num,g_num;
-
extern int SEG4_con1,SEG4_con2,SEG4_con3,SEG4_con4,
-
SEG4_a,SEG4_b,SEG4_c,SEG4_d,SEG4_e,SEG4_f,SEG4_g,SEG4_dp;
-
extern unsigned char t_table[10][8];
-
-
-
void isr_led8_4seg();
-
void con_display(int con, int num);
-
-
#ifdef __cplusplus
-
}
-
#endif//__cplusplus
-
-
#endif
seg4_led.c文件内容
-
#include <Arduino.h>
-
#include "seg4_led.h"
-
-
#ifdef __cplusplus
-
extern "C"
-
{
-
#endif//__cplusplus
-
// 全局变量k_num,h_num,d_num,g_num分别存放
-
// 4段共阳数码管显示的数值的千位、
-
// 百位、十位、个位
-
int k_num=0,h_num=0,d_num=0,g_num=0;
-
-
// 全局变量SEG4_X用来存放seg4_led_init()函数初始化的
-
// 4段共阳数码管使用的I/O引脚号。
-
int SEG4_con1,SEG4_con2,SEG4_con3,SEG4_con4,
-
SEG4_a,SEG4_b,SEG4_c,SEG4_d,SEG4_e,SEG4_f,SEG4_g,SEG4_dp;
-
-
// 共阴数码管显示码表,使用时需要转换为共阳码表
-
unsigned char table[10][8]=
-
{
-
{0,0,1,1,1,1,1,1},//0
-
{0,0,0,0,0,1,1,0},// 1
-
{0,1,0,1,1,0,1,1},// 2
-
{0,1,0,0,1,1,1,1},// 3
-
{0,1,1,0,0,1,1,0},// 4
-
{0,1,1,0,1,1,0,1},// 5
-
{0,1,1,1,1,1,0,1},// 6
-
{0,0,0,0,0,1,1,1},// 7
-
{0,1,1,1,1,1,1,1},// 8
-
{0,1,1,0,1,1,1,1},// 9
-
};
-
-
-
#ifdef __cplusplus
-
}
-
#endif//__cplusplus
-
-
// mstime2时钟中断服务函数
-
void isr_led8_4seg()
-
{
-
if(k_num>0){
-
con_display(4,k_num);
-
delay(3);//延迟3ms
-
con_display(3,h_num);
-
delay(3);
-
con_display(2,d_num);
-
delay(3);
-
con_display(1,g_num);
-
delay(3);
-
}
-
else if(h_num>0){
-
con_display(4,0);
-
delay(3);
-
con_display(3,h_num);
-
delay(3);
-
con_display(2,d_num);
-
delay(3);
-
con_display(1,g_num);
-
delay(3);
-
}
-
else if(d_num>0){
-
con_display(4,0);
-
delay(3);
-
con_display(3,0);
-
delay(3);
-
con_display(2,d_num);
-
delay(3);
-
con_display(1,g_num);
-
delay(3);
-
}
-
else {
-
con_display(4,0);
-
delay(3);
-
con_display(3,0);
-
delay(3);
-
con_display(2,0);
-
delay(3);
-
con_display(1,g_num);
-
delay(3);
-
}
-
}
-
-
// 指定第con个数码管显示num
-
//con取值1~4,con=1,最右边一个数码管
-
// con=4,最左边一个数码管
-
void con_display(int con, int num)
-
{
-
//所有的数码管熄灭,消除"鬼影"
-
digitalWrite(SEG4_a,LOW);
-
digitalWrite(SEG4_b,LOW);
-
digitalWrite(SEG4_c,LOW);
-
digitalWrite(SEG4_d,LOW);
-
digitalWrite(SEG4_e,LOW);
-
digitalWrite(SEG4_f,LOW);
-
digitalWrite(SEG4_g,LOW);
-
digitalWrite(SEG4_dp,LOW);
-
-
//根据con的值,把相应数码管的共阳极置高电平
-
switch(con){
-
case 1:
-
digitalWrite(SEG4_con1,HIGH);
-
digitalWrite(SEG4_con2,LOW);
-
digitalWrite(SEG4_con3,LOW);
-
digitalWrite(SEG4_con4,LOW);
-
break;
-
case 2:
-
digitalWrite(SEG4_con1,LOW);
-
digitalWrite(SEG4_con2,HIGH);
-
digitalWrite(SEG4_con3,LOW);
-
digitalWrite(SEG4_con4,LOW);
-
break;
-
case 3:
-
digitalWrite(SEG4_con1,LOW);
-
digitalWrite(SEG4_con2,LOW);
-
digitalWrite(SEG4_con3,HIGH);
-
digitalWrite(SEG4_con4,LOW);
-
break;
-
case 4:
-
digitalWrite(SEG4_con1,LOW);
-
digitalWrite(SEG4_con2,LOW);
-
digitalWrite(SEG4_con3,LOW);
-
digitalWrite(SEG4_con4,HIGH);
-
break;
-
-
}
-
-
//第con个LED数码管显示num,
-
//由于table是共阴码值表,这里使用的是共阳数码管;
-
// 因此这里需要用1减去其值。
-
digitalWrite(SEG4_a,1-table[num][7]);
-
digitalWrite(SEG4_b,1-table[num][6]);
-
digitalWrite(SEG4_c,1-table[num][5]);
-
digitalWrite(SEG4_d,1-table[num][4]);
-
digitalWrite(SEG4_e,1-table[num][3]);
-
digitalWrite(SEG4_f,1-table[num][2]);
-
digitalWrite(SEG4_g,1-table[num][1]);
-
digitalWrite(SEG4_dp,1-table[num][0]);
-
-
}
【4.使用扩展】
把该扩展导入mblock中,在mblock扩展菜单中选中"SEG4_LED"扩展,就能在机器人模块中出现SEG4_LED扩展及其相应的语句。这里对4段共阳数码管的操作只实现了两个语句,即“4段共阳数码管初始化”和“4段共阳数码管显示数值”。使用mblock编写测试程序,下载到arduino运行,正常。如图2所示。实际运行如图3所示。
图2
图3
【5.注意事项】
本程序中使用了很多全局变量,这些全局变量都定义在seg4_led.c文件中。
-
// 全局变量k_num,h_num,d_num,g_num分别存放
-
// 4段共阳数码管显示的数值的千位、
-
// 百位、十位、个位
-
int k_num=0,h_num=0,d_num=0,g_num=0;
-
-
// 全局变量SEG4_X用来存放seg4_led_init()函数初始化的
-
// 4段共阳数码管使用的I/O引脚号。
-
int SEG4_con1,SEG4_con2,SEG4_con3,SEG4_con4,
-
SEG4_a,SEG4_b,SEG4_c,SEG4_d,SEG4_e,SEG4_f,SEG4_g,SEG4_dp;
-
-
// 共阴数码管显示码表,使用时需要转换为共阳码表
-
unsigned char table[10][8]=
-
{
-
{0,0,1,1,1,1,1,1},//0
-
{0,0,0,0,0,1,1,0},// 1
-
{0,1,0,1,1,0,1,1},// 2
-
{0,1,0,0,1,1,1,1},// 3
-
{0,1,1,0,0,1,1,0},// 4
-
{0,1,1,0,1,1,0,1},// 5
-
{0,1,1,1,1,1,0,1},// 6
-
{0,0,0,0,0,1,1,1},// 7
-
{0,1,1,1,1,1,1,1},// 8
-
{0,1,1,0,1,1,1,1},// 9
-
};
然后在seg4_led.h中使用extern声明这些全局变量,别的cpp文件/c文件如果要使用这些全局变量,直接包含seg4_led.h文件即可。
-
// 声明使用的全局变量和数码管显示码表
-
extern int k_num,h_num,d_num,g_num;
-
extern int SEG4_con1,SEG4_con2,SEG4_con3,SEG4_con4,
-
SEG4_a,SEG4_b,SEG4_c,SEG4_d,SEG4_e,SEG4_f,SEG4_g,SEG4_dp;
-
extern unsigned char t_table[10][8];
如果把这些全局变量直接定义在seg4_led.h头文件中,则链接时容易造成“全局变量重复定义”错误。
使用全局变量的一个原则:全局变量最好在.cpp/.C文件中定义,在.h文件中加上extern申明,因为在.h文件中定义,容易在链接时造成变量重定义。具体请参考:https://blog.csdn.net/xxxxxx91116/article/details/7446455
Seg4_led.zip seg4_led扩展
阅读(1495) | 评论(0) | 转发(0) |