找回密码
 立即注册

QQ登录

只需一步,快速开始

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

新手学习单片机进度很慢,应该如何学习?

  [复制链接]
跳转到指定楼层
楼主
ID:695930 发表于 2020-6-20 20:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 你速度发生的 于 2020-6-21 00:11 编辑

我想咨询各位大佬,我是19级大一,我学习单片机有半年左右,对单片机的理解只到大概可以看懂,51普中的板子例程也都走了一遍。但是和我一师兄习单片机的师兄他就比我深入很多,我们那个时候制作一个小项目LCD1602液晶显示温度并设定温度上下限,蜂鸣器报警提示超限。我师兄他制作这个程序只有

这是不是说明我学习的进度慢了他很多,我看单片机的书看到时序,串口什么的原理就头疼,看久了就发呆去了,求各位大佬支招。主要是想问学习单片机是否要像我师兄那样深入的学习,我应该怎么学
  1. #include <reg51.h>
  2. #include "temp.h"
  3. #include <stdio.h>
  4. void LcdDisplay(int);
  5. void UsartConfiguration(void);
  6. /*******************************************************************************
  7. * 函数名         : main
  8. * 函数功能     : 主函数
  9. * 输入           : 无
  10. * 输出           : 无
  11. *******************************************************************************/
  12. void main()
  13. {

  14. UsartConfiguration();//初始化
  15. EA=1;      //打开总中断
  16. while(1)
  17. {
  18.    LcdDisplay(Ds18b20ReadTemp());  
  19.    Delay1ms(100);//0.1s钟刷一次
  20.    
  21. }
  22. }
  23. /*******************************************************************************
  24. * 函数名         : LcdDisplay()
  25. * 函数功能     : LCD显示读取到的温度
  26. * 输入           : v
  27. * 输出           : 无
  28. *******************************************************************************/
  29. void LcdDisplay(int temp)   //lcd显示
  30. {
  31.   static int q=0;
  32. int i=0;
  33.   char  datas[] = {0, 0, 0, 0, 0}; //定义数组
  34. float tp;  

  35.   temp=temp-1;
  36.   
  37.   tp=temp;
  38. tp=tp*0.0625+0.5;
  39. //  temp=tp*0.0625*100+0.5;
  40. // tp=(float)temp/100;
  41.   printf("第%d次测量的温度为:+%0.2f\n",q++,tp);
  42. }
  43. /*******************************************************************************
  44. * 函 数 名         :UsartConfiguration()
  45. * 函数功能     :设置串口
  46. * 输    入         : 无
  47. * 输    出         : 无
  48. *******************************************************************************/
  49. void UsartConfiguration(void)
  50. {

  51. TMOD=0x20;//即0010 0000,定时器/计数器1,工作方式2
  52. TH1=0xfd;//设置波特率为9600
  53. TL1=0xfd;
  54. TR1=1;//启动定时器/计数器1
  55. SCON=0x50; //0101 0000.串口工作方式1,允许串行控制
  56. PCON=0x00;//设置SMOD=0
  57. IE=0x90; //CPU允许中断,串行允许中断
  58. TI=1;//
  59. }


  60. 而我自己的
  61. /*******************************************************************************
  62. 注意事项:
  63. 根据自己使用的LCD1602是否带有转接板,如果带有转接板的即为4位,需在LCD.H头文件中
  64. 将宏#define LCD1602_4PINS打开,我们这里使用的LCD1602是8位,所以默认将该宏注释。
  65. 接线说明:(开发攻略每个实验章节内的实验现象都有对应的接线图说明)
  66. LCD1602接线参考LCD1602液晶显示实验接线图
  67. DS18B20传感器接线参考DS18B20温度传感器实验接线图

  68. 实验操作:
  69. LCD1602上显示采集的温度,同时
  70. 打开串口调试助手,将串口波特率选择9600,打开串口,此时在串口上就会显示采集的温度,串口截图参考文件夹下。
  71. *******************************************************************************/
  72. #include<reg51.h>
  73. #include"lcd.h"
  74. #include"temp.h"
  75. #include<intrins.h>  //因为要用到左右移函数,所以加入这个头文件
  76. typedef unsigned int u16;   //对数据类型进行声明定义
  77. typedef unsigned char u8;
  78. sbit beep=P1^1;
  79. uchar i;
  80. int n=0;
  81. uchar CNCHAR[17] = "第1次测试温度为:";
  82. uchar lx[1]="1";
  83. void LcdDisplay(int);
  84. void UsartConfiguration();
  85. sbit LSA=P0^7;
  86. sbit LSB=P2^3;
  87. sbit LSC=P2^4;
  88. /*******************************************************************************
  89. * 函 数 名         : delay
  90. * 函数功能     : 延时函数,i=1时,大约延时10us
  91. *******************************************************************************/
  92. void delay(u16 i)
  93. {
  94. while(i--);
  95. }
  96. /*******************************************************************************
  97. * 函数名         : main
  98. * 函数功能     : 主函数
  99. * 输入           : 无
  100. * 输出           : 无
  101. *******************************************************************************/
  102. void main()
  103. {
  104. UsartConfiguration();
  105. LcdInit();    //初始化LCD1602
  106. LcdWriteCom(0x88); //写地址 80表示初始地址
  107. LcdWriteData('C');
  108. while(1)
  109. {
  110.   LcdDisplay(Ds18b20ReadTemp());
  111.          if((Ds18b20ReadTemp()>480)||(Ds18b20ReadTemp()<400))
  112.   {
  113.       for(i=0;i<120;i++)
  114.    {
  115.    beep=~beep;
  116.     delay(100);   
  117.    };
  118.   }
  119.   else
  120.   {
  121.      ;
  122.   };
  123. //  Delay1ms(1000);//1s钟刷一次
  124. }
  125. }

  126. /*******************************************************************************
  127. * 函数名         : LcdDisplay()
  128. * 函数功能     : LCD显示读取到的温度
  129. * 输入           : v
  130. * 输出           : 无
  131. *******************************************************************************/
  132. void LcdDisplay(int temp)   //lcd显示
  133. {
  134.    unsigned char i, datas[] = {0, 0, 0, 0, 0}; //定义数组
  135. float tp;  
  136. if(temp< 0)    //当温度值为负数
  137.    {
  138.     LcdWriteCom(0x80);  //写地址 80表示初始地址
  139.   SBUF='-';//将接收到的数据放入到发送寄存器
  140.   while(!TI);            //等待发送数据完成
  141.   TI=0;       //清除发送完成标志位
  142.      LcdWriteData('-');    //显示负
  143.   //因为读取的温度是实际温度的补码,所以减1,再取反求出原码
  144.   temp=temp-1;
  145.   temp=~temp;
  146.   tp=temp;
  147.   temp=tp*0.0625*100+0.5;
  148.   //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
  149.   //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
  150.   //算由?.5,还是在小数点后面。

  151.    }
  152.   else
  153.    {   
  154.     LcdWriteCom(0x80);  //写地址 80表示初始地址
  155.      LcdWriteData('+');   //显示正
  156.   SBUF='+';//将接收到的数据放入到发送寄存器
  157.   while(!TI);            //等待发送数据完成
  158.   TI=0;       //清除发送完成标志位
  159.   tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
  160.   //如果温度是正的那么,那么正数的原码就是补码它本身
  161.   temp=tp*0.0625*100+0.5;
  162.   //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
  163.   //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
  164.   //算加上0.5,还是在小数点后面。
  165. }
  166. datas[0] = temp / 10000;
  167. datas[1] = temp % 10000 / 1000;
  168. datas[2] = temp % 1000 / 100;
  169. datas[3] = temp % 100 / 10;
  170. datas[4] = temp % 10;
  171. LcdWriteCom(0x82);    //写地址 80表示初始地址
  172. LcdWriteData('0'+datas[0]); //百位
  173. SBUF = '0'+datas[0];//将接收到的数据放入到发送寄存器
  174. while (!TI);            //等待发送数据完成
  175. TI = 0;

  176. LcdWriteCom(0x83);   //写地址 80表示初始地址
  177. LcdWriteData('0'+datas[1]); //十位
  178. SBUF = '0'+datas[1];//将接收到的数据放入到发送寄存器
  179. while (!TI);            //等待发送数据完成
  180. TI = 0;
  181. LcdWriteCom(0x84);  //写地址 80表示初始地址
  182. LcdWriteData('0'+datas[2]); //个位
  183. SBUF = '0'+datas[2];//将接收到的数据放入到发送寄存器
  184. while (!TI);            //等待发送数据完成
  185. TI = 0;
  186. LcdWriteCom(0x85);  //写地址 80表示初始地址
  187. LcdWriteData('.');   //显示 ‘.’
  188. SBUF = '.';//将接收到的数据放入到发送寄存器
  189. while (!TI);            //等待发送数据完成
  190. TI = 0;
  191. LcdWriteCom(0x86);   //写地址 80表示初始地址
  192. LcdWriteData('0'+datas[3]); //显示小数点  
  193. SBUF = '0'+datas[3];//将接收到的数据放入到发送寄存器
  194. while (!TI);            //等待发送数据完成
  195. TI = 0;
  196. LcdWriteCom(0x87);   //写地址 80表示初始地址
  197. LcdWriteData('0'+datas[4]); //显示小数点
  198. SBUF = '0'+datas[4];//将接收到的数据放入到发送寄存器
  199. while (!TI);            //等待发送数据完成
  200. TI = 0;
  201. for(i=0; i<17; i++)
  202. {
  203.    SBUF = CNCHAR[i];//将接收到的数据放入到发送寄存器
  204.   while (!TI);            //等待发送数据完成
  205.   TI = 0;
  206. }
  207.   if((CNCHAR[2]='1')&&(n<9))我只在这里修改了一下
  208.   {
  209.     n++;
  210.        CNCHAR[2]=lx[0];
  211.        lx[0]=lx[0]+1;   
  212.   }
  213.   else
  214. {
  215.     CNCHAR[2]='1';
  216.    lx[0]='1';
  217.    n=0;
  218. }
  219. }
  220. /*******************************************************************************
  221. * 函 数 名         :UsartConfiguration()
  222. * 函数功能     :设置串口
  223. * 输    入         : 无
  224. * 输    出         : 无
  225. *******************************************************************************/
  226. void UsartConfiguration()
  227. {
  228.   SCON=0x50;//设置串口工作方式1
  229. TMOD=0x20;//设置计数器工作方式2
  230. PCON=0x00;//即SMOD=1,波特率不加倍
  231. TH1=0xFD;//计数器初值。波特率是9600,晶振为11.0592MHz
  232. TL1=0xFD;
  233. // ES=1;      //打开接收中断
  234. // EA=1;      //打开总中断
  235. TR1=1;//打开计数器
  236. }
复制代码




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

使用道具 举报

沙发
ID:748788 发表于 2020-6-21 10:53 | 只看该作者
你的师兄除了跟着课本走,还多动了脑子,在原有程序的基础上加了新的东西。这正是你缺少的。编程就要多动脑子,而且是越用越好用
回复

使用道具 举报

板凳
ID:235200 发表于 2020-6-21 11:36 | 只看该作者
说明与单片机相关的基础知识薄弱,需要进一步加深学习
回复

使用道具 举报

地板
ID:785582 发表于 2020-6-21 12:47 | 只看该作者
先从理论知识开始,硬啃,然后结合编程实践应该会好很多
回复

使用道具 举报

5#
ID:47286 发表于 2020-6-21 18:06 | 只看该作者
这事的关键不在技术本身 在你自己 你是特想学么 你是一定要学么 如果俩条件都满足 时间其实不是问题 人的进步又不是线性的 也许是对数曲线也许是指数曲线
回复

使用道具 举报

6#
ID:420836 发表于 2020-6-21 23:18 | 只看该作者
要很好地学习单片机,需要大量的实践经验,例如编程和制作。
回复

使用道具 举报

7#
ID:785561 发表于 2020-6-22 07:40 | 只看该作者
理论+实践,从中深层次理解!!!
回复

使用道具 举报

8#
ID:162664 发表于 2020-6-22 09:48 | 只看该作者
我认为基础的硬件知识对理解mcu的深入程度有一定的辅助作用。一:基础模块的修炼。(第一个阶段不要看汇编,用c语言。汇编门槛太高容易一下子把脆弱的积极性和兴趣给打击掉。)
1:建议找个单片机的教程,先把单片机的基础模块摸一遍,理解基础的mcu模块(通论本质上就是串行和并行的区别。了解本质之后就是规则的问题而已)
1.2:输出输出端口操作、定时器、pwm模块、adc转换、模拟iic、模拟spi、硬件uart、外部中断、系统时钟、看门狗(你可能用的stc的mcu,系统时钟可以暂时不弄,iic、spi的先用模拟的方式来。)
2:寄存器的操作一定要自己写,可以参考别人写得来拓展一下思路,(对mcu寄存器基本的操作可以参考新唐n76e003的demo程序,官网有资料。)
2.1:这个过程中你买一个逻辑分析仪(30rmb)、串口接收的ch340(8rmb),如果有示波器更好、暂时不强求。
3:每一个模块需要一些硬件知识,一般的教程都会讲解的。基础的按键操作滤波、lcd的现实在这个过程中会学。
通讯部分优先uart、后spi、iic。uart不要模拟实现,用mcu模块方式实现(模拟只是让你对它了解更深刻,一般使用不模拟)。iic、spi先用模拟方式实现后用mcu模块方式实现。
二:代码编写修炼
1:因为上述的操作是mcu的模块操作,接下来是怎么优化和让你程序变得贴近应用。需要对编写代码方式的修炼。
1.1:c51的语言的修炼暂时不需要做的太深刻。指针和结构体慢慢来(先看懂,再慢慢会用),基础的if else siwtch while break  for #define 差不多就够了(可能有遗漏一时想不起来)
2:看看《单片机编程魔法师》。最基础的两个思想要掌握。( 一定要摆脱掉对 delay这种延时超过1ms的用法 ,delay可以用,但是不能延时时间太长,影响程序的并行效率。)
2.1:驱动的思想/程序分层。
2.2:定时器的多层复用。
2.3:多任务并行(伪并行)。
三:基础的模块会了之后,并行的思想吸收了一些,这样可以应用在项目上。再反推回来去深刻理解mcu的基本原理和硬件的知识。。
回复

使用道具 举报

9#
ID:677449 发表于 2020-6-22 10:48 | 只看该作者
从简单的开始做起,从驱动定时串口中断等一步步学习,代码复杂的肯定比简单的费脑子
回复

使用道具 举报

10#
ID:786442 发表于 2020-6-22 11:00 | 只看该作者
先看单片机原理,再学编程。
回复

使用道具 举报

11#
ID:786687 发表于 2020-6-22 15:13 | 只看该作者
找一块单片机开发板进行练习。可以自己花钱买一块单片机的开发板,不需要功能太全,对于初学者来说功能非常多的板子,上面有很多东西你这辈子都用不着。建议有流水灯、数码管、独立键盘、矩阵键盘、AD或DA(原理一样)、液晶、蜂鸣器,有这些就差不多了。如果上面提到的这些,你能熟练应用,那可以说对于单片机方面的硬件你已经入门了,剩下的就是自己练习设计电路,不断的积累经验。
回复

使用道具 举报

12#
ID:355173 发表于 2020-6-22 17:17 | 只看该作者
多做实验,自己动手去做才会发现其中隐藏了许多自己没注意到的各种坑,然后从中找到解决方法,多去看各个寄存器的作用以及单片机的datasheet
回复

使用道具 举报

13#
ID:772467 发表于 2020-6-22 19:23 来自手机 | 只看该作者
大概了解整体框架,后来的实验设计,会逼着你学会很多
回复

使用道具 举报

14#
ID:787349 发表于 2020-6-23 09:32 | 只看该作者
我觉得可以结合一些实际的需求或者是例子,这样有了时间节点要求的话就会倒逼自己去学。再有串口什么的原理可以去b站看视频学习很快就能学会
回复

使用道具 举报

15#
ID:147017 发表于 2020-6-23 10:32 | 只看该作者
找一些自己感兴趣的dome入手,这样的话会更快的有成效
回复

使用道具 举报

16#
ID:91521 发表于 2020-6-23 12:19 | 只看该作者
基础一定要扎实,以后多看一些别人编的程序就可以了
回复

使用道具 举报

17#
ID:452950 发表于 2020-6-25 13:18 | 只看该作者
自己设计一个小项目,解决制作过程中实际遇到的问题,就能理解的更透彻。
回复

使用道具 举报

18#
ID:363342 发表于 2020-6-25 20:41 | 只看该作者
还是得自己多动脑思考,把例程跑几遍后就开始自己试着改程序,后续慢慢自己写
回复

使用道具 举报

19#
ID:695930 发表于 2020-6-25 22:23 | 只看该作者
谢谢大家的回复,我会继续努力的,我发现应该是我在做小项目思考的不够发散,我每次都是做完项目之后就没想了,而我的师兄他想的更深入
回复

使用道具 举报

20#
ID:682197 发表于 2020-6-27 18:45 | 只看该作者
51单片机新手也就50多个程序去了解,点灯,键盘,蜂鸣器,中断,串口,lcd,ds18b20...,半年能学完自己打一遍就不错了。
多看视频,再去看书,视频有些人已经总结好了,现在跟以前不一样了,要学会利用网络,看书只是复习或查缺,看数据手册是做单片机必备的,越早学习怎么看越好。
多参加比赛,做项目是最锻炼自己和提高最快的,学不下去就是没有时限和动力,一旦你做下去的时候,你会发现其实时间会越来越不够
回复

使用道具 举报

21#
ID:733205 发表于 2020-7-21 15:20 | 只看该作者
慢不要紧,只要每一次比上一次有进步就行,快也并不一定好,基础打牢点更好
回复

使用道具 举报

22#
ID:981034 发表于 2022-1-21 14:25 | 只看该作者
欲速则不达,慢慢来
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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