标题:
新手学习单片机进度很慢,应该如何学习?
[打印本页]
作者:
你速度发生的
时间:
2020-6-20 20:31
标题:
新手学习单片机进度很慢,应该如何学习?
本帖最后由 你速度发生的 于 2020-6-21 00:11 编辑
我想咨询各位大佬,我是19级大一,我学习单片机有半年左右,对单片机的理解只到大概可以看懂,51普中的板子例程也都走了一遍。但是和我一师兄习单片机的师兄他就比我深入很多,我们那个时候制作一个小项目LCD1602液晶显示温度并设定温度上下限,蜂鸣器报警提示超限。我师兄他制作这个程序只有
这是不是说明我学习的进度慢了他很多,我看单片机的书看到时序,串口什么的原理就头疼,看久了就发呆去了,求各位大佬支招。主要是想问学习单片机是否要像我师兄那样深入的学习,我应该怎么学
#include <reg51.h>
#include "temp.h"
#include <stdio.h>
void LcdDisplay(int);
void UsartConfiguration(void);
/*******************************************************************************
* 函数名 : main
* 函数功能 : 主函数
* 输入 : 无
* 输出 : 无
*******************************************************************************/
void main()
{
UsartConfiguration();//初始化
EA=1; //打开总中断
while(1)
{
LcdDisplay(Ds18b20ReadTemp());
Delay1ms(100);//0.1s钟刷一次
}
}
/*******************************************************************************
* 函数名 : LcdDisplay()
* 函数功能 : LCD显示读取到的温度
* 输入 : v
* 输出 : 无
*******************************************************************************/
void LcdDisplay(int temp) //lcd显示
{
static int q=0;
int i=0;
char datas[] = {0, 0, 0, 0, 0}; //定义数组
float tp;
temp=temp-1;
tp=temp;
tp=tp*0.0625+0.5;
// temp=tp*0.0625*100+0.5;
// tp=(float)temp/100;
printf("第%d次测量的温度为:+%0.2f\n",q++,tp);
}
/*******************************************************************************
* 函 数 名 :UsartConfiguration()
* 函数功能 :设置串口
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void UsartConfiguration(void)
{
TMOD=0x20;//即0010 0000,定时器/计数器1,工作方式2
TH1=0xfd;//设置波特率为9600
TL1=0xfd;
TR1=1;//启动定时器/计数器1
SCON=0x50; //0101 0000.串口工作方式1,允许串行控制
PCON=0x00;//设置SMOD=0
IE=0x90; //CPU允许中断,串行允许中断
TI=1;//
}
而我自己的
/*******************************************************************************
注意事项:
根据自己使用的LCD1602是否带有转接板,如果带有转接板的即为4位,需在LCD.H头文件中
将宏#define LCD1602_4PINS打开,我们这里使用的LCD1602是8位,所以默认将该宏注释。
接线说明:(开发攻略每个实验章节内的实验现象都有对应的接线图说明)
LCD1602接线参考LCD1602液晶显示实验接线图
DS18B20传感器接线参考DS18B20温度传感器实验接线图
实验操作:
LCD1602上显示采集的温度,同时
打开串口调试助手,将串口波特率选择9600,打开串口,此时在串口上就会显示采集的温度,串口截图参考文件夹下。
*******************************************************************************/
#include<reg51.h>
#include"lcd.h"
#include"temp.h"
#include<intrins.h> //因为要用到左右移函数,所以加入这个头文件
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
sbit beep=P1^1;
uchar i;
int n=0;
uchar CNCHAR[17] = "第1次测试温度为:";
uchar lx[1]="1";
void LcdDisplay(int);
void UsartConfiguration();
sbit LSA=P0^7;
sbit LSB=P2^3;
sbit LSC=P2^4;
/*******************************************************************************
* 函 数 名 : delay
* 函数功能 : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{
while(i--);
}
/*******************************************************************************
* 函数名 : main
* 函数功能 : 主函数
* 输入 : 无
* 输出 : 无
*******************************************************************************/
void main()
{
UsartConfiguration();
LcdInit(); //初始化LCD1602
LcdWriteCom(0x88); //写地址 80表示初始地址
LcdWriteData('C');
while(1)
{
LcdDisplay(Ds18b20ReadTemp());
if((Ds18b20ReadTemp()>480)||(Ds18b20ReadTemp()<400))
{
for(i=0;i<120;i++)
{
beep=~beep;
delay(100);
};
}
else
{
;
};
// Delay1ms(1000);//1s钟刷一次
}
}
/*******************************************************************************
* 函数名 : LcdDisplay()
* 函数功能 : LCD显示读取到的温度
* 输入 : v
* 输出 : 无
*******************************************************************************/
void LcdDisplay(int temp) //lcd显示
{
unsigned char i, datas[] = {0, 0, 0, 0, 0}; //定义数组
float tp;
if(temp< 0) //当温度值为负数
{
LcdWriteCom(0x80); //写地址 80表示初始地址
SBUF='-';//将接收到的数据放入到发送寄存器
while(!TI); //等待发送数据完成
TI=0; //清除发送完成标志位
LcdWriteData('-'); //显示负
//因为读取的温度是实际温度的补码,所以减1,再取反求出原码
temp=temp-1;
temp=~temp;
tp=temp;
temp=tp*0.0625*100+0.5;
//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
//算由?.5,还是在小数点后面。
}
else
{
LcdWriteCom(0x80); //写地址 80表示初始地址
LcdWriteData('+'); //显示正
SBUF='+';//将接收到的数据放入到发送寄存器
while(!TI); //等待发送数据完成
TI=0; //清除发送完成标志位
tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
//如果温度是正的那么,那么正数的原码就是补码它本身
temp=tp*0.0625*100+0.5;
//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
//算加上0.5,还是在小数点后面。
}
datas[0] = temp / 10000;
datas[1] = temp % 10000 / 1000;
datas[2] = temp % 1000 / 100;
datas[3] = temp % 100 / 10;
datas[4] = temp % 10;
LcdWriteCom(0x82); //写地址 80表示初始地址
LcdWriteData('0'+datas[0]); //百位
SBUF = '0'+datas[0];//将接收到的数据放入到发送寄存器
while (!TI); //等待发送数据完成
TI = 0;
LcdWriteCom(0x83); //写地址 80表示初始地址
LcdWriteData('0'+datas[1]); //十位
SBUF = '0'+datas[1];//将接收到的数据放入到发送寄存器
while (!TI); //等待发送数据完成
TI = 0;
LcdWriteCom(0x84); //写地址 80表示初始地址
LcdWriteData('0'+datas[2]); //个位
SBUF = '0'+datas[2];//将接收到的数据放入到发送寄存器
while (!TI); //等待发送数据完成
TI = 0;
LcdWriteCom(0x85); //写地址 80表示初始地址
LcdWriteData('.'); //显示 ‘.’
SBUF = '.';//将接收到的数据放入到发送寄存器
while (!TI); //等待发送数据完成
TI = 0;
LcdWriteCom(0x86); //写地址 80表示初始地址
LcdWriteData('0'+datas[3]); //显示小数点
SBUF = '0'+datas[3];//将接收到的数据放入到发送寄存器
while (!TI); //等待发送数据完成
TI = 0;
LcdWriteCom(0x87); //写地址 80表示初始地址
LcdWriteData('0'+datas[4]); //显示小数点
SBUF = '0'+datas[4];//将接收到的数据放入到发送寄存器
while (!TI); //等待发送数据完成
TI = 0;
for(i=0; i<17; i++)
{
SBUF = CNCHAR[i];//将接收到的数据放入到发送寄存器
while (!TI); //等待发送数据完成
TI = 0;
}
if((CNCHAR[2]='1')&&(n<9))我只在这里修改了一下
{
n++;
CNCHAR[2]=lx[0];
lx[0]=lx[0]+1;
}
else
{
CNCHAR[2]='1';
lx[0]='1';
n=0;
}
}
/*******************************************************************************
* 函 数 名 :UsartConfiguration()
* 函数功能 :设置串口
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void UsartConfiguration()
{
SCON=0x50;//设置串口工作方式1
TMOD=0x20;//设置计数器工作方式2
PCON=0x00;//即SMOD=1,波特率不加倍
TH1=0xFD;//计数器初值。波特率是9600,晶振为11.0592MHz
TL1=0xFD;
// ES=1; //打开接收中断
// EA=1; //打开总中断
TR1=1;//打开计数器
}
复制代码
作者:
wwh2382
时间:
2020-6-21 10:53
你的师兄除了跟着课本走,还多动了脑子,在原有程序的基础上加了新的东西。这正是你缺少的。编程就要多动脑子,而且是越用越好用
作者:
csmyldl
时间:
2020-6-21 11:36
说明与单片机相关的基础知识薄弱,需要进一步加深学习
作者:
xsjsensei
时间:
2020-6-21 12:47
先从理论知识开始,硬啃,然后结合编程实践应该会好很多
作者:
dzbj
时间:
2020-6-21 18:06
这事的关键不在技术本身 在你自己 你是特想学么 你是一定要学么 如果俩条件都满足 时间其实不是问题 人的进步又不是线性的 也许是对数曲线也许是指数曲线
作者:
TTQ001
时间:
2020-6-21 23:18
要很好地学习单片机,需要大量的实践经验,例如编程和制作。
作者:
17803856022
时间:
2020-6-22 07:40
理论+实践,从中深层次理解!!!
作者:
gxslxxm
时间:
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的基本原理和硬件的知识。。
作者:
爱你的猪
时间:
2020-6-22 10:48
从简单的开始做起,从驱动定时串口中断等一步步学习,代码复杂的肯定比简单的费脑子
作者:
NiiBoo
时间:
2020-6-22 11:00
先看单片机原理,再学编程。
作者:
1398653046
时间:
2020-6-22 15:13
找一块单片机开发板进行练习。可以自己花钱买一块单片机的开发板,不需要功能太全,对于初学者来说功能非常多的板子,上面有很多东西你这辈子都用不着。建议有流水灯、数码管、独立键盘、矩阵键盘、AD或DA(原理一样)、液晶、蜂鸣器,有这些就差不多了。如果上面提到的这些,你能熟练应用,那可以说对于单片机方面的硬件你已经入门了,剩下的就是自己练习设计电路,不断的积累经验。
作者:
a179996496
时间:
2020-6-22 17:17
多做实验,自己动手去做才会发现其中隐藏了许多自己没注意到的各种坑,然后从中找到解决方法,多去看各个寄存器的作用以及单片机的datasheet
作者:
苣茜
时间:
2020-6-22 19:23
大概了解整体框架,后来的实验设计,会逼着你学会很多
作者:
想吃鱼的虾
时间:
2020-6-23 09:32
我觉得可以结合一些实际的需求或者是例子,这样有了时间节点要求的话就会倒逼自己去学。再有串口什么的原理可以去b站看视频学习很快就能学会
作者:
drf63329272
时间:
2020-6-23 10:32
找一些自己感兴趣的dome入手,这样的话会更快的有成效
作者:
daiya
时间:
2020-6-23 12:19
基础一定要扎实,以后多看一些别人编的程序就可以了
作者:
xxpp2011
时间:
2020-6-25 13:18
自己设计一个小项目,解决制作过程中实际遇到的问题,就能理解的更透彻。
作者:
是啊啊啊啊啊
时间:
2020-6-25 20:41
还是得自己多动脑思考,把例程跑几遍后就开始自己试着改程序,后续慢慢自己写
作者:
你速度发生的
时间:
2020-6-25 22:23
谢谢大家的回复,我会继续努力的,我发现应该是我在做小项目思考的不够发散,我每次都是做完项目之后就没想了,而我的师兄他想的更深入
作者:
阿铭不吃小辣椒
时间:
2020-6-27 18:45
51单片机新手也就50多个程序去了解,点灯,键盘,蜂鸣器,中断,串口,lcd,ds18b20...,半年能学完自己打一遍就不错了。
多看视频,再去看书,视频有些人已经总结好了,现在跟以前不一样了,要学会利用网络,看书只是复习或查缺,看数据手册是做单片机必备的,越早学习怎么看越好。
多参加比赛,做项目是最锻炼自己和提高最快的,学不下去就是没有时限和动力,一旦你做下去的时候,你会发现其实时间会越来越不够
作者:
草草111111
时间:
2020-7-21 15:20
慢不要紧,只要每一次比上一次有进步就行,快也并不一定好,基础打牢点更好
作者:
HAPPY3
时间:
2022-1-21 14:25
欲速则不达,慢慢来
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1