[应用相关]

单片机学习中的常见问题

[复制链接]
1291|78
手机看帖
扫描二维码
随时随地手机跟帖
工程师犹饿死|  楼主 | 2021-11-19 16:22 | 显示全部楼层 |阅读模式
在单片机学习中,我们常常遇到这样那样的零星问题,这里我将我遇到的问题总结如下,都是个人见解,如果不对,望指出。

问题0001:51单片机下载失败常见原因

1.查看单片机是否插反了;


2.下载软件选择正确的单片机型号(注意STC89C52和STC89C52RC是不同的) ;


3.检测是否连接了晶振 ,时候有晶振接触不良的现象 ;


4.查看电脑com是否有多个,是否选错了com口 (是否安装了相应的驱动);


5.单片机开发板是否重新上电了(下载单片机程序需要冷启动过程) ;


6.注意是否有短路(比如开发板下面最好铺一张纸,不要被短路) ;


7.下载软件用的什么版本,旧版本可能需要设置最低、最高波特率,并且还会出现很多奇怪的现象,比如第一次烧写用一个波特率,第二次就不行了,但是有时候却一直可以(个人经验)。新版本不用设置,并且不用等待软件提醒上电才可以上电,点击下载后,直接重新上电即可,建议尽量使用新版 ;


8.如果使用的是CH340/CH341或者PL2302,检测RXD/TXD是否连接反了。(注意PL2302,驱动,新版的驱动只支持正版芯片,这个一定要注意,很多人会沿用老版本驱动,不建议用PL2302)

9.换一个单片机试试看,验证单片机是否已损坏。


10.一部分人修改上一次工程代码,然后直接编译,下载无效果。可能是新的代码编译有错(编译有三个按钮,请注意区别差异),导致目标文件未生成,hex文件未更新,所以下载的还是上一次的程序。这里要注意。


11.STC-ISP软件选择hex文件后,要勾“每次下载前都重新装置文件”,这样有三大好处:(1)免去每次编译都重新手动装在hex文件(2)避免因忘记手动重新装载hex文件,而导致下载的hex文件还是上一次的hex文件,代码下载后现象和上一次一样,误以为还是程序问题(3)方便快速调试代码。


12.连接线可以出现问题,比如接触不良,线头脱断等。


13.芯片“锁死”。STC-ISP软件设置问题,上一次下载程序的时候,在STC-ISP可能勾选了“下次冷启动时,P1.0 / P1.1为0/0才可以下载程序” , 这种情况,试着将此两个IO拉低,下载程序试试看。


使用特权

评论回复
工程师犹饿死|  楼主 | 2021-11-19 16:23 | 显示全部楼层
问题0002:学习单片机我们都需要什么软件
最近看到群里面有很多人为了学习单片机,下载了STC-ISP,然后又下载了串口软件、单片机小精灵、定时器计算神器之类的,可谓五花八门,但是实际我们并不需要那么多的软件。

1840461975f0ef08f0.png

使用特权

评论回复
工程师犹饿死|  楼主 | 2021-11-19 16:24 | 显示全部楼层
大家注意到STC-ISP软件已经附带了很多功能了,学会使用这些功能可以让我们事半功倍。另外,STC手册上有C语言和汇编语言程序,值得参考。下面在分析几款常用软件给大家:

keil4 : 点击打开链接   (附带我下载的两个仿真插件,可以做很多仿真)

STC-ISP 下载方式:进入www.**.comwww.**.com  然后CTRL+F搜索STC-ISP即可。

BCompare : 点击打开链接 (快速比较文件差异,便于对比程序)

Proteus7.5 仿真:点击打开链接    (文件中包含我录制的**过程,目前我的系统为W8.1暂时未发现使用问题)

Multisim 仿真 :点击打开链接

Source Insight : 点击打开链接(适合编写代码,非常方便)

SecureCRT7 :点击打开链接 (免**)

Altium Designer6.9 : 点击打开链接

Altium Designer14.2.3 : 点击打开链接

屏幕录制专家: 点击打开链接 (有时候交流沟通,录制视频更加简单直接)

使用特权

评论回复
工程师犹饿死|  楼主 | 2021-11-19 16:24 | 显示全部楼层
另外,单片机采用C语言编程的学生,有两本书必须要度:

华为技术有限公司c语言编程规范.pdf :https://download.csdn.net/download/weixin_42202078/15594778
高质量C编程指南—林锐.pdf  : https://download.csdn.net/download/weixin_42202078/15594778

使用特权

评论回复
工程师犹饿死|  楼主 | 2021-11-19 16:25 | 显示全部楼层
问题0003:51类单片机需要冷启动,但是一定要手动重启开关一次吗
  51类单片机下载程序时必须冷启动,这是大家都知道的。昨天,一个学生告诉我他是用的普中科技开发板,他用普中科技的下载软件去下载程序,发现不是很好用。我告诉他STC-ISP下载软件非常好用,他说STC-ISP软件必须经过手动重启开关完成下载,而普中科技的开发板,可以完成全自动下载,只需点击“下载”按钮即可,无需手动重启开关,并且普中科技技术支持告诉他,只能使用他们的软件才能够完成全自动下载(我对此只能呵呵)。本人也是采用普中科技开发板,普中科技的自动下载功能确实存在,但是我使用过发现并不是很好用,而且需要结合它的开发板硬件才行。这里介绍一下我使用过的两种“全自动”下载(可能方法还有很多,需要广大网友的补充)

使用特权

评论回复
工程师犹饿死|  楼主 | 2021-11-19 16:26 | 显示全部楼层
(1)硬件法:利用STC自动下载器,点击下载后,模块会自动重新上电,完成下载任务,需要淘宝购买,约9~13元。
(2)软件法:利用串口结合IAP功能,点击下载,模块自动完成下载,无需手动重启。(版本古老的芯片无此功能)此方法可参考我的笔记:stc单片机“全自动下载”(程序版) http://blog.csdn.net/yagnruinihao/article/details/21739665

使用特权

评论回复
工程师犹饿死|  楼主 | 2021-11-19 16:26 | 显示全部楼层
为了简化问题,这里把程序简化为2行(先不要看变量i是否有意义)
3003861975fc241f48.png

使用特权

评论回复
工程师犹饿死|  楼主 | 2021-11-19 16:27 | 显示全部楼层
342161975fe25d744.png

使用特权

评论回复
工程师犹饿死|  楼主 | 2021-11-19 23:22 | 显示全部楼层
在C语言方面,这是可以的(尽管这样不是很规范),但是在keil4中,却出现了问题,网上百度,说可能是有中文字符,但是我将程序删除后,编译没有错误,切换输入法,再次输入图片2的内容,出错,将int i=0 ; 剪切到第一行,错误消失。还有一个可能是软件出错(经过测试,排除可能性)。
所以,在单片机编程中,最好将变量的定义放在执行语句的前面。

使用特权

评论回复
工程师犹饿死|  楼主 | 2021-11-19 23:24 | 显示全部楼层
问题0005:程序中的“死循环等待”正确吗?


在单片机程序中,有时候会需要“死循环等待”,也就是等到某一条件我们才需要执行下面的操作。这里以温度传感器DS18B20为例,主机首先需要发送一个存在检测脉冲,如果DS18B20存在,则它会以60us至240us的电平来回应主机,这里就会需要一个“死循环等待”,我们必须等到DS18B20“回应完成”,这时候主机才能继续发送指令到DS18B20中去,这时候很多人会采用这样的方式:(首先假设sbit ds18b20_io_bit = P3^7 ;)
则,while( !ds18b20_io_bit) ;

使用特权

评论回复
工程师犹饿死|  楼主 | 2021-11-19 23:25 | 显示全部楼层
这样的代码其实是有问题的,在未连接DS18B20或者接触不良时,DS18B20并不能回应主机,这样的代码就会有问题,尤其在大工程中,所以,为了安全,我通常的做法是:
第一步:
while( (!ds18b20_io_bit) ;
P1=0x01 ; //led
如果,P1口的led有变化,则表示我们“程序在逻辑上和时序上没有问题”

使用特权

评论回复
工程师犹饿死|  楼主 | 2021-11-19 23:25 | 显示全部楼层
第二步:
将上面的代码修改为:
unsigned long i=0
while( ( (!ds18b20_io_bit) && (i++)) ;
然后打印 i ,
因为i一般都很小,所以这时候我一般将unsigned long 修改为unsigned char 类型,然后最后修改为这样
while( (!ds18b20_io_bit)&& (i++ <250)) ;
注意这里的250不是随意写的,是经过测试的,经过测试,我读出的i值远小于250,我才这样做的,如果在其他类似的地方,打印出来i是其他较大的值,那就重新定义i的类型为unsigned int 或者unsigned long ,根据具体情况而定。
  上面的修改似乎意义不大,但是在大工程中,这样不会因为DS18B20的“不存在”而导致整个程序“死循环等待”。

使用特权

评论回复
工程师犹饿死|  楼主 | 2021-11-19 23:26 | 显示全部楼层
问题0006:指针能否指向特殊功能寄存器


特殊功能寄存器的寻址方式只有直接寻址和位寻址。没有间接寻址方式。而指针却是间接寻址方式,不能通过指向特殊功能寄存器的指针来操作特殊功能寄存器。
例:利用指向0x90的指针来操作P1口的LCD灯(高电平时LCD点亮)(P1口的地址是0x90,但是属于特殊功能寄存器区)
#include <stdio.h>
#include "./stc/stc12c5a60s2.h"

void main(void)
{
unsigned char *p=0x90;

while(1)
{
*p=0x55;/*从这里看,似乎应该是LCD每隔一个被点亮,但是事实却并非这样*/
}
}


使用特权

评论回复
工程师犹饿死|  楼主 | 2021-11-19 23:27 | 显示全部楼层
问题0007:“判忙” 函数重要吗

在某些芯片操作时,会有一些引脚或者寄存器或地址的数据被用来表明当前芯片处于的状态为忙碌状态或者空闲状态,如果忙碌,单片机需要用轮询的方式等待直到芯片空闲下来才继续发送指令或数据。这里以1602液晶屏为例:

使用特权

评论回复
工程师犹饿死|  楼主 | 2021-11-19 23:40 | 显示全部楼层
一个朋友用ST89C52操作1602液晶屏,操作成功,后来换了芯片STC12C5A60S2,同样的程序,显示出来的却是“乱码”,后来经过测试,程序部门似乎没有问题,于是,我在LCD1602的“写命令”函数和“写数据”函数中

使用特权

评论回复
工程师犹饿死|  楼主 | 2021-11-19 23:42 | 显示全部楼层
加入了延时(只是为了快速测试),下载后,两个芯片都运行正常。其实对于LCD1602,一般都不需要“判忙”,它运行时比较快的,但是如果将一个没有“判忙”的1602液晶屏模块封装起来,在调试一个大工程时,这时候

使用特权

评论回复
工程师犹饿死|  楼主 | 2021-11-19 23:42 | 显示全部楼层
因为换了芯片,导致整体效果错误,这就是增加了调试难度。比如在利用LCD1602学习使用时钟芯片DS1302时,如果显示乱码,这时候,因为你的LCD1602是实验的基础环节,肯定是你之前就已经封装好了的,这时候

使用特权

评论回复
工程师犹饿死|  楼主 | 2021-11-19 23:43 | 显示全部楼层
你肯定会怀疑DS1302环节操作出错了,这就增加了调试的难度和时间。所以,“判忙”函数必不可少。这里,又有一个技巧,就是防止程序“卡死”,含义与本文中的问题0002类似。

使用特权

评论回复
工程师犹饿死|  楼主 | 2021-11-19 23:45 | 显示全部楼层
起初LCD1602的核心操作为:
do{
;
}while( (lcd1602ReadStatus()) & 0x80));

使用特权

评论回复
工程师犹饿死|  楼主 | 2021-11-19 23:46 | 显示全部楼层
后来我变为
unsigned long i=0 ;
do{
i++;
}while( (lcd1602ReadStatus()) & 0x80);
UartSendValue("i = " ,i) ;/*利用串口打印出i的值*/

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

59

主题

798

帖子

0

粉丝