出处:https://www.sekorm.com/news/25653139.html
瑞萨科技是世界十大半导体芯片供应商之一,在汽车领域的MCU市场份额更是排在最前列。近日笔者碰到刚接手瑞萨MCU的开发人员,提出一个比较有意思的问题,分享出来以帮助大家更快上手。
我们使用的是瑞萨R5F109GE的开发板,通过开发板来熟悉瑞萨的MCU资源是比较好的办法。这位朋友提出的问题是:R5F109GE使用瑞萨自有的CS+的编译器,但在编程中,无法对单片机IO口进行位操作。比如说做跑马灯实验,需要不断的改变某个IO口的输出信号,而编译器只识别整个IO口寄存器,而无法识别对其中的位操作,这样不利于编程开发。
以其中的IO口P51为例,正常我们希望的是编译器可以识别以下代码,方便理解:
P5.1=1;//P51口输出高电平
//或P51=1;//P51口输出高电平
不过实际上,编译器是无法识别P5.1和P51。我们以前碰到这样的情况,可能需要自己来做下数据处理如下所示:
P5= P5|(1<<1);// P51口输出高电平
这样才能达到我们所要的P51口输出高电平效果。但是,这么长的赋值语句,如果在一个本身就比较长的代码中,很容易引起操作失误。
笔者仔细研究了下瑞萨的CS+ 的编译器,在编译器创建工程默认后的iodefine.h文件中,找到了瑞萨为我们提供的一个更好的解决办法。
如下代码所示:
typedef struct
{
unsigned char no0:1;
unsigned char no1:1;
unsigned char no2:1;
unsigned char no3:1;
unsigned char no4:1;
unsigned char no5:1;
unsigned char no6:1;
unsigned char no7:1;
} __bitf_T;
#define P5 (*(volatile __near unsigned char *)0xFF05)
#define P5_bit (*(volatile __near __bitf_T *)0xFF05)
在上面的代码中,CS+编译器的iodefine.h文件中定义了一个8bit的结构体__bitf_T(如果是16位,或者32位只需要往上叠加no个数即可),并定义了P5整个寄存器的地址,以及P5_bit这个__bitf_T型的结构体的地址,都指向PORT5的寄存器地址。此时,我们可以通过以下的简单操作即可实现PORT口的位操作。
P5_bit.no1=1;
编译器会创建P5_bit这个__bitf_T型的结构体,以方便我们调用。如果P51使用的比较频繁,觉得代码还比较长,我们可以在宏定义中添加:
#define P51 P5_bit.no1
这样就可以实现我们一开始所需求的代码:
P51=1; / P51口输出高电平
最后给大家整理下,据说高级工程师都会选择以下的写法:
#define P51 (((volatile __near __bitf_T *)0xFF05)->no1)
P51=1; / P51口输出高电平