如果不是 "halting clock cycles",则 TM4C123 上的 LED 闪烁失败
LED blinking on TM4C123 fails if not "halting clock cycles"
我正在按照 this tutorial 学习嵌入式系统。在他们附加的用于 TM4C123 上 LED 闪烁的代码中,他们创建了变量 ulLoop
这让我感到困惑,因为他们只是将点击启用字节分配给 ulLoop
但之后从未使用过它。但是,我尝试删除写 ulLoop = SYSCTL_RCGCGPIO_R;
的行并且 LED 停止闪烁,正如他们在教程中所说的那样“uloop 变量和包含 uloop 的语句存在于那里,只是为了在移动到外围设备之前停止 3 个时钟周期,这是使用 TIVA 时必须的。"
我不明白他们所说的“停止 3 个时钟周期”和“移动到外围设备”是什么意思,以及为什么它需要停止 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 条汇编指令。
how am I supposed to know where the problem is without further information
在嵌入式系统世界中,这可以通过调试来实现。有些问题真的很难调试,尤其是当它出现在控制器初始化序列中时。
按照数据表 instructions/recommendations.
初始化控制器(时钟、外围设备)时,您应该非常小心
我正在按照 this tutorial 学习嵌入式系统。在他们附加的用于 TM4C123 上 LED 闪烁的代码中,他们创建了变量 ulLoop
这让我感到困惑,因为他们只是将点击启用字节分配给 ulLoop
但之后从未使用过它。但是,我尝试删除写 ulLoop = SYSCTL_RCGCGPIO_R;
的行并且 LED 停止闪烁,正如他们在教程中所说的那样“uloop 变量和包含 uloop 的语句存在于那里,只是为了在移动到外围设备之前停止 3 个时钟周期,这是使用 TIVA 时必须的。"
我不明白他们所说的“停止 3 个时钟周期”和“移动到外围设备”是什么意思,以及为什么它需要停止 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 条汇编指令。
how am I supposed to know where the problem is without further information
在嵌入式系统世界中,这可以通过调试来实现。有些问题真的很难调试,尤其是当它出现在控制器初始化序列中时。 按照数据表 instructions/recommendations.
初始化控制器(时钟、外围设备)时,您应该非常小心