【问题标题】:Memory mapped point to pointer?内存映射指向指针?
【发布时间】:2014-06-28 19:22:35
【问题描述】:

我的 C 很生锈,但我想知道我是否在正确的轨道上理解以下语法。(这是在 io 头文件中)

#define TCC0 (*(TC0_t*) 0x8000)

TCC0      TC0_t
[ • ] --→ [ • ] --→ [xxxx xxx] 0x8000
  • [ • ] = 指针
  • TC0_t 是一个结构体,这里基本上是结构体定义的样子。

    typedef struct TC0_struct
    {
        ...
    }TC0_t;
    

所以我的假设是 TCC0 指向一个结构指针,该指针指向与我的微控制器上的定时器寄存器相对应的内存地址。

如果这是真的,如果我想为多个计时器创建自己的结构,myTimer 结构看起来像

typedef struct myTimer
{
    TC0_t    *timer;
    //other useful stuff
 }myTimer;

myTimer Xtimer;
xtimer.timer = TCD0;

谢谢。

编辑:

所以 holt 建议在 myTimer 中添加更多内容。本质上,我会有不同的计时器对应于不同的端口,这将在 io 头文件中

#define TCC0 (*(TC0_t*) 0x8000)
#define TCD0 (*(TC0_t*) 0x9000)

我想创建一个结构,让我可以轻松地循环通过计时器,类似于循环通过任务列表中的任务。我可能想多了。

【问题讨论】:

  • 我使用的是 Xmega32C4,你说得对,我少了一个括号。
  • 我不确定你是否已经检查过这个,或者它是否有帮助,但这里是atmel application note on using xmega timer/counters。你用定时器做什么?定期执行代码?看起来单个计时器(硬件,例如 TCx0)可以有多个“通道”用于相关功能。
  • .... 还是硬件的外部信号?进一步阅读......看起来有2个定时器Timer0和Timer1可以映射到4个端口[D-F]。 TCC0 对应于端口 C 上的 Timer0。试图围绕您要实现的目标展开我的头脑。
  • 我正在尝试循环使用定时器,以获得电容式传感器滑块开关。我知道那里有图书馆,但我很固执。无论如何,我希望能够循环通过计时器,一次打开一个。每个定时器都将连接到一个 ISR,该 ISR 将切换一个引脚。
  • xmega d4 datasheet(第 54 页)的一个注释看起来应该分别是 TCC0 和 TCD0 的 0x0800 和 0x0900。此外,第 51 页上有一个有趣的注释(端口 C 备用功能)——看起来将 TC0 配置为 TC2 可以允许端口 C 的所有 8 个引脚用作 PWM 输出。不一定对循环有用,但在那个页面上看起来单个计时器可以控制 4 个引脚(可能不是异步的)。

标签: c pointers syntax microcontroller


【解决方案1】:

这里只有一个指针。第一个 * 是指针解引用。

当这样定义时:

#define TCC0 (*(TC0_t*) 0x8000)

TCC0 表示:

  • 取整数0x8000
  • 将其转换为指向TC0_t 的指针。
  • 访问该指针下的值。

TCC0 的行为有点像TC0_t 类型的常规变量。如果你想在某处传递它,你有三个选择:

TC0_t timer = TCC0;
TC0_t *timer = &TCC0;
TC0_t *timer = (TC0_t*) 0x8000;

请记住,第一个只会复制当前值。其他两个应该完全相同。

【讨论】:

    【解决方案2】:

    我觉得你错了,只有一个指针,一个解引用操作符,第一个是强制转换操作符。代码可以这样看:

    TC0_t *ptc0 = 0x8000 ; // Pointer pointing to the '0x8000 address'
    TC0_t TCC0 = *ptc0 ; // Value at the '0x8000 address'
    

    如果是你所理解的,那么你的问题不是很清楚......

    在您的示例中,如果TCD0TCC0 相同,那么您的代码是错误的,因为TCC0TC0_t 的实例而不是TC0_t*。如果TCD0 不是TCC0,那么也许可以解释一下它是什么。

    顺便说一下,要注意命名约定:如果你不想对结构使用以大写开头的 caml 大小写,至少不要以大写字母开头你的变量,这对于任何想要理解你的代码。

    【讨论】:

    • hmm,因此 TCD0 和 TCC0 将位于不同的端口,因此每个 #define TCD0 ((TC0_t) 0x9000) #define TCC0 ( (TC0_t) 0x8000) 剂量使其或多或少清晰?
    • @Lpaulson 也许您应该在答案中添加信息,您目前是否有不同的计时器 TCC0 和 TCD0?你想创建一个可以存储任何计时器的结构吗?所有计时器?
    【解决方案3】:
    #define TCC0 (*(TC0_t*) 0x8000);
    

    这是一个宏定义。当您在程序中使用它时,文本 TCC0 将被替换为 (*(TC0_t*) 0x8000);。例如:

    xtimer.timer = TCC0;
    

    变成:

    xtimer.timer = (*(TC0_t*) 0x8000);;
    

    (注意双分号。您应该(可能)永远不要在宏定义中添加尾随分号。)

    常量0x8000 被转换为TC0_t * 类型的指针,产生实现定义的结果。然后取消引用该指针,从而产生一个类型为 TC0_t 的值(从地址 0x8000 检索)。

    在您的代码中,xtimer.timer 的类型为 TC0_t *,因此这显然是一个错误(假设 TCD0TCC0 的拼写错误)。

    在我看来,你要么想要:

    xtimer.timer = &TCC0;
    

    或:

    #define TCC0 ((TC0_t*) 0x8000)
    

    在您的代码中没有指向指针的指针。

    【讨论】:

    • 不,TCC0和TCD0是不同地址的两个不同的宏定义。它们代表微控制器的 PORTC 和 PORTD 的定时器。
    • @Lpaulson:对。但它并没有改变代码的本质。
    猜你喜欢
    • 1970-01-01
    • 2022-10-01
    • 2018-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多