我正在学习嵌入式系统。在TM4C123上LED闪烁的附加代码中,他们创建了变量ulLoop
,这让我感到困惑,因为他们只是将点击启用字节分配给ulLoop
,但之后从未使用过它。然而,我试着删除写ulLoop = SYSCTL_RCGCGPIO_R;
和LED停止闪烁的行,正如他们在教程中所说的那样;uloop变量和包含uloop的语句在移动到外围设备之前只存在3个时钟周期,这是使用TIVA时必须的。
我不明白他们所说的"半三个时钟周期"是什么意思。以及"转向外围设备",以及为什么它需要停止3个时钟周期,而不是4个或5个周期,或者根本不需要。此外,如果我对教程中提到的关于魔术变量的内容一无所知,只是发现程序不工作,那么在没有进一步信息的情况下,我怎么知道问题出在哪里,因为在构建过程中没有错误和警告。如果问题问得不对或听起来很傻,请原谅我。
#define SYSCTL_RCGCGPIO_R (*(( volatile unsigned long *)0x400FE608 ) )
#define GPIO_PORTF_DATA_R (*(( volatile unsigned long *)0x40025038 ) )
#define GPIO_PORTF_DIR_R (*(( volatile unsigned long *)0x40025400 ) )
#define GPIO_PORTF_DEN_R (*(( volatile unsigned long *)0x4002551C ) )
#define GPIO_PORTF_CLK_EN 0x20
#define GPIO_PORTF_PIN1_EN 0x02
#define LED_ON1 0x02
#define GPIO_PORTF_PIN2_EN 0x04
#define LED_ON2 0x04
#define GPIO_PORTF_PIN3_EN 0x08
#define LED_ON3 0x08
#define DELAY_VALUE 1000000
volatile unsigned long j=0;
static void Delay(void){
for (j=0; j<DELAY_VALUE ; j++);
}
int main ( void )
{
volatile unsigned long ulLoop ; // I don't understand why creating this variable
SYSCTL_RCGCGPIO_R |= GPIO_PORTF_CLK_EN ;
ulLoop = SYSCTL_RCGCGPIO_R; // But if not adding this line the LED won't blink
GPIO_PORTF_DIR_R |= GPIO_PORTF_PIN1_EN ;
GPIO_PORTF_DEN_R |= GPIO_PORTF_PIN1_EN ;
GPIO_PORTF_DIR_R |= GPIO_PORTF_PIN2_EN ;
GPIO_PORTF_DEN_R |= GPIO_PORTF_PIN2_EN ;
GPIO_PORTF_DIR_R |= GPIO_PORTF_PIN3_EN ;
GPIO_PORTF_DEN_R |= GPIO_PORTF_PIN3_EN ;
// Loop forever .
while (1)
{
GPIO_PORTF_DATA_R &= LED_ON3;
GPIO_PORTF_DATA_R &= LED_ON2;
GPIO_PORTF_DATA_R |= LED_ON1;
Delay();
GPIO_PORTF_DATA_R &= LED_ON1;
GPIO_PORTF_DATA_R &= LED_ON2;
GPIO_PORTF_DATA_R |= LED_ON3;
Delay();
GPIO_PORTF_DATA_R &= LED_ON3;
GPIO_PORTF_DATA_R &= LED_ON1;
GPIO_PORTF_DATA_R |= LED_ON2;
Delay();
}
}
因为在这一行
SYSCTL_RCGCGPIO_R |= GPIO_PORTF_CLK_EN ;
程序正在启用时钟,这一行
ulLoop = SYSCTL_RCGCGPIO_R;
只是一个虚拟代码,它给微控制器时钟一点时间来稳定。
你会发现这对于你将要使用的任何微控制器都是有效的,在时钟设置之后,你必须允许一些时间让时钟稳定。
现在,为什么是3个时钟周期?在读取微控制器数据表时,您应该找到该信息,其中应指定需要多少时钟周期来稳定时钟?
为什么不是5个或更多?当然,您不希望在此操作中浪费这么多时钟周期,因此程序的其余部分可以尽快执行。
这条虚拟线如何对应3个时钟周期?
ulLoop = SYSCTL_RCGCGPIO_R;
这确实是不同于控制器的,或者更具体地说,不同于编译器的。编译器会将这行c代码转换成汇编代码。每条装配线需要一个时钟周期来执行。因此,无论写这段代码的人是谁,只要看看编译器生成的汇编代码,就会发现这行代码被翻译成3条汇编指令。
如果没有进一步的信息,我怎么知道问题在哪里
在嵌入式系统世界中,这可以通过调试来实现。有些问题真的很难调试,特别是当它是在控制器初始化序列。在初始化控制器(时钟、外设)时,请按照数据表说明/建议进行初始化。