一、前言

  本人工作中经常会使用STC单片机做完成一些简单工作,但是在使用过程中会遇到一些意想不到的东西。本文的名字是“那些年使用STC单片机踩过的坑”,目的去记录一些使用STC单片机需要注意的点,有些是在官方渠道中有解释的点,有些则是坑人不眨眼,连官方都没有解释的点。

二、STC15系列与引脚相关的模式配置寄存器必须初始化

  指的是PaMb系列寄存器,a为[0:7],b为[0:1],这些寄存器是用来配置引脚模式的,以P0为例,如下图:

  

  我一直以为这些寄存器的初始值为都0,实际并非如此,这16个寄存器中有5个初始值不是0。其实也没必要去记哪些寄存器的初始值不是0,只要在使用某个引脚的时候记得要修改对应的引脚配置即可。

 三、IAP15F4K32S4单片机内部时钟频率无法改变

  写了一个简单的串口程序,就是以9600的波特率,发送0x55,用的是外部11.0592MHz的晶振,用逻辑分析仪采样得出的结果如下:

  

  可见一个脉冲的宽度为104.5us,实际上9600波特率的脉冲宽度应该为1000000/9600≈104.17us,算上逻辑分析仪的采样精度,这个结果是没问题的。

  当我把时钟改为内部时钟,然后再下载运行程序后,得到的结果如下图:

  

   很显然,这个结果比预期值差太远了。

PS:程序下载完成后,有这样的提示:

  内部/外部时钟源切换,目标芯片需要重新上电后才有效 !
  若是由外部时钟切换到内部时钟,需重新下载一次才可正确调节频率 !

  

  本次测试是遵循了这个规则的,而且是不断的下载、断电、断电,得到的结果非常一致,都是48us。

  有人可能会说会不会是晶振频率选的不对,这点我确信是对的,而且程序下载成功后会将真实频率显示出来,如下图:

   

   如果是这样的话,那实际频率比预想中的快2倍多,这属实有点离谱。

  为了进一步验证问题所在,我在STC-ISP软件中将内部时钟改成不同的值,结果竟然是:无论我将时钟频率调到多少,得到的结果是一样的。

  这意味着有可能是我使用的芯片有问题,有可能是STC-ISP软件有问题。

  在网上搜了一圈,还真发现有类似的问题,并且在官方的说明网站中找到了这个:

  

   我使用的芯片型号为IAP15W4K61S4,但是这个网站里并没有找到类似信息,我下了一个6.36版本的软件,发现这个版本的软件还不支持IAP15W4K61S4的下载。然后我又测试了6.88L和6.88K,都没解决问题。(我写这篇文章时最新版是6.88L)

  于是乎,我直接去百度搜“IAP15W4K61S4时钟不准”,好家伙,2015年就有人遇到过这个问题了:https://www.amobbs.com/thread-5629386-1-1.html

  但是这个帖子并没有给出解决办法,在别的地方也没找到解决办法,现在已经放假了,所以想等上班以后问问STC的工程师吧。

  经过验证,IAP15W4K61S4这个“不能改变的频率”是24M,所以我写的程序按照24MHz的频率写就没问题了(向黑恶势力低头)。

四、使用外部晶振读不到bandgap的值

  我们知道,使用AD转换芯片去测量某个电压时,得到的值并不是电压值,而是基于某个电压的参考值,那么AD转换结果的可靠性就和这个参考值的可靠性相关了。

  STC单片机声称具有一个非常准确的参考电压,就是bandgap电压,不会随芯片的工作电压的改变而变化,如果能把这个功能用上的话,那相当于可以节省一个外部的参考电压源,这个功能无疑是非常好的。

  但是有一个前提,就是必须使用片内时钟。否则无法正确的读出bandgap电压。这个问题和上个问题把我坑的不要不要的。

  再提一嘴,如果要获取bandgap电压,在下载程序时除了要选用内部时钟以外,还要勾选“在程序区的结束处添加重要测试参数”,如下图:

  

 

  并且在程序内要根据芯片型号选择正确的ID_ADDR_ROM值。在官方例程里有从1K ROM到60K ROM的定义,IAP15W4K61S4是61K ROM,要自己写上去,值为0xF3F7。

 五、IAP系列单片机每次下载都会整片擦除EEPROM

  我使用的单片机型号为:IAP15W4K61S4,下载时的硬件选项中:“下次下载用户程序时擦除用户EEPROM区”这个选项是强制不能勾选的,如下图:

  

   但是从我的实验现象中发现,每次重新下载都会整片擦除。

  查看芯片手册发现这样的描述:

  

  有些系列程序存储空间和用户的存储空间是分开的,而我选的这个系列程序存储空间和用户存储空间是不分开的,所以下载程序时就不区分,直接全部擦除?这只是我的猜想。