数码之家

 找回密码
 立即注册
搜索
查看: 983|回复: 15

[C51] 小白自学C51单片机编程,请大家指出不足之处

[复制链接]
发表于 2023-12-19 11:18:50 | 显示全部楼层 |阅读模式

爱科技、爱创意、爱折腾、爱极致,我们都是技术控

您需要 登录 才可以下载或查看,没有账号?立即注册

x
网上买了这种简单的开发板,按店家提供的资料和网上的贴子自己学着编程,请大家指出不足之处,谢谢!
用的这种简单的开发板,IC型号是STC89C52
. 66e49b29345d3939b8b746f8dd728fb.jpg

用的电脑是这台老掉牙的小本本,

6f157a394e4302a4c05925d596efe0d.jpg

本次的任务是用4位数码管和定时器实际0000-9999累加循环显示。

  1. #include <reg52.h>
  2. #define uchar unsigned char  //宏定义,意思就是用char 代替unsigned char 相当于缩写的意思了,
  3. #define uint unsigned int

  4. sbit a = P1^0;  //位定义,表示个位数码管的位,以下是十位,百位,千位
  5. sbit b = P1^1;
  6. sbit c = P1^2;
  7. sbit d = P1^3;
  8. // 数码管的编码,抄来的,没去深究
  9. uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

  10. uint num=0;    //定义变量,并给初值,如果不给初值,是不是默认就是0?num就是要显示的数
  11. uint xms;  //表示延时
  12. uchar shi=0;  

  13. void display(num);  //定义显示函数,如果函数写在main前可以不定义,写在main后要先定义,我发现有些函数括号内有变量,有些没有,有什么不同?不懂
  14. void delay(xms); //定义延时函数,

  15. void main ()
  16. {
  17.      TMOD=0X01; //定时器模式1
  18.     TH0=(65536-50000)/256;  //高8位初值,为什么是这样也不懂,抄来的
  19.     TL0=(65536-50000)%256; //低8位初值
  20.     EA=1;  //总中断
  21.     ET0=1; //定时器0
  22.     TR0=1;  //开定时器0
  23.     while(1)
  24.     {
  25.         display(num);  //主循环,就一个任务,显示
  26.     }
  27. }

  28. void display(num)  //显示子函数,利用发光残留和人眼视觉误差,每次开一个数码管,显示完了再开另一个,看起来就是4个一起亮。
  29. {
  30.       a=0;   //开个位位选
  31.      P0=table[num%10];  //送段选值 %表示求余,如123%10 除10后余3 就只显示3
  32.      delay(5);  //延时,如果延时用10,就能看到明显闪
  33.      a=1;  // 关个位位选

  34.      b=0;
  35.      P0=table[num/10%10];
  36.      delay(5);
  37.      b=1;

  38.      c=0;
  39.      P0=table[num/100%10];
  40.      delay(5);
  41.      c=1;

  42.      d=0;
  43.      P0=table[num/1000%10];
  44.      delay(5);
  45.      d=1;
  46. }


  47. void delay(xms)
  48. {
  49.      uchar i;
  50.     while(xms--)
  51.     {
  52.          for(i=0;i<113;i++);  //先给初值,然后判断,如果条件符合就执行,再回到判断,如果不符合就跳出语句
  53.     }
  54. }


  55. void jishu ()interrupt 1 //定时器中断函数
  56. {   
  57.      if(shi==10)  //定时器满了10次就执行一次中断
  58.     {        
  59.          shi=0;  //从新开始
  60.         num++;  // 要显示的数加1
  61.         if(num==10000)  //要显示的数上限,我试过,如果不设上限,到了9999后会显示一些乱码,为什么我也不知道
  62.         {
  63.              num=0;
  64.         }
  65.     }
  66.     TH0=(65536-50000)/256;   
  67.     TL0=(65536-50000)%256;
  68.     shi++;
  69. }
复制代码

没有系统的学习过,好些都很难理解,开发板的好处就是可以不断的尝试,谢谢大家



打赏

参与人数 1家元 +15 收起 理由
不长叶子的树 + 15

查看全部打赏

发表于 2023-12-19 11:39:05 | 显示全部楼层
勇敢的迈出了第一步!赞
回复 支持 1 反对 0

使用道具 举报

发表于 2023-12-19 11:46:04 | 显示全部楼层
不是该学汇编吗
回复 支持 反对

使用道具 举报

发表于 2023-12-19 11:50:58 来自手机浏览器 | 显示全部楼层
进入了一个新世界
回复 支持 反对

使用道具 举报

发表于 2023-12-19 12:10:17 | 显示全部楼层
换个大屏幕吧,一屏只显示几行,程序一大就不好写了
回复 支持 反对

使用道具 举报

发表于 2023-12-19 12:41:20 | 显示全部楼层
1.display函数中,应该先设置段,再打开位控制。不然上一个位关了,下一下位打开时还是上一个段的数据,会有轻微重影。改成这样
     P0=table[num%10];  //送段选值 %表示求余,如123%10 除10后余3 就只显示3
      a=0;   //开个位位选
     delay(5);  //延时,如果延时用10,就能看到明显闪
     a=1;  // 关个位位选

2.中断计时函数中shi++应该放到else里。不然shi=10后,虽然有shi=0,但最后又被sh++了,少计了一个数。改成这样
if (shi == 10) {
   .....
} else {
  shi++;
}

3.函数的参数应声明数据类型,比如这样
void display(unsigned int num)

4.单片机跟硬件强相关,建议初学者搞懂底层的原理,比如你个代码中数码管的编码是怎么来的,共阴、共阳有什么区别,动态扫描的原理,定时器的初始值为什么要这么设置。搞懂了这些才对深入单片机的学习有帮助。不然只是网上抄代码,编译下载能跑,对学习没有任何帮助。
回复 支持 反对

使用道具 举报

发表于 2023-12-19 13:28:15 | 显示全部楼层
还是得先找一本微机教材过一遍,对基本的概念有个理解再实操验证
回复 支持 反对

使用道具 举报

发表于 2023-12-19 14:11:07 | 显示全部楼层
wangxiangtan2 发表于 2023-12-19 13:28
还是得先找一本微机教材过一遍,对基本的概念有个理解再实操验证

大神求解惑:
https://www.mydigit.cn/thread-428143-1-1.html
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-19 16:52:44 | 显示全部楼层
elecfunwb 发表于 2023-12-19 12:41
1.display函数中,应该先设置段,再打开位控制。不然上一个位关了,下一下位打开时还是上一个段的数据,会 ...

谢谢 elecfunwb
1、按照你的方法,先送段信号P0=table[num%10]; 确实没有轻微重影,
2、多重的IF函数我还是不熟,绕的头晕
3、void display(unsigned int num) 括号内的声明我在程序前面声明过一次,我以为在括号内就不要再次声明了
4、数码管的编码我只知道里面有8个发光二极管,哪几个二极管导通就显示出什么数字,位就是这8个的总开关,16进制数转换成2进制数,就是对应哪个二极管导通,共阳共阴好理解,定时器初值没看懂,只知道-50000就是50mS 计时20次就是1S
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-19 17:02:40 | 显示全部楼层
本帖最后由 hellozwt 于 2023-12-19 17:12 编辑

试一下上传视频

5540f280cc5be2d0637229f9e54a768d.mp4 (2.41 MB, 下载次数: 0)
回复 支持 反对

使用道具 举报

发表于 2023-12-19 17:12:47 | 显示全部楼层
这个是适合学原理的程序,大部分时间在延时消耗
回复 支持 反对

使用道具 举报

发表于 2023-12-19 19:44:07 | 显示全部楼层
初学都是先学点灯,数码管,按键,定时器,串口,慢慢的就入门了
回复 支持 反对

使用道具 举报

发表于 2023-12-20 09:50:01 | 显示全部楼层
还是arduino简单 几行代码就能点灯 点数码管
回复 支持 反对

使用道具 举报

发表于 2023-12-20 11:06:01 | 显示全部楼层
很多代码都是被前人误导了
回复 支持 反对

使用道具 举报

发表于 2023-12-22 10:08:07 | 显示全部楼层
大学时学的汇编语言都忘了,也没学好。那时候觉得好抽象啊!
回复 支持 反对

使用道具 举报

发表于 2023-12-22 15:01:47 | 显示全部楼层
可以试下  STC8H8K64U,可以直接USB下载和仿真!
回复 支持 反对

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2024-5-1 11:37 , Processed in 0.234001 second(s), 12 queries , Redis On.

Powered by Discuz!

© 2006-2023 smzj.net

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