kw38点灯大师

kw38点灯大师

KW38点灯大师

frdmkw38_gpio_led_output 工程

KW38点灯大师哈哈哈.

light

主函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
int main(void)
{
/* Define the init structure for the output LED pin*/
gpio_pin_config_t led_config = {
kGPIO_DigitalOutput,
0,
};

/* Board pin, clock, debug console init */
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();

/* Print a note to terminal. */
PRINTF("\r\n GPIO Driver example\r\n");
PRINTF("\r\n The LED is blinking.\r\n");

/* Init output LED GPIO. */
GPIO_PinInit(BOARD_LED_GPIO, BOARD_LED_GPIO_PIN, &led_config);

while (1)
{
delay();
GPIO_PortToggle(BOARD_LED_GPIO, 1u << BOARD_LED_GPIO_PIN);
}
}

这段代码是一个GPIO驱动的示例代码,它使用了MCUXpresso SDK提供的GPIO驱动库来控制开发板上的LED灯。

在这个示例中,我们使用了GPIO_PinInit()函数来初始化LED灯的GPIO引脚,然后在一个while循环中不断地切换LED灯的状态,从而实现LED灯的闪烁效果。

具体来说,我们使用了GPIO_PortToggle()函数来切换LED灯的状态,使用了delay()函数来控制LED灯的闪烁频率。

led_config 结构体

定义了一个gpio_pin_config_t类型的变量led_config,它是一个结构体类型,用于配置GPIO引脚的属性。具体来说,它包含两个成员变量,

  • 第一个成员变量是GPIO的工作模式,这里我们使用了kGPIO_DigitalOutput模式,表示这个GPIO引脚是一个数字输出引脚
  • 第二个成员变量是GPIO的初始电平,这里我们使用了0,表示初始电平为低电平

这个led_config变量会在GPIO_PinInit函数中被使用,用于初始化LED灯的GPIO引脚

GPIO_PinInit 函数

1
2
// 初始化GPIO引脚
GPIO_PinInit(BOARD_LED_GPIO, BOARD_LED_GPIO_PIN, &led_config);

三个参数:

  • BOARD_LED_GPIO : 第一个参数是GPIO的端口号
  • BOARD_LED_GPIO_PIN : 第二个参数是GPIO的引脚号
  • &led_config : 第三个参数是一个指向gpio_pin_config_t类型的指针,用于配置GPIO引脚的属性

这个函数会根据传入的参数来初始化GPIO引脚,从而使得LED灯能够正常工作。

这里根据宏定义,使用的是红灯,查找board.h可以知道:

1
2
3
4
5
6
7
8
#ifndef BOARD_LED_RED_GPIO
#define BOARD_LED_RED_GPIO GPIOC
#endif
#define BOARD_LED_RED_GPIO_PORT PORTC
#ifndef BOARD_LED_RED_GPIO_PIN
#define BOARD_LED_RED_GPIO_PIN 1U
#endif
// 红灯是GPIOC Pin1 绿灯是GPIOA Pin16 蓝灯是GPIOB Pin2

GPIO_PinInit()函数初始化了一个由板子使用的GPIO引脚。它接受参数:

  • GPIO外设基址指针(GPIOA、GPIOB、GPIOC等)、
  • GPIO端口引脚号和
  • GPIO引脚配置指针。

该函数根据配置将引脚设置为输入或输出引脚

该函数首先检查配置指针是否不为空。然后它将标志设置为1。

  • 如果引脚方向设置为数字输入,则函数在端口数据方向寄存器(PDDR)中清除引脚号处的位。(按位与上0

  • 如果引脚方向设置为数字输出,则函数使用GPIO_PinWrite()函数将输出逻辑值写入引脚,并在PDDR中设置引脚号处的位(按位或上1)。

GPIO_PinWrite()函数

关于 GPIO_PinWrite()函数:

用于设置GPIO的输出电平。函数的输入参数:包括GPIO的基地址、GPIO的引脚号以及输出电平。

函数的实现是通过设置GPIO的寄存器来实现的。

如果输出电平为0,则通过PCOR寄存器清除对应引脚的输出电平;如果输出电平为1,则通过PSOR寄存器设置对应引脚的输出电平。

GPIO_PortToggle() 函数

用来控制GPIO口输出,它的作用是将指定的GPIO口的指定引脚的电平翻转。在这个例子中,它被用来控制开发板上的LED灯的闪烁。

GPIO_PortToggle()函数的第一个参数是GPIO端口号,第二个参数是要翻转的引脚号。

在这个例子中,BOARD_LED_GPIO和BOARD_LED_GPIO_PIN分别定义了LED灯的GPIO端口号和引脚号。GPIO_PortToggle(BOARD_LED_GPIO, 1u << BOARD_LED_GPIO_PIN)的作用是将LED灯的电平翻转。

其中1u << BOARD_LED_GPIO_PIN是将1左移BOARD_LED_GPIO_PIN位,得到一个只有BOARD_LED_GPIO_PIN位为1的数,这个数表示要翻转的引脚。GPIO_PortToggle()函数会将这个数对应的引脚的电平翻转。

base->PTOR = mask;通过配置PTOR寄存器设置引脚电平翻转。

宏定义和原型函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#define BOARD_LED_GPIO BOARD_LED_RED_GPIO
#define BOARD_LED_GPIO_PIN BOARD_LED_RED_GPIO_PIN

/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief delay a while.
*/
void delay(void);

/*******************************************************************************
* Variables
******************************************************************************/

/*******************************************************************************
* Code
******************************************************************************/
void delay(void)
{
volatile uint32_t i = 0;
for (i = 0; i < 800000; ++i)
{
__asm("NOP"); /* delay */
}
}

delay函数

delay函数中的for循环执行了800000次,每次循环都执行了一个空指令__asm("NOP"),这个指令的作用是延迟一段时间。

具体来说,这个循环的执行时间取决于CPU的主频和循环次数,假设CPU主频为100MHz,那么这个循环的执行时间大约为8ms。因此,delay函数的作用是延迟一段时间,用于控制LED灯的闪烁频率。

其他

mtb.c

这个文件是MTB初始化文件。MTB是Micro Trace Buffer的缩写,是一种用于调试的技术。

MTB可以记录程序的执行过程,包括程序计数器的值、寄存器的值、函数调用和返回等信息。这个文件中的代码用于初始化MTB缓冲区

  • 如果定义了__MTB_DISABLE,则不会创建MTB缓冲区。
  • 如果没有定义__MTB_BUFFER_SIZE,则会提供一个小的默认缓冲区
  • 如果定义了__MTB_RAM_BANK,则会将MTB缓冲区放置在指定的RAM bank中
  • 如果没有定义__MTB_RAM_BANK,则会将MTB缓冲区放置在默认的RAM bank中。
  • 如果__MTB_BUFFER_SIZE大于0,则会引入cr_mtb_buffer.h头文件,并将MTB缓冲区放置在RAM bank中。

semihost_hardfault.c

这个文件是提供硬故障处理程序的,以允许半主机代码在调试器未连接时不挂起应用程序

在应用程序中包含半主机操作(例如printf调用)的应用程序的一个问题是,当调试器未连接时,代码将无法正确执行。通常,这将显示为应用程序似乎只是挂起。这可能包括从复位运行应用程序或启动板子(已经在FLASH中存在应用程序),以及在调试会话终止后应用程序无法继续执行。

总结点灯的流程

  1. BOARD_InitPins();
    1. 里面有Port的时钟使能,CLOCK_EnableClock(kCLOCK_PortA);
    2. 引脚复用 PORT_SetPinMux(BOARD_INITPINS_myGreen_PORT, BOARD_INITPINS_myGreen_PIN, kPORT_MuxAsGpio);
  2. BOARD_BootClockRUN(); 板子时钟RUN模式使能
  3. BOARD_InitDebugConsole(); 板子console debug初始化
  4. GPIO_PinInit(BOARD_LED_GPIO0, BOARD_LED_GPIO_PIN0, &led_config); GPIO引脚初始化;
  5. GPIO_PortToggle(BOARD_LED_GPIO0, 1u << BOARD_LED_GPIO_PIN0); GPIO端口高低电平切换
作者

Gavin

发布于

2023-03-24

更新于

2023-03-24

许可协议

CC BY-NC-SA 4.0

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×