• 51单片机实验:数码管动态显示00-99


    1、实验要求

            利用STC89C52RC单片机开发板实现:使用2位数码管循环显示00-99,每次间隔1s,并且当计数到20时,则蜂鸣器鸣响1次。

    2、实验分析

    程序实现分析:        

            1、定义数码管位选引脚(P2.4、P2.5、P2.6、P2.7)

            2、定义个位、十位显示函数(用来未选第1、2位显示个位、十位上的数字)

            3、定义延时函数(使用for循环嵌套实现空语句执行,从而达到延时的效果)

            4、定义计数变量,分别计算出个位、十位的数,将其传入到个位、十位显示的函数

            5、结合延时函数,实现数字的显示

            6、判断计数变量大于99,则重新赋值为0

    3、代码实现

    (1)导入头文件及引脚定义

    1. #include
    2. sbit pos1 = P2^4; // 第1为数码管位选控制位
    3. sbit pos2 = P2^5; // 第2为数码管位选控制位
    4. sbit pos3 = P2^6; // 第3为数码管位选控制位
    5. sbit pos4 = P2^7; // 第4为数码管位选控制位
    6. sbit fmq = P2^3; // 蜂鸣器控制位

    (2)定义个位、十位显示函数

    1. // 分别对应:0/1/2/3/4/5/6/7/8/9
    2. int code_sz[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};
    3. // 宏定义:简写 unsigned int
    4. #define uint unsigned int
    5. // 函数声明
    6. void show_ge(uint x);
    7. void show_shi(uint y);
    8. // 显示个位数字:左起第2位数码管
    9. void show_ge(uint x) // x:计算的个位数的值,对应数组中的索引,从而取到对应的值
    10. {
    11. P0 = 0x00; // P0(段选位)复位
    12. pos1 = 0;
    13. pos2 = 1; // 选择第2位数码管
    14. pos3 = 0;
    15. pos4 = 0;
    16. P0 = code_sz[x]; // 数组索引取到对应的数字值赋值给P0
    17. }
    18. void show_shi(uint y) // y:计算的十位数的值,对应数组中的索引,从而取到对应的值
    19. {
    20. P0 = 0x00; // P0(段选位)复位
    21. pos1 = 1; // 选择第1位数码管
    22. pos2 = 0;
    23. pos3 = 0;
    24. pos4 = 0;
    25. P0 = code_sz[y]; // 数组索引取到对应的数字值赋值给P0
    26. }

    (3)定义延时函数

    1. void delay(uint ms); // 延时函数声明
    2. void delay(uint ms) // 延时指定的毫秒(错略延时)
    3. {
    4. uint i, j;
    5. for(i=ms; i>0; i--)
    6. {
    7. for(j=112; j>0; j--);
    8. }
    9. }

    (4)编写主函数逻辑

    1. uint val = 0;
    2. uint ge, shi;
    3. void main()
    4. {
    5. while (1)
    6. {
    7. ge = val % 10; // 计算个位的值
    8. shi = val / 10; // 计算十位的值
    9. show_shi(shi); // 调用显示十位的函数
    10. delay(100); // 延时100ms,让十位数显示保持
    11. show_ge(ge); // 调用显示个位的函数
    12. delay(900); // 延时900ms,让十位数显示保持
    13. fmq = 1; // 关闭蜂鸣器鸣叫
    14. pos1 = 0; // 位选复位(避免出现位选错乱,产生乱码)
    15. pos2 = 0;
    16. pos3 = 0;
    17. pos4 = 0;
    18. val++; // 计数值增加1
    19. if (val > 99) val =0; // 如果计数值大于99,则重新从0开始
    20. if (val == 20) fmq=0; // 如果计数值等于20,则蜂鸣器鸣叫
    21. }
    22. }

    【单片机显示问题】数码管显示不同的值需要考虑2个问题:

    (1)十位、个位显示不同值:由于P0段选共用,则需要实现位选调整才能实现。

    (2)要保证个位、十位的数同时显示。

    【单片机显示现象】十位数字很暗,基本无法显示,个位可以正常,但会出现闪烁情况,无法看到00--99的数字。

    【单片机显示分析】十位(第1位数码管)显示由于延时时间过短(100ms),造成还未显示,程序就执行到了显示个位的代码,从而位选就切换至第2位数(个位)码管,则P0对应的取值则会显示到第1位数码管,此时添加的900ms延时,也只能显示个位上的数字。

    【单片机显示调整】

    A、个位、十位显示的时间间隔不能过大这样(10s),由于代码执行较快(us),这样就能因为视觉停留现象则就会感觉数字是一直显示,同时也不会出现闪烁情况。

    B、个位、十位数值变化时间要保证1s:则计数变量则1s内需要计数50次再增加1(1000 / (10 + 10) = 50), 这样就能让个位十位数码管1s内更新50次后显示下一个数。


    1. uint times = 0;
    2. void main()
    3. {
    4. while (1)
    5. {
    6. times++;
    7. if(times == 50) // 每50次,计数增加1
    8. {
    9. times = 0; // 次数50次后复位
    10. val++; // 计数值增加1
    11. if (val > 99) val =0; // 如果计数值大于99,则重新从0开始
    12. }
    13. ge = val % 10; // 计算个位的值
    14. shi = val / 10; // 计算十位的值
    15. show_shi(shi); // 调用显示十位的函数
    16. delay(10); // 延时10ms,让十位数显示保持
    17. show_ge(ge); // 调用显示个位的函数
    18. delay(10); // 延时10ms,让十位数显示保持
    19. fmq = 1; // 关闭蜂鸣器鸣叫
    20. pos1 = 0; // 位选复位(避免出现位选错乱,产生乱码)
    21. pos2 = 0;
    22. pos3 = 0;
    23. pos4 = 0;
    24. if (val == 20) fmq=0; // 如果计数值等于20,则蜂鸣器鸣叫
    25. }
    26. }

    4、完整代码

    1. #include
    2. // 宏定义:简写 unsigned int
    3. #define uint unsigned int
    4. sbit pos1 = P2^4; // 第1为数码管位选控制位
    5. sbit pos2 = P2^5; // 第2为数码管位选控制位
    6. sbit pos3 = P2^6; // 第3为数码管位选控制位
    7. sbit pos4 = P2^7; // 第4为数码管位选控制位
    8. sbit fmq = P2^3; // 蜂鸣器控制位
    9. // 分别对应:0/1/2/3/4/5/6/7/8/9
    10. int code_sz[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};
    11. // 函数声明
    12. void show_ge(uint x);
    13. void show_shi(uint y);
    14. void delay(uint xms);
    15. uint times = 0;
    16. uint val = 0;
    17. uint ge, shi;
    18. void main()
    19. {
    20. while (1)
    21. {
    22. times++;
    23. if(times == 50) // 每50次,计数增加1
    24. {
    25. times = 0; // 次数50次后复位
    26. val++; // 计数值增加1
    27. if (val > 99) val =0; // 如果计数值大于99,则重新从0开始
    28. }
    29. ge = val % 10; // 计算个位的值
    30. shi = val / 10; // 计算十位的值
    31. show_shi(shi); // 调用显示十位的函数
    32. delay(10); // 延时10ms,让十位数显示保持
    33. show_ge(ge); // 调用显示个位的函数
    34. delay(10); // 延时10ms,让十位数显示保持
    35. fmq = 1; // 关闭蜂鸣器鸣叫
    36. pos1 = 0; // 位选复位(避免出现位选错乱,产生乱码)
    37. pos2 = 0;
    38. pos3 = 0;
    39. pos4 = 0;
    40. if (val == 20) fmq=0; // 如果计数值等于20,则蜂鸣器鸣叫
    41. }
    42. }
    43. // 显示个位数字:左起第2位数码管
    44. void show_ge(uint x) // x:计算的个位数的值,对应数组中的索引,从而取到对应的值
    45. {
    46. P0 = 0x00; // P0(段选位)复位
    47. pos1 = 0;
    48. pos2 = 1; // 选择第2位数码管
    49. pos3 = 0;
    50. pos4 = 0;
    51. P0 = code_sz[x]; // 数组索引取到对应的数字值赋值给P0
    52. }
    53. void show_shi(uint y) // y:计算的十位数的值,对应数组中的索引,从而取到对应的值
    54. {
    55. P0 = 0x00; // P0(段选位)复位
    56. pos1 = 1; // 选择第1位数码管
    57. pos2 = 0;
    58. pos3 = 0;
    59. pos4 = 0;
    60. P0 = code_sz[y]; // 数组索引取到对应的数字值赋值给P0
    61. }
    62. void delay(uint ms) // 延时指定的毫秒(错略延时)
    63. {
    64. uint i, j;
    65. for(i=ms; i>0; i--)
    66. {
    67. for(j=112; j>0; j--);
    68. }
    69. }

    5、实验总结

            要明确数码管的显示要解决的问题(显示不同的值的数据保持、不同位的数据同时显示),着重问题的本身出发,设计对应的程序:通过多次判断实现对计数的修改,同时要明确程序执行的速度较快,人有视觉暂停现象, 结合这些因素实现对应逻辑分步操作。


    结语以上整个程序的实现逻辑,还存在很多不全面的地方,欢迎各位大佬指点;如果觉得笔者不易,欢迎关注和点赞,给予我记录更多文章的动力!!

  • 相关阅读:
    盘点面试中常见的超大规模数据常见的算法问题
    Linux关于gittee的远端仓库的连接和git三板斧
    网络安全保险行业面临的挑战与变革
    源代码转换:Tangible Software Solutions v22.10.20
    JAVA面试中的SSM框架基础面试题
    探秘小米增程汽车与仿生机器人的未来:AI大模型的潜在影响及苹果iPhone15Pro发热问题解决之道
    K8S网络原理
    java-net-php-python-jsp学生会人事管理信息系统计算机毕业设计程序
    语法练习:sleep_in
    猫头虎博主成为创作者的第1024天纪念日
  • 原文地址:https://blog.csdn.net/qq_19394437/article/details/134049057