中颖

1、8bit MCU 通用I/O 结构图

端口模块如下图(79系列图):

“中颖8bit

2、相关设置寄存器及注意事项:

端口控制寄存器

“中颖8bit

“中颖8bit

PxCR寄存器控制I/O输入输出状态设置。

当寄存器设置成输入模式时,Px寄存器读取的是端口电平状态。

当寄存器设置成输出模式时,Px寄存器读取的是数据寄存器的值。

如有未使用到的I/O,需要设置输出固定电平以免I/O浮动电平带来的漏电流。

端口上拉电阻控制寄存器

“中颖8bit

“中颖8bit

端口数据寄存器

“中颖8bit

“中颖8bit

79系列单片机 Px 寄存器都在位寻址区(例如:80H,88H等),都可以进行位寻址操作。

在初始化设施PxCR(输出状态)前,请优先设置Px寄存器,避免WDT,,OVL等复位带来的端口电平变化。

当PxCR寄存器设置成输入状态时,操作读取对应Px,是读取对应引脚电平状态。

当PxCR寄存器设置成输出状态时,根据指令来分别对应 读取的是寄存器还是引脚电平。

端口寄存器读-改-写指令举例:

ANL P0, #立即数 ; P0->立即数&(与)P0->P0

ORL P0, A ; P0->A|(或)P0->P0

INC P0 ; P0->P0+1->P0

CPL P0.0 ; P0.0->P0.0~(取反)->P0.0

引脚电平读取指令举例:

MOV A,P0 ; P0->A

MOV R0, P0 ; P0->R0

不管端口是否共享为其它功能,对端口写操作都是针对端口数据寄存器。

当第二功能有冲突时,按照端口共享表格中的优先级来决定输出功能。

通常I/O的优先级是低于其他功能的。

以下图为例,当P0.6引脚上BUZ功能和LED功能同时选中时,引脚输出LED波形。

“中颖8bit

当允许端口复用为其它功能时,用户可以修改PxCR﹑PxPCR,但在复用的其它功能被禁止前,这些操作不会影响端口状态。

当允许端口复用为其它功能时,任何对端口的读写操作只会影响到数据寄存器的值,端口引脚值保持不变,直到复用的其它功能关闭。

3、 I/O开漏模式介绍:

“中颖8bit

在I/O章节有选择N沟道开漏功能的寄存器时,可以实现I/O的N沟道开漏功能(注意上图红线处,IO管脚的电压不得超过VDD+0.3V电压)

如果I/O章节没有该选项的寄存器,但是又有TWI通讯功能,那么在TWI功能开启时,引脚自动切换成N沟道开沟。关闭TWI功能,自动切换回普通I/O。

芯片的电源输入端建议加去耦电路,防止VDD端出现瞬间的高压引入导致的电路损坏。

4、施密特及TTL功能介绍:

施密特功能介绍:

施密特输入特性是输入高电平阈值为0.8VDD,输入低电平阈值为0.2VDD。

VDD=5V举例,输入高电平>=4V,端口读取的电平为高,输入低电平<=1V,端口读取的电平为低。相对应的引脚是否具有施密特功能,请查询电气特性章节(输入高电压2和输入低电压2中注明有施密特功能的引脚,例如INT0-4,T3-T5等)。普通I/O不具有施密特功能。

TTL功能介绍:

TTL电平输入特性是

1) 输入高电平阈值为0.25VDD+0.8,输入低电平阈值为0.15VDD(VDD=2.7V~4.5V)

以VDD=3.3V举例,输入高电平>=1.625V,端口读取的电平为高,输入低电平<=0.495V,端口读取的电平为低。

2)输入高电平阈值为2.0V,输入低电平阈值为0.8V(VDD=4.5V~5.5V)

以VDD=5 V举例,输入高电平>=2V,端口读取的电平为高,输入低电平<=0.8V,端口读取的电平为低。

选择TTL电平功能可与VDD电压为3.3V的WIFI模块直接通过以Uart或者TWI的方式通讯,又或者直接接收外部中断信号(INT0-4),不需要外加电平转换电路。(芯片是否有TTL功能请查询I/O章节及电气特性章节)

端口输入模式选择寄存器如下(TTL和CMOS选择)

“中颖8bit

“中颖8bit

*:CPU在任何情况下,读取端口数据寄存器(P0,P1……),其输入高电平阈值为0.7VDD,输入低电平阈值为0.3VDD(CMOS逻辑,无施密特);该控制位控制的是其他功能输入的逻辑电平状态,例如:INT0 - 4,RXD,SDA等数字电平输入。

注意:TTL电平特性,详情请见规格书电气特性章节。

来源:中颖电子
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 131

在MCU程序开发调试过程中,总会发现很多的程序bug。有一些bug是逻辑问题,规格书理解问题,笔误问题等,以上列出的这些问题,通过断点,单步等调试手段,很容易发现并解决问题。但是有一些程序的bug就比较难通过常规手段定位出问题的地点和原因,例如:芯片不定时跑飞和复位。

以下总结了芯片不定时跑飞和复位的5大原因

1、看门狗复位

原因:程序中使用了看门狗,但是没有及时清看门狗,从而导致看门狗复位,使程序直接跳到复位位置。

解决方法:通过读或写RSTSTAT寄存器,在程序中清看门狗。

示例:

A.程序中写RSTSTAT寄存器清看门狗。

“中颖8bit

2、中断服务程序缺失

原因:程序中打开了某个中断,但是没有相应的中断服务程序,从而导致在中断发生后,找不到中断服务程序入口,从而导致程序跑飞。

解决方法:检查程序中是否存在打开了某个中断,但是没有相对应的中断服务程序。

示例:

A.使能外部中断0,并且屏蔽外部中断0服务程序。

“中颖8bit

“中颖8bit

B.下降沿触发外部中断0后,程序跑到地址0x0003处(INT0向量地址为0x0003),由于没有中断服务程序,该地址的指令被编译器填充为初始化程序,因此导致程序跑飞。

“中颖8bit

3、 中断服务程序没有对bank压栈和出栈

原因:主程序在操作bank1寄存器时,进入中断没有对bank1压栈,此时切换到bank0对寄存器操作,退出中断后由于没有保存bank1的状态,导致主程序在bank0中对bank1的寄存器操作,误改bank0寄存器的值,程序可能会运行异常。

解决方法:进入中断服务程序后,对bank进行压栈,退出中断之前对bank进行出栈,这样无论主程序在操作bank0还是bank1,中断里面都会保存进中断之前bank状态,退出中断后会还原bank状态,这样就不会因为切换bank导致寄存器的值被误改。

示例:

A.在主循环操作bank1寄存器,定时器Timer3中断里面不进行压栈和出栈操作,直接操作bank0寄存器。

“中颖8bit

B.退出中断后此时程序状态为bank0,下一步返回主程序,本来应该改变的是P5_0的值,由于没有切换到bank1,所以在bank0中将相同地址的寄存器P0_0的值误改,同时导致P5_0的值修改无效。

“中颖8bit

“中颖8bit

“中颖8bit

4、数组越界

原因:程序中定义的数组元素的个数小于程序中实际使用的数组元素的个数,数组使用循环函数时,如果循环变量没控制好则会出现数组越界,意外修改其他变量值可能会导致程序异常。
解决方法:检查函数中调用的数组是否存在越界的情况。

示例:

A.定义SendBuffer和RecBuffer两个数组变量,数组长度为5,初值均为0。

“中颖8bit

B.主程序中对数组SendBuffer[0]~ SendBuffer[4]赋值,此时SendBuffer[5]和SendBuffer[6]也被意外赋值,从watch窗口可以看出,这两个值改变了原来RecBuffer[0]和RecBuffer[1]的值,可能会造成程序异常。

“中颖8bit

“中颖8bit

5、堆栈溢出

原因:函数嵌套太深或者局部变量太多导致超出堆栈空间,正常数据被改写。

解决方法:尽量减少函数调用层级,局部变量不要使用太多,尤其是局部大数组,从而减少压栈的时候所需的空间。
示例:

A.定义4个全局变量和1个局部变量数组,总共占用RAM空间为249个字节

“中颖8bit

“中颖8bit

B.计算程序中所需的堆栈大小,主程序中调用Delay()函数,占用2个字节,中断服务函数占用16个字节,中断嵌套调用leddisplay()函数,占用2个字节,总共需要20个字节堆栈空间,由A可知,系统只剩下6个字节堆栈空间,所以程序运行后,堆栈一定会溢出。

“中颖8bit

“中颖8bit

“中颖8bit

C.运行程序,正常现象为P40端口一直翻转,TestData变量值始终为0,触发外部中断0,进入中断服务程序后,可以看到SP堆栈指针已经溢出,同时将R7寄存器的值压栈到0x08的地址上,通过.m51文件可以查到0x08正好是TestData变量地址,所以TestData的值被误改为0x01,导致主程序中条件判断出错,程序异常。

“中颖8bit

“中颖8bit

“中颖8bit

“中颖8bit

在调试MCU程序过程中,由于程序书写的不规范产生程序漏洞,跑飞现象比较常见,如果我们提前了解程序可能跑飞的原因,对于快速定位问题有很大帮助,从而提高分析和解决问题的效率,减少产品的开发周期,加速产品的上市时间。

来源:中颖电子
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 53

中颖很多8位MCU产品支持外部32.768kHz晶振,用作系统低频时钟和RTC时钟。有几个常用的控制寄存和代码选项与32.768kHz晶振电路相关,下文以SH86F7088举例逐一说明。

1、32K_SPDUP

32K_SPDUP是32.768kHz晶振加速模式控制位,位于时钟控制寄存器(CLKCON)的最高位,上电默认是使能状态。只有代码选项OP_OSC选择了32.768kHz晶体振荡器,此控制位才有效。

此寄存器位在系统发生任何形式的复位,如上电复位、看门狗复位等时,自动由硬件置1(使能),用以加速32.768kHz振荡器起振,缩短起振时间。

如果有需要,本位也可以由软件置1(使能)或者清0(关闭)。比如进入掉电模式前,可以将此位置1,掉电模式唤醒后再由软件清0。

使能此位后,会增加一点系统功耗。在低功耗应用中,可以关闭32.768kHz加速模式(此位清0)以节省系统耗电。

2、OP_32KDRIVE

OP_32KDRIVE是用户代码选项,用于使能晶振电路的强驱模式。在此模式下,晶振电路的抗湿度能力会显著增强,但功耗也会相应增加。此代码选项的初始默认设置是普通模式。

为了方便程序控制强驱模式,IC还设计了一个寄存器控制位(32K_DRIVE),功能同此代码选项相同。

备注:

(1) 使能强驱模式时,晶振匹配电容不能小于15pF;

(2)一旦使能强驱模式,即使没有使用外部32K晶振,增加的功耗也会持续存在。

3、32K_DRIVE

32K_DRIVE是32.768kHz晶振强驱模式的寄存器控制位,位于时钟控制寄存器(CLKCON)的bit 1,复位初始值由代码选项OP_32KDRIVE给出。只有代码选项OP_OSC选择了32.768kHz晶体振荡器,此控制位才有效。

寄存器控制位32K_DRIVE和代码选项OP_32KDRIVE的功能相同,都是强驱模式控制位,但是它们的有效范围有一些区别:

(1) IC复位后,OP_32KDRIVE有效,强驱模式受代码选项控制,此时32K_DRIVE的初始值同OP_32KDRIVE的值。

(2) 用户用程序修改32K_DRIVE的值后,32K_DRIVE生效,强驱模式受寄存器位控制。此时OP_32KDRIVE无效,直到发生系统复位后才再次生效。

4、OP_32KLCAP

OP_32KLCAP是用户代码选项,用于配置芯片内建的32.768kHz晶振匹配电容,初始默认设置是选择12pF内建电容。

内建匹配电容用于替代片外匹配电容,可以精简BOM。如果要使用片外匹配电容,需要用此代码选项关闭内建匹配电容。内建匹配电容有7档可选,容值范围8~25pF,容值最大偏差±15%。

为了方便程序选择内建电容值,IC还设计了寄存器控制位(LCAP[2:0]),功能同此代码选项相同。

5、 LCAP[2:0]

LCAP[2:0]是寄存器控制位,也是用来配置芯片内建的32.768kHz晶振匹配电容。位于内建电容选择寄存器(OSCLCAPS)的bit[2:0],复位初始值由代码选项OP_32KLCAP给出。只有代码选项OP_OSC选择了32.768kHz晶体振荡器,此控制位才有效。

寄存器控制位LCAP[2:0]和代码选项OP_32KLCAP的功能相同,都是配置内建匹配电容,但是它们的有效范围有一些区别:

(1) IC复位后,OP_32KLCAP有效,内建匹配电容受代码选项控制,此时LCAP[2:0]的初始值同OP_32KLCAP的值。

(2) 用户用程序修改LCAP[2:0]的值后,LCAP[2:0]生效,内建匹配电容受寄存器位控制。此时OP_32KLCAP无效,直到发生系统复位后才再次生效。

来源:中颖电子
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 131

页面

订阅 RSS - 中颖