牛卧堂MCU技术交流

标题: 说说新唐8051关于SFR多个page那些事 [打印本页]

作者: jamesliu    时间: 2019-12-11 14:54
标题: 说说新唐8051关于SFR多个page那些事
本帖最后由 jamesliu 于 2020-6-15 11:18 编辑

由于8051的特殊寄存器(SFR)只有128个字节,但是现在MCU的功能越做越强大,集成了很多外设在芯片中,使用这些外设就需要通过SFR去设置,这样一来导致128个字节的SFR根本不够用,那怎么办?于是用page的方式解决,将SFR寄存器放在不同page中,可以增加SFR访问的字节数。


大家有没考虑过增加page带来的副作用?
代码里对SFR访问时需要频繁的切换page,会增加额外的代码量,其实这不是致命的问题。
主要问题是中断程序中切换page带来的影响,比如主循环中刚刚切换到page0,下一步对page0中SFR读\写操作,但是这时被中断打断了,进入中断中又切换到page1,退出中断后,此时代码中想对page0的SFR读\写操作,其实是对page1相同地址读\写操作,就根本没有读\写成功,更糟糕的是还破坏了page1中SFR值。
如何解决中断中切换page问题,我们可以对page选择SFRS寄存器进行压栈和出栈保护。怎么实现?很简单如下操作:


注意:下面截图代码有个问题,TH0和TL0是在page0,代码少了一句SFRS = 0;

以KeilC51为例,注意使用push和pop要#include ”intrins.h”


IAR为例,注意0x91SFRS的地址

除此之外还会遇到哪些问题呢?
使用UART printf 打印不出SFR的值
建议使用XRAM来暂存不同页内需要打印的SFR值,再回到SFRS PAGE0来印出。以ML51EB9AE为例,演示如何打印出PWM0C1H的值。因为UART0的SBUF所在位置为page 0且PWM0C1H所在位置为page 1,需先将PWM0C1H值存入XRAM中再将SFR page切换至SBUF 所在page,才能正确的印出PWM0C1H的值。范例程序如下图所示。
切记调用printf前一定先切换到page0,否则代码会卡死在printf函数中。


注意:有些型号的SFRS是受到TA写入保护(比如N76E003),那是不适合用压栈、出栈的方式在中断里保护的。可以这样做:进中断时先读到一个临时变量中,出中断时那就要先解锁TA然后再把临时变量值赋值给SFRS。但是N76E003的宏定义在操作page1的寄存器是这样的:关闭全局中断然后切换到page1,操作做完后在切换到page0,再打开全局中断。这么一来在中断里就不需要对SFRS保护的,只要保证中断里操作SFRS后恢复到page0状态就行了。这么做主要是N76E003在page1的寄存器数目并不多,大多数是在page0的。

如果大家还遇到关于page问题,请跟帖分享,谢谢!!!








作者: 匿名    时间: 2019-12-13 21:55
太好了。。。。。。。。。。。。。。。。。。。。。
作者: 匿名    时间: 2019-12-13 21:56
楼主的这个方法真棒。给力,终于找到卡死原因了。
作者: 匿名    时间: 2021-1-3 09:04
                 P15=~P15;         set_SFRPAGE;         Pwmtemp = 12*RcvData[4];         tempH = Pwmtemp>>8;         tempL = Pwmtemp&0x00FF;         PWM4H = tempH;         PWM4L = tempL;//高电平少         set_LOAD;         clr_SFRPAGE;         P15=~P15;偶尔出现死机了 跳不出来 这个该怎么解决。、




欢迎光临 牛卧堂MCU技术交流 (http://nuvoton-mcu.com/) Powered by Discuz! X3.2