本帖最后由 yuyy1989 于 2023-5-9 08:59 编辑
第10集,数码管的动态显示
多位数码管的同时显示是一位一位不停切换实现的,和视频的原理一样利用了人眼的视觉残留现象,最好保证整个数码管刷新耗时在20ms以内
没有试验箱也没有数码管,下面的代码没有经过验证
- #define LEDSEG_NUM 8 //数码管位数
- #define LEDSEG_COM_PORT P4 //共阳共阴控制端口,假设bit0-bi7控制1-8位
- #define LEDSEG_COMON_TYPE 0 //共阳共阴控制脚导通电平 0拉低导通 1拉高导通
- #define LEDSEG_LED_PORT P2 //假设bit0-bi7与abcdefg小数点依次相连
- #define LEDSEG_LEDON_TYPE 0 //led控制脚导通电平 0拉低导通 1拉高导通
- #define BEEP P54
- /*
- a
- ----
- f| g |b
- ----
- e| |c
- ---- .h
- d
-
- 字符 h g f e d c b a 16进制数值
- 0 0 0 1 1 1 1 1 1 0x3F
- 1 0 0 0 0 0 1 1 0 0x06
- 2 0 1 0 1 1 0 1 1 0x5B
- 3 0 1 0 0 1 1 1 1 0x4F
- 4 0 1 1 0 0 1 1 0 0x66
- 5 0 1 1 0 1 1 0 1 0x6D
- 6 0 1 1 1 1 1 0 1 0x7D
- 7 0 0 0 0 0 1 1 1 0x07
- 8 0 1 1 1 1 1 1 1 0x7F
- 9 0 1 1 0 1 1 1 1 0x6F
- - 0 1 0 0 0 0 0 0 0x40
- A 0 1 1 1 0 1 1 1 0x77
- b 0 1 1 1 1 1 0 0 0x7C
- c 0 1 0 1 1 0 0 0 0x58
- C 0 0 1 1 1 0 0 1 0x39
- d 0 1 0 1 1 1 1 0 0x5E
- E 0 1 1 1 1 0 0 1 0x79
- F 0 1 1 1 0 0 0 1 0x71
- H 0 1 1 1 0 1 1 0 0x76
- J 0 0 0 1 1 1 1 0 0x1E
- L 0 0 1 1 1 0 0 0 0x38
- o 0 1 0 1 1 1 0 0 0x5C
- P 0 1 1 1 0 0 1 1 0x73
- q 0 1 1 0 0 1 1 1 0x67
- U 0 0 1 1 1 1 1 0 0x3E
- t 0 1 1 1 1 0 0 0 0x78
- r 0 0 1 1 0 0 1 1 0x33
- 将对应的数值写入寄存器即可显示相应符号
- */
- const uint8_t ledsegnumdatas[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
- uint8_t currentdatas[LEDSEG_NUM] = {0};
- uint8_t currentseg = 0;
-
- uint16_t segcunter = 0;//计数0-9999 每10ms+1
- uint8_t segtimer = 0;//0-10
- uint8_t segkeycount = 0;//0初始状态 1计数 2停止
-
-
- //选择数码管的一位0-7
- void yuyy_segled_select(uint8_t seg)
- {
- uint8_t segdat = 0;
- if (seg < 8)
- {
- segdat = 1<<seg;
-
- #if(LEDSEG_COMON_TYPE == 0)
- segdat = ~segdat;
- #endif
- LEDSEG_COM_PORT = segdat;
- }
-
- }
- //数码管显示字符
- void yuyy_segled_showdat(uint8_t dat)
- {
- #if(LEDSEG_LEDON_TYPE == 0)
- dat = ~dat;
- #endif
- LEDSEG_LED_PORT = dat;
- }
- //刷新显示
- void yuyy_segled_show()
- {
- if(currentseg > 7)
- {
- currentseg = 0;
- }
- yuyy_segled_select(currentseg);
- yuyy_segled_showdat(currentdatas[currentseg]);
- currentseg++;
- }
- //控制小数点显示,bit0-1每个bit代表一个小数点
- void yuyy_segled_showdots(uint8_t dots)
- {
- uint8_t i=0;
- while (i<8)
- {
- if(dots&0x01)
- {
- currentdatas[i] |= 0x80;
- }
- else
- {
- currentdatas[i] &= 0x7F;
- }
- dots= dots>>1;
- i++;
- }
-
- }
- //设置指定位置的字符,传入符号对应的数值
- void yuyy_segled_shownumcharat(uint8_t num, uint8_t pos)
- {
- if(pos < 8)
- {
- currentdatas[pos] &= 0x80;
- currentdatas[pos] |= num;
- }
- }
- //设置指定位置的数字
- void yuyy_segled_show09numat(uint8_t num, uint8_t pos)
- {
- if(num < 10)
- {
- yuyy_segled_shownumcharat(ledsegnumdatas[num],pos);
- }
- if(num == 0xFF)
- {
- yuyy_segled_shownumcharat(0,pos);
- }
- }
- //显示4位数字 num 0000-9999 count数字位数 pos起始位置
- void yuyy_segled_shwownums(uint16_t num,uint8_t count,uint8_t pos)
- {
- uint8_t i=0,d=0;
- while (count<5 && i<count)
- {
- d = num % 10;
- yuyy_segled_show09numat(d,pos+i);
- num = num / 10;
- i++;
- }
- }
-
- //按下一次KEY0,开始计数,再按停止,再按重置
- void key0down_ledsegcounter()
- {
- if(KEY0 == 0)
- {
- delay_ms(10);//去抖
- if(KEY0 == 0)
- {
- if((keydown&0x01) == 0)
- {
- keydown |= 0x01;
- if(segkeycount == 0)
- {
- //开始计数
- segkeycount = 1;
- }
- else if(segkeycount == 1)
- {
- //停止计数
- segkeycount = 2;
- }
- else
- {
- //重置
- segkeycount = 0;
- segcunter = 0;
- yuyy_segled_shwownums(segcunter,4,0);
- }
- }
- }
- }
- else
- {
- keydown &= 0xFE;
- }
-
- if(segkeycount == 1 && segtimer == 10)
- {
- if(segcunter < 9999)
- {
- segcunter++;
- yuyy_segled_shwownums(segcunter,4,0);
- }
- segtimer = 0;
- }
- yuyy_segled_show();
- delay_ms(1);
- segtimer++;
- }
-
- //实战小练main部分
- yuyy_segled_shwownums(1000,4,4);
- yuyy_segled_shwownums(0,4,0);
- yuyy_segled_showdots(0x44);
- while(1)
- {
- key0down_ledsegcounter();
- }
-
- //课后练习简易时钟
- uint16_t clockms = 0; //毫秒
- uint8_t clocksec = 0; //秒
- uint8_t clockmin = 0; //分
- uint8_t clockhour = 0; //时
- void clocktest()
- {
- if(clockms == 1000)
- {
- clocksec++;
- clockms = 0;
- yuyy_segled_shwownums(clocksec,2,0);
- }
- if(clocksec == 60)
- {
- clockmin++;
- clocksec = 0;
- yuyy_segled_shwownums(clocksec,2,0);
- yuyy_segled_shwownums(clockmin,2,3);
- }
- if(clockmin == 60)
- {
- clockhour++;
- clockmin = 0;
- yuyy_segled_shwownums(clockmin,2,3);
- yuyy_segled_shwownums(clockhour,2,6);
- }
- if(clockhour == 24)
- {
- clockhour = 0;
- yuyy_segled_shwownums(clockhour,2,6);
- }
- if(clockhour == 0 && clockmin == 0 && clocksec == 30) // 00-00-30闹钟开始响
- {
- BEEP = 1;
- }
- if(clockhour == 0 && clockmin == 0 && clocksec == 33) // 00-00-33闹钟结束
- {
- BEEP = 0;
- }
- yuyy_segled_show();
- delay_ms(1);
- clockms++;
- }
-
- //课后练习的main部分
- yuyy_segled_showdots(0x00);
- yuyy_segled_shownumcharat(0x40,2);
- yuyy_segled_shownumcharat(0x40,5);
- yuyy_segled_shwownums(0,2,0);
- yuyy_segled_shwownums(0,2,3);
- yuyy_segled_shwownums(0,2,6);
- while(1)
- {
- clocktest();
- }
复制代码
|