打印
[PIC®/AVR®/dsPIC®产品]

研究AVR和PIC IO口定义的风格 -- 发现两个有趣的地方

[复制链接]
1331|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
奔波儿熊|  楼主 | 2019-4-26 17:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
AVR, pic, IO, TE
本帖最后由 奔波儿熊 于 2019-4-26 17:12 编辑

首先是AVR的IO口定义, 摘自iom4808.h:

typedef volatile uint8_t register8_t;

/* Virtual Ports */
typedef struct VPORT_struct
{
    register8_t DIR;  /* Data Direction */
    register8_t OUT;  /* Output Value */
    register8_t IN;  /* Input Value */
    register8_t INTFLAGS;  /* Interrupt Flags */
} VPORT_t;

/* I/O Ports */
typedef struct PORT_struct
{
    register8_t DIR;  /* Data Direction */
    register8_t DIRSET;  /* Data Direction Set */
    register8_t DIRCLR;  /* Data Direction Clear */
    register8_t DIRTGL;  /* Data Direction Toggle */
    register8_t OUT;  /* Output Value */
    register8_t OUTSET;  /* Output Value Set */
    register8_t OUTCLR;  /* Output Value Clear */
    register8_t OUTTGL;  /* Output Value Toggle */
    register8_t IN;  /* Input Value */
    register8_t INTFLAGS;  /* Interrupt Flags */
    register8_t PORTCTRL;  /* Port Control */
    register8_t reserved_0x0B;
    register8_t reserved_0x0C;
    register8_t reserved_0x0D;
    register8_t reserved_0x0E;
    register8_t reserved_0x0F;
    register8_t PIN0CTRL;  /* Pin 0 Control */
    register8_t PIN1CTRL;  /* Pin 1 Control */
    register8_t PIN2CTRL;  /* Pin 2 Control */
    register8_t PIN3CTRL;  /* Pin 3 Control */
    register8_t PIN4CTRL;  /* Pin 4 Control */
    register8_t PIN5CTRL;  /* Pin 5 Control */
    register8_t PIN6CTRL;  /* Pin 6 Control */
    register8_t PIN7CTRL;  /* Pin 7 Control */
    register8_t reserved_0x18;
    register8_t reserved_0x19;
    register8_t reserved_0x1A;
    register8_t reserved_0x1B;
    register8_t reserved_0x1C;
    register8_t reserved_0x1D;
    register8_t reserved_0x1E;
    register8_t reserved_0x1F;
} PORT_t;

#define VPORTA              (*(VPORT_t *) 0x0000) /* Virtual Ports */
#define PORTA                (*(PORT_t *) 0x0400) /* I/O Ports */

其次是PIC的IO口定义, 摘自pic16f18875.h:
// Register: PORTA
#define PORTA PORTA
extern volatile unsigned char           PORTA               @ 0x00C;
#ifndef _LIB_BUILD
asm("PORTA equ 0Ch");
#endif
// bitfield definitions
typedef union {
       struct {
              unsigned RA0                    :1;
              unsigned RA1                    :1;
              unsigned RA2                    :1;
              unsigned RA3                    :1;
              unsigned RA4                    :1;
              unsigned RA5                    :1;
              unsigned RA6                    :1;
              unsigned RA7                    :1;
       };
} PORTAbits_t;
extern volatile PORTAbits_t PORTAbits @ 0x00C;

两个有趣的地方已经标红了.
问题1:
#define PORTA PORTA 有什么用?
问题2:
extern volatile unsigned char           PORTA               @ 0x00C;
看到这行我的第一反应是有extern, 这应该是PORTA的声明, 那应该有个地方定义了PORTA, 但是我并没有找到. 那怎么理解呢?

关于这两个问题,我心里已经有了自己的答案, 先不献丑了,先看看强大的水友们有何见解.

使用特权

评论回复
沙发
奔波儿熊|  楼主 | 2019-4-26 17:26 | 只看该作者
如果有兴趣的不管知不知道答案,可以留个言,要不然帖子沉底了,我就忘记这回事了.

使用特权

评论回复
板凳
Cjy_JDxy| | 2019-4-27 13:33 | 只看该作者
先说说你的答案呗

使用特权

评论回复
地板
CoolSilicon| | 2019-4-28 09:07 | 只看该作者
重点应该是在你标注红色的代码下面那一句:

#ifndef _LIB_BUILD
asm("PORTA equ 0Ch");
#endif

这个是汇编定义PORTA所在的物理地址, 红色的是C代码..
所以......
算是回答了你的问题吧?

使用特权

评论回复
5
ayb_ice| | 2019-4-28 14:52 | 只看该作者
已经定义在芯片内了,所以要外部声明才能用

使用特权

评论回复
6
waveforms| | 2019-4-28 15:48 | 只看该作者
第二个应该是将PORTA定义到特定地址上

使用特权

评论回复
7
奔波儿熊|  楼主 | 2019-4-28 17:08 | 只看该作者
CoolSilicon 发表于 2019-4-28 09:07
重点应该是在你标注红色的代码下面那一句:

#ifndef _LIB_BUILD

汇编去掉,代码一样正常的.

使用特权

评论回复
8
598330983| | 2019-4-28 17:39 | 只看该作者
其实我偏爱AVR

使用特权

评论回复
9
流浪地球多少年| | 2019-4-28 17:43 | 只看该作者
是要解释两句红色代码的作用吧?

extern volatile unsigned char           PORTA               @ 0x00C;
这句声明了一个全局变量PORTA,并且制定了地址。

#define PORTA PORTA
看似一条无用的代码,-----实际上功能上确实没有用。
至于为什么加这条宏定义,个人的理解是,方便用户对芯片的资源配置进行判断。

#ifdef PORTA
如果有A口,就执行某些代码。


使用特权

评论回复
10
奔波儿熊|  楼主 | 2019-5-6 11:00 | 只看该作者
过完五一了,公布我心中的的答案(楼上的兄弟和我想法一样):
1.extern volatile unsigned char           PORTA               @ 0x00C;
这句并不是标准的C语言, 是PIC的编译器支持@地址这种写法,有了地址就表明变量有了定义.
2.#define PORTA PORTA
Linux kernal 里有很多地方有这种宏, 用处就是用来判断某个宏是否存在,详见https://gcc.gnu.org/onlinedocs/gcc-4.6.2/cpp/Self_002dReferential-Macros.html#Self_002dReferential-Macros

使用特权

评论回复
11
猴三棒| | 2019-5-7 13:57 | 只看该作者
学习了

使用特权

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

本版积分规则

22

主题

503

帖子

2

粉丝