- /*
- 秒表程序,采用4位共阳数码管,为接线方便,把模拟口A0~A5改成数字口D14~D19,接数码管上面的6条线,这样基本消除了面包板上下区之间的跨接面包线。
- */
- //设置阳(阴)极接口,采用4位数码管
- int a = 15;//设置A1口连接数码管a段
- int b = 19;//设置A5口连接数码管b段
- int c = 7;//设置D7口连接数码管c段
- int d = 5;//设置D5口连接数码管d段
- int e = 4;//设置D4口连接数码管e段
- int f = 16;//设置A2口连接数码管f段
- int g = 8;//设置D8口连接数码管g段
- int dp = 6;//设置D6口连接数码管dp段
- //设置阳极接口
- int d1 = 14;//设置A0口连接第一个数码管公共阳极
- int d2 = 17;//设置A3口连接第二个数码管公共阳极
- int d3 = 18;//设置A4口连接第三个数码管公共阳极
- int d4 = 9;//设置D9口连接第四个数码管公共阳极
- //设置变量
- long n = 0;//设时间的自变量n
- int ptimer = 100;//改用此数值对时钟进行设置:100-0.1s,1000-1s,...
- int del = 45; //此处数值对时钟进行微调
- /***************************赋值数组******************************/
- byte segs[7] = { a, b, c, d, e, f, g };//除了小数点外的数码管7笔划段
- byte seven_seg_digits[10][7] = { { 1,1,1,1,1,1,0 },//设置数码管显示0的数组
- { 0,1,1,0,0,0,0 },//设置数码管显示1的数组
- { 1,1,0,1,1,0,1 },//设置数码管显示2的数组
- { 1,1,1,1,0,0,1 },//设置数码管显示3的数组
- { 0,1,1,0,0,1,1 },//设置数码管显示4的数组
- { 1,0,1,1,0,1,1 },//设置数码管显示5的数组
- { 1,0,1,1,1,1,1 },//设置数码管显示6的数组
- { 1,1,1,0,0,0,0 },//设置数码管显示7的数组
- { 1,1,1,1,1,1,1 },//设置数码管显示8的数组
- { 1,1,1,1,0,1,1 }//设置数码管显示9的数组
- };
- /*************************初始化设置函数***************************/
- void setup()
- {
- pinMode(d1, OUTPUT);
- pinMode(d2, OUTPUT);
- pinMode(d3, OUTPUT);
- pinMode(d4, OUTPUT);
- pinMode(a, OUTPUT);
- pinMode(b, OUTPUT);
- pinMode(c, OUTPUT);
- pinMode(d, OUTPUT);
- pinMode(e, OUTPUT);
- pinMode(f, OUTPUT);
- pinMode(g, OUTPUT);
- pinMode(dp, OUTPUT);//以上定义数码管所有引脚连线的单片机引脚为输出引脚
- }
- /**************************秒表主程序(循环)*****************************/
- void loop()//秒表主程序
- {
- clearLEDs();//数码管清屏
- pickDigit(1);//第一个数码管显示百秒数值
- lightSegments((n/ptimer/1000)%10);//n除以100,再除以1000,然后取除以10的余数,就得到秒表百位的数值
- delayMicroseconds(del);//百秒数字亮度
- clearLEDs();//数码管清屏
- pickDigit(2);//第二个数码管显示十秒数值
- lightSegments((n/ptimer/100)%10);//n除以100,再除以100,然后取除以10的余数,得到秒表十位的数值
- delayMicroseconds(del);//十秒数字亮度
- clearLEDs();//清屏
- pickDigit(3);//第三个数码管显示个位数值
- dispDec(3);//开启第三个数码管小数点
- lightSegments((n/ptimer/10)%10);//n除以100,再除以10,然后取除以10的余数,得到秒表个位的数值
- delayMicroseconds(del);//个位数字亮度
- clearLEDs();//数码管清屏
- pickDigit(4);//第四个数码管显示十分位住址
- lightSegments(n/ptimer%10); //n除以100,再取除以10的余数,就得到秒表十分位的数值
- delayMicroseconds(del);//十分位数字亮度
- n++;//计时
- }
- /**************************开启数码管子函数****************************/
- void pickDigit(int x) //定义pickDigit(x),其作用是开启数码管
- {
- digitalWrite(d1, 1-HIGH);
- digitalWrite(d2, 1-HIGH);
- digitalWrite(d3, 1-HIGH);
- digitalWrite(d4, 1-HIGH);
- switch(x)
- {
- case 1:
- digitalWrite(d1, (n>100000)-LOW); //小于100秒该数码管不亮
- break;
- case 2:
- digitalWrite(d2, (n>10000)-LOW); //小于10秒该数码管不亮
- break;
- case 3:
- digitalWrite(d3, 1-LOW); //秒表个位数数码管
- break;
- default:
- digitalWrite(d4, 1-LOW);
- break;
- }
- }
- /*************************开启小数点子函数**************************/
- void dispDec(int x) //设定开启小数点
- {
- digitalWrite(dp, 1-HIGH);//点亮小数点
- }
- /***********************数码管清屏子函数**************************/
- void clearLEDs()
- {
- digitalWrite(a, 1-LOW);
- digitalWrite(b, 1-LOW);
- digitalWrite(c, 1-LOW);
- digitalWrite(d, 1-LOW);
- digitalWrite(e, 1-LOW);
- digitalWrite(f, 1-LOW);
- digitalWrite(g, 1-LOW);
- digitalWrite(dp, 1-LOW);//将数码管所有管脚置高,数码管是共阳数码管,即将所有管脚熄灭
- }
- /**********************点亮对应数字的数码管子函数***********************/
- void lightSegments(int x)
- {
- for (int i = 0; i < 7; i++)
- {
- digitalWrite(segs[i], 1-seven_seg_digits[x][i]);//对于共阴极的笔画段设置,这里要用1-的算术,改成共阳极数码管的正确显示
- }
- }
复制代码
【效果】最终效果图如下