7289|7

60

帖子

0

TA的资源

纯净的硅(初级)

楼主
 

纯属好玩,基于STC51的4位数码管驱动模块 [复制链接]

本帖最后由 karajanlee 于 2014-1-17 16:05 编辑

如题,真的是纯属好玩,用串口接收数据,单独的MCU来显示数据,所以不会闪烁,可以减轻主MCU的运算压力。。哈哈。。

电路图


洞洞板效果,数码管叠在MCU上。。。


  1. /**
  2. * 基于STC15W204S的串口4位LED驱动模块
  3. *
  4. * 串口波特率:         9600 bps
  5. * 单次发送数据长度:   8 位
  6. * 格式:
  7. *      字符索引1 控制位1 ... 字符索引4 控制位4
  8. * 字符索引列表:
  9. *      00 -> 0, 01 -> 1, 02 -> 2, 03 -> 3, 04 -> 4,
  10. *      05 -> 5, 06 -> 6, 07 -> 7, 08 -> 8, 09 -> 9,
  11. *      0A -> -, 0B -> A, 0C -> b, 0D -> c, 0E -> d,
  12. *      0F -> E, 10 -> F, 11 -> g, 12 -> H, 13 -> J,
  13. *      14 -> L, 15 -> n, 16 -> o, 17 -> p, 18 -> q,
  14. *      19 -> r, 1A -> S, 1B -> t, 1C -> U, 1D -> y,
  15. * 控制位:
  16. *     -----------------------------------------------------------
  17. *     | 7 | 6 | 5 | 4 | 3 | 2 | 1            | 0                |
  18. *     |---------------------------------------------------------|
  19. *     | x | x | x | x | x | x | 0/1          | 0/1              |
  20. *     |---------------------------------------------------------|
  21. *     |                     0:| 不显示小数点 | 不显示当前位字符 |
  22. *     |                     1:| 显示小数点   | 显示当前位字符   |
  23. *     -----------------------------------------------------------
  24. *
  25. * No license applied. Use as you wish.
  26. * Happy Coding!
  27. *
  28. * 2014 (c) K% Design
  29. * by HouYu Li <lihouyu@phpex.net>
  30. */

  31. #include <INTRINS.H>
  32. #include <STC/STC15F2K60S2.H>

  33. sbit CommD1 = P1 ^ 1;   // 数字1(最高位)共阴极 P1.1
  34. sbit CommD2 = P3 ^ 6;   // 数字2共阴极 P3.6
  35. sbit CommD3 = P3 ^ 3;   // 数字3共阴极 P3.3
  36. sbit CommD4 = P5 ^ 5;   // 数字4共阴极 P5.5

  37. unsigned char MaskCommD1 = 0x02;    // 数字1共阴极Byte表示形式
  38. unsigned char MaskCommD2D3 = 0x48;  // 数字2,3共阴极合并Byte表示形式
  39. unsigned char MaskCommD4 = 0x20;    // 数字4共阴极Byte表示形式
  40. unsigned char UARTPINEN = 0x03;     // 置高P3.0, P3.1使串口工作正常

  41. /**
  42. * 以下是各个字符的段码,由于没有足够的IO,并简化了硬件连接
  43. * 所以导致需要三组端口配合来实现字符显示
  44. */
  45. unsigned char P1SEG[30] =   {0x2D, 0x20, 0x0D, 0x29, 0x20,
  46.                             0x29, 0x2D, 0x21, 0x2D, 0x29,
  47.                             0x00, 0x25, 0x2C, 0x0C, 0x2C,
  48.                             0x0D, 0x05, 0x29, 0x24, 0x28,
  49.                             0x0C, 0x24, 0x2C, 0x05, 0x21,
  50.                             0x04, 0x29, 0x0C, 0x2C, 0x28};
  51. /* 为了节约内存,改用switch选择语句
  52. unsigned char P3SEG[30] =   {0x84, 0x04, 0x04, 0x04, 0x84,
  53.                             0x80, 0x80, 0x04, 0x84, 0x84,
  54.                             0x00, 0x84, 0x80, 0x00, 0x04,
  55.                             0x80, 0x80, 0x84, 0x84, 0x04,
  56.                             0x80, 0x00, 0x00, 0x84, 0x84,
  57.                             0x00, 0x80, 0x80, 0x84, 0x84};
  58. unsigned char P5SEG[30] =   {0x00, 0x00, 0x10, 0x10, 0x10,
  59.                             0x10, 0x10, 0x00, 0x10, 0x10,
  60.                             0x10, 0x10, 0x10, 0x10, 0x10,
  61.                             0x10, 0x10, 0x10, 0x10, 0x00,
  62.                             0x00, 0x10, 0x10, 0x10, 0x10,
  63.                             0x10, 0x10, 0x10, 0x00, 0x10};
  64. */
  65. /** // */

  66. // 串口接收数据缓存
  67. unsigned char UARTBUFF[8] = {0, 0x01, 0, 0x03, 0, 0x01, 0, 0x01};
  68. // 串口接收自己位置索引
  69. unsigned char idxUARTBUFF = 0;
  70. // 存放显示数据
  71. unsigned char DISPBUFF[8] = {1, 0x01, 2, 0x03, 3, 0x01, 4, 0x01};
  72. // 接收数据长度
  73. unsigned char BUFFLEN = 8;
  74. // 数据是否接受完毕
  75. char RXDONE = 0;
  76. //char TXBUSY = 0;

  77. void initIO();

  78. void showChar(unsigned char idx, unsigned char segidx, unsigned char ctrl);

  79. /**
  80. * 以下代码由STC刷机工具生成
  81. */
  82. void Delay1ms();
  83. void initUart(void);

  84. void Delay1ms()                //@11.0592MHz
  85. {
  86.         unsigned char i, j;

  87.         _nop_();
  88.         _nop_();
  89.         _nop_();
  90.         i = 11;
  91.         j = 190;
  92.         do
  93.         {
  94.                 while (--j);
  95.         } while (--i);
  96. }

  97. void initUart(void) //9600bps@11.0592MHz
  98. {
  99.         SCON = 0x50;    //8位数据,可变波特率
  100.         AUXR |= 0x04;   //定时器2时钟为Fosc,即1T
  101.         T2L = 0xE0;                //设定定时初值
  102.         T2H = 0xFE;                //设定定时初值
  103.         AUXR |= 0x01;   //串口1选择定时器2为波特率发生器
  104.         AUXR |= 0x10;   //启动定时器2
  105.    
  106.     // 以下2行代码自行添加
  107.     EA = 1;         //启用系统总中断和串口中断
  108.     ES = 1;
  109. }
  110. /** // */

  111. /**
  112. * 初始化IO
  113. */
  114. void initIO() {
  115.     // 将所有驱动LED的IO设置成强推挽模式
  116.     // 除了P3.0, P3.1
  117.     P1M0 = 0x3D + MaskCommD1;
  118.     P3M0 = 0x84 + MaskCommD2D3;
  119.     P5M0 = 0x10 + MaskCommD4;

  120.     // 将IO赋初始值
  121.     // 共阴极IO置高
  122.     // 字符段IO置低
  123.     // 保持P3.0, P3.1为高
  124.     P1 = MaskCommD1;
  125.     P3 = MaskCommD2D3 + UARTPINEN;
  126.     P5 = MaskCommD4;
  127. }

  128. /**
  129. * 显示字符
  130. * 参数:idx        显示第几个字符,从左到右顺序为1,2,3,4
  131. * 参数:segidx     要显示的字符索引值
  132. * 参数:ctrl       当前字符的控制位
  133. */
  134. void showChar(unsigned char idx, unsigned char segidx, unsigned char ctrl) {
  135.     if (ctrl & 1 && idx < 30) {             // 确认当前字符的索引值有效
  136.         // 要同时设置好P1, P3和P5才能正常显示字符
  137.         // 设置Port1
  138.         P1 = P1SEG[segidx] + MaskCommD1;
  139.         // 设置Port3
  140.         //P3 = P3SEG[segidx] + MaskCommD2D3 + UARTPINEN;
  141.         switch (segidx) {
  142.             case 1:
  143.             case 2:
  144.             case 3:
  145.             case 7:
  146.             case 14:
  147.             case 19:
  148.                 P3 = 0x04 + MaskCommD2D3 + UARTPINEN;
  149.                 break;
  150.             case 10:
  151.             case 13:
  152.             case 21:
  153.             case 22:
  154.             case 25:
  155.                 P3 = MaskCommD2D3 + UARTPINEN;
  156.                 break;
  157.             case 5:
  158.             case 6:
  159.             case 12:
  160.             case 15:
  161.             case 16:
  162.             case 20:
  163.             case 26:
  164.             case 27:
  165.                 P3 = 0x80 + MaskCommD2D3 + UARTPINEN;
  166.                 break;
  167.             default:
  168.                 P3 = 0x84 + MaskCommD2D3 + UARTPINEN;
  169.                 break;
  170.         }
  171.         // 设置Port5
  172.         //P5 = P5SEG[segidx] + MaskCommD4;
  173.         switch (segidx) {
  174.             case 0:
  175.             case 1:
  176.             case 7:
  177.             case 9:
  178.             case 20:
  179.             case 28:
  180.                 P5 = MaskCommD4;
  181.                 break;
  182.             default:
  183.                 P5 = 0x10 + MaskCommD4;
  184.                 break;
  185.         }
  186.         
  187.         // 是否显示小数点
  188.         if (ctrl & 2)
  189.             P1 |= 0x10;
  190.         
  191.         // 置低相应位的共阴极IO
  192.         switch (idx) {
  193.             case 1:
  194.                 CommD1 = 0;
  195.                 break;
  196.             case 2:
  197.                 CommD2 = 0;
  198.                 break;
  199.             case 3:
  200.                 CommD3 = 0;
  201.                 break;
  202.             case 4:
  203.                 CommD4 = 0;
  204.                 break;
  205.         }
  206.     }
  207. }

  208. /**
  209. * 主函数
  210. */
  211. void main() {
  212.     initIO();       // 初始化IO
  213.     initUart();     // 初始化串口
  214.    
  215.     while (1) {
  216.         if (RXDONE == 1) {
  217.             /**
  218.             while (TXBUSY);
  219.             TXBUSY = 1;
  220.             SBUF = DISPBUFF[4];
  221.             */
  222.             RXDONE = 0;
  223.             // 当接收完数据后重置IO,准备显示新的数字
  224.             P1 = MaskCommD1;
  225.             P3 = MaskCommD2D3 + UARTPINEN;
  226.             P5 = MaskCommD4;
  227.         }
  228.         showChar(1, DISPBUFF[0], DISPBUFF[1]);
  229.         Delay1ms();
  230.         showChar(2, DISPBUFF[2], DISPBUFF[3]);
  231.         Delay1ms();
  232.         showChar(3, DISPBUFF[4], DISPBUFF[5]);
  233.         Delay1ms();
  234.         showChar(4, DISPBUFF[6], DISPBUFF[7]);
  235.         Delay1ms();
  236.     }
  237. }

  238. /**
  239. * 串口中断
  240. */
  241. void UART() interrupt 4 using 1 {
  242.     if (RI) {
  243.         RI = 0;
  244.         UARTBUFF[idxUARTBUFF] = SBUF;
  245.         idxUARTBUFF++;
  246.         // 当接收完指定长度(BUFFLEN)的数据之后
  247.         // 把串口接收数据缓存的数据复制到显示的缓存中
  248.         // 同时重置了串口接收缓存位置索引
  249.         if (idxUARTBUFF == BUFFLEN) {
  250.             while (idxUARTBUFF > 0) {
  251.                 idxUARTBUFF--;
  252.                 DISPBUFF[idxUARTBUFF] = UARTBUFF[idxUARTBUFF];
  253.             }
  254.             RXDONE = 1;
  255.         }
  256.     }
  257.     /**
  258.     if (TI) {
  259.         TI = 0;
  260.         TXBUSY = 0;
  261.     }
  262.     */
  263. }
复制代码


此帖出自51单片机论坛

最新回复

3.3V可以直接驱动三极管来 驱动控制 数码管亮吗   详情 回复 发表于 2018-5-23 10:50
点赞 关注
 

回复
举报

60

帖子

0

TA的资源

纯净的硅(初级)

沙发
 
本帖最后由 karajanlee 于 2014-1-17 16:06 编辑

把代码和二进制文件附加一下


main.c.zip

2.54 KB, 下载次数: 13

代码

Digits.hex.zip

1008 Bytes, 下载次数: 11

二进制文件

此帖出自51单片机论坛
 
 
 

回复

1万

帖子

25

TA的资源

裸片初长成(高级)

板凳
 
现在的51机的价格很低了,用这种办法完成显示倒是值得推广的。
此帖出自51单片机论坛
 
 
 

回复

60

帖子

0

TA的资源

纯净的硅(初级)

4
 
修复数字9的显示错误..

Digits.zip

1021 Bytes, 下载次数: 17

main.zip

2.59 KB, 下载次数: 25

此帖出自51单片机论坛
 
 
 

回复

4005

帖子

0

TA的资源

版主

5
 
不错,程序可以更好些,加上ADC功能可以做表头了
此帖出自51单片机论坛
 
 
 

回复

60

帖子

0

TA的资源

纯净的硅(初级)

6
 
呵呵,升级版了。。
做了一片PCB,原始设计用的是0.36英寸的数码管,共阴极只是加了限流电阻,这次升级共阴极加了三极管,设计的时候是想把PCB做成数码管一样大小的,于是0.36的面积有点紧张,于是换成了0.56英寸的数码管了。接口方面仍然是支持FTDI的USB转RS232的工具的,外加了利用FTDI工具上的DTR端口进行单片机自动硬重启的功能,刷程序就简单多了。。呵呵。。。程序有改动,晚上回去传,先上图片和电路图,还有PCB的生产文件,有兴趣的同学可以玩玩。。









Tiny4Numbers_release_files-G20140227.zip

14.64 KB, 下载次数: 19

Gerber

此帖出自51单片机论坛
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

7
 
你好,请问VCC电源电压是 几V的?
此帖出自51单片机论坛
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

8
 
3.3V可以直接驱动三极管来 驱动控制 数码管亮吗
此帖出自51单片机论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表