假设我们想在地址 say 处写入0xc000,我们可以在 C 中定义一个宏:
#define LCDCW1_ADDR       0xc000
#define READ_LCDCW1()     (*(volatile uint32_t *)LCDCW1_ADDR)
#define WRITE_LCDCW1(val) ((*(volatile uint32_t *)LCDCW1_ADDR) = (val))
我的问题是,当使用任何微控制器时,考虑一个例子MSP430,P1OUT寄存器地址是0x0021。
但是当我们使用P1OUT=0xFFFF时;// 它为 P1OUT 分配一个值 0xFFFF。
我的问题是它如何写入该地址,例如在本例中为 0x0021。IDE是IAR。我在头文件 msp430g2553.h 中找到了以下定义:
#define P1OUT_              (0x0021u)  /* Port 1 Output */
DEFC(   P1OUT             , P1OUT_)
我想它正在定义地址,但是其他要写入或读取的宏在哪里。
谁能解释一下 P1OUT 如何在该特定地址位置写入的流程?另外请告诉我 0x0021u 中的 u 是什么意思?
谢谢
到目前为止我发现的细节是:
在 msp430g2553.h 中
#ifdef __IAR_SYSTEMS_ICC__
#include "in430.h"
#pragma language=extended
#define DEFC(name, address) __no_init volatile unsigned char name @ address;
#define DEFW(name, address) __no_init volatile unsigned short …我知道,与MSP430F2619与TI的CCSv4工作时,我可以得到一个以上的中断使用相同的中断处理程序的代码看起来是这样的:
#pragma vector=TIMERA1_VECTOR
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void){
ServiceWatchdogTimer();
}
我的问题是,当我发现自己处于那个中断时,有没有办法弄清楚这些中断中的哪一个让我在这里?
我对程序计数器(R0)和堆栈指针(R1)在内存映射中的位置感到困惑.我认为它们位于CPU内部,因此内存映射中没有任何位置显示这些寄存器.但我的朋友坚持认为它们位于特殊功能寄存器(SFR)中,它们位于存储器映射的底部.哪一个是正确的答案?
我将MSP430F2013处理器用于没有UART的应用程序.我需要一个UART,因此我使用TI的示例代码"msp430x20x3_ta_uart2400.c"来模拟使用定时器模块.这一切都运行良好(使用IAR Embedded Workbench编译),使用PuTTY测试它以将字符传输到开发板,并使用环回将它们回显到终端.
这是一个降低风险的练习,现在我已将该代码移植到我的应用程序的状态机中.完成此操作后,我遇到了有关定时器中断和低功耗睡眠模式的问题.这是我进入低功耗(睡眠)模式的代码片段:
// Prepare the UART to receive one byte.
prepare_receiver();
// Enter low power mode 1.
__bis_SR_register(LPM1_bits + GIE);
// Check whether the full message has been received.
if(true == get_message_complete())
{
    process_event(e_euart_message_received, NULL);
}
我在调试器(C-Spy)上看到的是,有时它会bis_SR_register()在第一个条目上执行该行,然后转到if语句,即忽略我要求它进入睡眠状态的事实.在其他情况下,当它确实进入睡眠状态时,ISR会正确触发并最终将我带回if语句以继续执行程序(正如我所料).但是,如果我尝试跳到下一个语句,应用程序会冻结第一行,即我无法前进.
我想不出任何功能上与我正在做的TI示例有什么不同,所以我认为我的问题必须与我如何移植它有关.例如,我的Timer ISR和我在这里发布的代码是在不同的编译单元 - 这种决定会对事情有什么影响吗?我知道我的问题可能有点模糊,但不幸的是我无法发布我的所有代码,所以相反,我正在寻找有MSP经验的人,他可能会提出一些建议,或者一些潜在的陷阱,我可能已陷入其中.
我有通过中断读取USCI(UART)的"正常"代码,但TI SimpliciTI堆栈是CPU占用的,并且在维护无线电时它会丢弃UART字节.
我假设DMA是可行的方法,但我找不到使用USCI作为输入的DMA的完整示例.
我正在编写一个简单的游戏并尝试在MSP430F5529微控制器上进行测试.我遇到的问题与看门狗定时器有关.
我写的代码会导致器件复位,这表示看门狗定时器问题.我假设我需要在我的主代码的第一行,某种预初始化代码之前停止它.我是否在正确的轨道上说,或者问题可能还在代码的其他部分?
为了更清楚,我的主要代码如下(简单形式):
就我而言,这段代码应该是正确的.
我正在使用 GDB 调试我的 msp430。我连接目标,然后加载程序的二进制文件,然后“继续”。
我的程序运行良好,但我想实时查看变量的某些值。实际上我想检查我的代码开始和代码结束的时间戳,这会给我总持续时间。
由于我对 GDB 完全陌生,因此目前我已将此行放在我的代码中
printf("Hello World\n");
然而,没有打印任何内容,但我的代码工作正常,实际上是 LED 闪烁。
请指导我如何在调试模式下查看 GDB 中的变量值。
谢谢
致力于应对微观腐败挑战。从对 MIPS 的一点经验来看,我仍在弄清楚一些 msp430 的事情。
指令集摘要中没有特别描述 cmp.b 指令的条目,但我可以看到它在此处与 jne 指令结合使用。jne 描述:如果重置零位,则跳转到标签。
455a:  f290 8500 1024 cmp.b #0x85, &0x2410
4560:  0720           jne   #0x4570 <login+0x50>
因此,cmp.b 正在将 0x85 立即数的字节(如 .b 后缀所示)与存储在地址 0x2410 中的任何字节值进行比较,但是我只能想象这会在为 jne 保留的某些寄存器中设置一个位指令(前面提到的零位)检查以知道它是否应该执行跳转?如果是这种情况,那会是哪个寄存器?