找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8069|回复: 3
打印 上一主题 下一主题
收起左侧

分享自写码表单片机程序(共阴极数码管显示)

[复制链接]
跳转到指定楼层
楼主
ID:407089 发表于 2018-10-9 16:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/*
晶振频率11.0592MHz

程序修改说明:
第一版程序在开发板上运行时,虽能基本完成功能,但闪烁严重,复位后数组还有异常数据等,应是算法问题,此版寻求解决之道。

问题之一:闪烁严重
将FormatTimeWithMS(TotalMS)语句从定时器中断程序中移出,放到mian中,问题得到解决,与预计的FormatTimeWithMS函数占了太大的时间资源不一致。
但发现出现另一问题:最后(右)一位显示明显偏亮,运行别的程序时,各位显示一致,但亮度与前面所述最后一位一致,说明其实是前7位亮度偏暗。
经调试,发现原因为消影语句放置位置不妥,修改位置后,闪烁问题完全解决。

问题之二:保存数据的数据重置后数据异常
经调试,发现原因为数组设置与读取不正确,修改后正常。
*/

  1. #include <reg52.h>
  2. #include <string.h>

  3. typedef unsigned int u16;
  4. typedef unsigned char u8;

  5. sbit seg_sel = P2^6;
  6. sbit bit_sel = P2^7;
  7. sbit start_key = P3^0;
  8. sbit record_key = P3^1;
  9. sbit reload_key = P3^2;
  10. sbit reset_key = P3^3;

  11. //共阴极数码管0-9和"-"编码0x40
  12. unsigned char code seg_table[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x7,0x7F,0x6F,0x40};
  13. //数码管位码(数组第1位对应数码管最左位)
  14. unsigned char code bit_table[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};

  15. #define DATA P0

  16. u8 timer;
  17. //初始化显示数据
  18. u8 TimeFormat[] = {0,0,1,0,0,1,0,0};
  19. //数据记录数组,5组,每组8个数据
  20. u8 ResultArray[5][8];
  21. u8 ResultMax = 5;
  22.         
  23. u8 i,j,k,z;
  24. unsigned long TotalMS;
  25. u8 minS,minG,secS,secG,msS,msG;
  26. bit IsReload;

  27. void delay(u16 num)
  28. {
  29.         u16 m,n;
  30.         for(m=num; m>0; m--)
  31.                 for(n=113; n>0; n--);
  32. }

  33. //此函数将毫秒数转换成需要显示的时间格式(设置数组TimeFormat[])
  34. void FormatTimeWithMS(long tms)
  35. {
  36.         minS = (tms/60000)/10;
  37.         minG = (tms/60000)%10;
  38.         secS = (tms-(minS*10+minG)*60000)/1000/10;
  39.         secG = (tms-(minS*10+minG)*60000)/1000%10;
  40.         msS = (tms%1000)/100;
  41.         msG = (tms%1000)%100/10;

  42.         TimeFormat[0] = minS;
  43.         TimeFormat[1] = minG;
  44.         TimeFormat[3] = secS;
  45.         TimeFormat[4] = secG;
  46.         TimeFormat[6] = msS;
  47.         TimeFormat[7] = msG;
  48. }

  49. void TimeDisplay(void)
  50. {
  51.         i = 0;
  52.         for (j=0; j<8; j++)
  53.         {
  54.                 //移位
  55.                 bit_sel = 1;
  56.                 DATA = bit_table[j];
  57.                 bit_sel = 0;

  58.                 //显数
  59.                 seg_sel = 1;
  60.                 if ( i==2 | i==5 )
  61.                 {
  62.                         DATA = seg_table[10];
  63.                 }else{
  64.                         DATA = seg_table[TimeFormat[i]];
  65.                         if (!IsReload)
  66.                         {
  67.                                 DATA = seg_table[TimeFormat[i]];
  68.                         }else{
  69.                                 DATA = seg_table[ResultArray[z][i]];
  70.                         }
  71.                 }
  72.                 i++;
  73.                 delay(1);
  74.                
  75.                 //消影
  76.                 DATA = 0x00;
  77.                 seg_sel = 0;
  78.         }
  79. }

  80. void StopTimer(void)
  81. {
  82.         if(TR0){TR0=0;}        
  83.         IsReload = 1;
  84.         TotalMS = 0;
  85.         FormatTimeWithMS(TotalMS);
  86. }

  87. void main(void)
  88. {
  89.         DATA = 0x00;
  90.         P3 = 0xff;
  91.         seg_sel = 0;
  92.         bit_sel = 0;

  93.         TMOD = 0x01;
  94.         //单次溢出时间10ms之初值
  95.         TH0 = 0xdc;
  96.         TL0 = 0x00;
  97.         EA = 1;
  98.         ET0 = 1;

  99.         TotalMS = 0;

  100.         while(1)
  101.         {
  102.                 //计时启停
  103.                 if (start_key == 0)
  104.                 {
  105.                         delay(10);
  106.                         if (start_key == 0)
  107.                         {
  108.                                 TR0 = ~TR0;
  109.                         }
  110.                         while(!start_key);
  111.                 }
  112.                
  113.                 //记录时间
  114.                 if (record_key == 0)
  115.                 {
  116.                         delay(10);
  117.                         if (record_key == 0)
  118.                         {
  119.                                 //小于最大记录时,记录数据;达到最大值时,停止计时器
  120.                                 if (k < ResultMax)
  121.                                 {
  122.                                         ResultArray[k][0] = minS;
  123.                                         ResultArray[k][1] = minG;
  124.                                         ResultArray[k][2] = 1;
  125.                                         ResultArray[k][3] = secS;
  126.                                         ResultArray[k][4] = secG;
  127.                                         ResultArray[k][5] = 1;
  128.                                         ResultArray[k][6] = msS;
  129.                                         ResultArray[k][7] = msG;
  130.                                         k++;
  131.                                         if (k==ResultMax) if(TR0){TR0=0;}
  132.                                 }
  133.                         }
  134.                         while(!record_key);
  135.                 }
  136.                
  137.                 //回显被记录的时间
  138.                 if (reload_key == 0)
  139.                 {
  140.                         delay(10);
  141.                         if (reload_key == 0)
  142.                         {
  143.                                 //如果不是回显数据,那么z=0(此处加判断的意义是首次点击回显键时,数据从第一组开始显示)
  144.                                 if(!IsReload)
  145.                                 {
  146.                                         z = 0;
  147.                                 }else{
  148.                                         z++;
  149.                                         if( z > (ResultMax-1)){z=0;}
  150.                                 }
  151.                                 StopTimer();
  152.                         }
  153.                         while(!reload_key);
  154.                 }               
  155.                
  156.                 //重置(计时器停止,总显示时间清0,时间记录数组清0,回显数据状态置0)
  157.                 if (reset_key == 0)
  158.                 {
  159.                         delay(10);
  160.                         if (reset_key == 0)
  161.                         {
  162.                                 StopTimer();
  163.                                 memset(ResultArray,0,sizeof(ResultArray));
  164.                                 IsReload = 0;
  165.                         }
  166.                         while(!reset_key);
  167.                 }

  168.                 //显示时间
  169.                 FormatTimeWithMS(TotalMS);
  170.                 TimeDisplay();
  171.         }
  172. }

  173. void timer0_service(void) interrupt 1
  174. {
  175.         TH0 = 0xdc;
  176.         TL0 = 0x00;
  177.         //因为是每10ms溢出一次,故总时间累加10ms。
  178.         TotalMS = TotalMS+10;
  179. }
复制代码


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1 发表于 2018-10-10 19:21 | 只看该作者
补全原理图或者详细说明一下电路连接即可获得100+黑币
回复

使用道具 举报

板凳
ID:407089 发表于 2018-11-20 15:36 | 只看该作者
admin 发表于 2018-10-10 19:21
补全原理图或者详细说明一下电路连接即可获得100+黑币

stopwatch.rar (20.15 KB, 下载次数: 10)
谢谢管理!
回复

使用道具 举报

地板
ID:407089 发表于 2018-11-20 15:37 | 只看该作者
stopwatch.rar (20.15 KB, 下载次数: 7)
附上原理图及hex文件,方便各位测试。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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