找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3854|回复: 7
收起左侧

关于单片机+74HC164芯片控制数码管有很明显跳动的疑问

[复制链接]
ID:376199 发表于 2019-2-28 22:12 | 显示全部楼层 |阅读模式
本人用单片机驱动74HC164芯片串入并出驱动数码管,结果发现数码管显示一直有很明显跳动
QQ截图20190228220845.png

我认为是我的serial_Output函数有问题,于是加了个_nop_()延时,可是抖动还是很明显,本人想不出如何修改,望指教

单片机源码:
  1. #include<reg51.h>
  2. #include<intrins.h>
  3. #define u8 unsigned char
  4. #define u16 unsigned int

  5. u8 code seg[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0xff};
  6. const u16 m[] = {10000, 1000, 100, 10};                                                          //数位分解所用权值表
  7. u16 val = 42950;                                                                                                  //所演示的起始值
  8. u8 Buf[5];                                                                                                                  //分解以后的存放缓冲
  9. sbit DAT = P3^4;                                                                                                  //串行数据线
  10. sbit CLK = P3^7;                                                                                                  //串行时钟线

  11. void delayms(u8 ms)
  12. {
  13.         u8 i;

  14.         while(ms--)
  15.                 for(i = 0; i < 120; i++);
  16. }

  17. void Decompose(u16 x, u8 d[])
  18. {                                                                                                                                   //分解整数x
  19.         u8 i;

  20.         for(i = 0; i < 4; i++)
  21.         {
  22.                 d[i] = 0;
  23.                 while(x >= m[i]) {x -= m[i]; d[i]++;}
  24.         }
  25.         d[4] = x;
  26. }

  27. void serial_Output(u8 d)                                                                                  //模拟时序向74HC164串行输出1字节数据
  28. {
  29.         u8 i;

  30.         for(i = 0; i < 8; i++)
  31.         {
  32.                 CLK = 0;
  33.                 d <<= 1; DAT = CY;                                                                                  //移出一位,高位优先
  34.                 _nop_();                                                                                                  //加延时修补
  35.                 CLK = 1;                                                                                                  //上升沿移入数据
  36.         }
  37. }

  38. void main()
  39. {
  40.         u8 i;

  41.         while(1)
  42.         {
  43.                 Decompose(val, Buf);                                                                          //分解显示数据val
  44.                 for(i = 4; i != 0xff; i--)                                                                  //串行发送各数字段码
  45.                 {
  46.                         
  47.                         serial_Output(seg[Buf[i]]);
  48.                         //delayms(2);
  49.                 }                                                         
  50.                 delayms(500);
  51.                 val++;
  52.         }
  53. }
复制代码


回复

使用道具 举报

ID:246917 发表于 2019-3-1 01:18 | 显示全部楼层
delayms(500)时间太长了,缩短到10ms左右再试试,多次刷新利用余辉
回复

使用道具 举报

ID:479009 发表于 2019-3-1 03:58 | 显示全部楼层
把164换成595吧,164每次移位都会输出,前面7次输出的值都不是你想要的
回复

使用道具 举报

ID:245053 发表于 2019-3-1 10:08 | 显示全部楼层
视频每秒24帧,也就是说每秒刷新了24幅图片人眼才不会感觉到画面闪烁。动态刷新数码管一样,也需在1秒内刷新24遍,才会感觉不到闪烁,自己算:1/24秒内要刷新完你的数码管,每一个数码管的时间多少。。。
回复

使用道具 举报

ID:213173 发表于 2019-3-1 11:13 | 显示全部楼层
主要原因是你消隐没有处理好,在传输段码过程中要关闭数码管。否则在仿真时会闪烁,在实际电路中可能会有鬼影。给你把程序修改了一下就正常了。

无标题.jpg


  1. #include<reg51.h>
  2. #include<intrins.h>
  3. #define u8 unsigned char
  4. #define u16 unsigned int

  5. u8 code seg[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0xff, 0xaa};
  6. const u16 m[] = {10000, 1000, 100, 10};//数位分解所用权值表
  7. u16 val = 42950;  //所演示的起始值                                                                                                                 //分解以后的存放缓冲
  8. u8 Buf[5];
  9. sbit DAT = P3^4; //串行数据线
  10. sbit CLK = P3^7; //串行时钟线
  11. sbit Hide= P3^5; //消隐

  12. void delayms(u16 ms)
  13. {
  14.         u8 i;        
  15.         while(ms--)
  16.                 for(i = 0; i < 120; i++);
  17. }

  18. void Decompose(u16 x, u8 d[])   //分解显示数据val
  19. {                                                                                                                                   //分解整数x
  20.         u8 i;        
  21.         for(i=0;i<4;i++)
  22.         {
  23.                 d[i]= 0;
  24.                 while(x>=m[i])
  25.                 {
  26.                         x -= m[i];
  27.                         d[i]++;
  28.                 }
  29.         }
  30.         d[4] = x;
  31. }

  32. void serial_Output(u8 d)//模拟时序向74HC164串行输出1字节数据
  33. {
  34.         u8 i;
  35.         for(i=0;i<8;i++)
  36.         {
  37.                 d <<= 1;
  38.                 DAT = CY; //移出一位,高位优先
  39.                 CLK = 0;
  40.                 CLK = 1; //上升沿移入数据
  41.         }
  42. }

  43. void main()
  44. {
  45.         u8 i;
  46.         while(1)
  47.         {
  48.                 Decompose(val, Buf);    //分解显示数据val
  49.                 Hide=0;//消隐,关闭数码管电源
  50.                 for(i = 4; i != 0xff; i--) //串行发送各数字段码
  51.                 {
  52.                         serial_Output(seg[Buf[i]]);
  53.                         //delayms(2);
  54.                 }
  55.                 Hide=1;//打开数码管电源
  56.                 delayms(500);//延时u8最大255,改为u16
  57.                 val++;
  58.         }
  59. }
复制代码


回复

使用道具 举报

ID:213173 发表于 2019-3-1 14:53 | 显示全部楼层
为什么代码传上来回丢掉好些方括号???管理员知道这个问题吗???
回复

使用道具 举报

ID:1 发表于 2019-3-1 15:11 | 显示全部楼层
wulin 发表于 2019-3-1 14:53
为什么代码传上来回丢掉好些方括号???管理员知道这个问题吗???
1.png
您好,代码用这个框起来就不会丢失[ i]和[ b]了,或者改为[ i]和[ b](中间加个空格)

样例子


  1. 代码[i]
  2. 代码[i]
  3. 代码[i]
  4. 代码[i]
  5. 代码[i]
  6. 代码[i]

复制代码




回复

使用道具 举报

ID:213173 发表于 2019-3-1 15:18 | 显示全部楼层
admin 发表于 2019-3-1 15:11
您好,代码用这个框起来就不会丢失[ i]和[ b]了,或者改为[ i]和[ b](中间加个空格)

样例子

谢谢指教
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表