ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

K210开发板学习笔记-点亮LED灯

2022-07-25 03:31:06  阅读:170  来源: 互联网

标签:function LED0 LED K210 开发板 GPIONUM FUNC gpio GPIO


1. 介绍

和 51 单片机非常像,实验的2个LED灯都是一头接了 +3.3v 电源,控制 LED灯亮的话需要 K210芯片 对应的管脚提供一个低电平。

管脚:

  • 低电平-LED亮
  • 高电平-LED灭

GPIO 连接为:

  • K210-io0  -> LED0 ->+3.3v
  • K210-io17 -> LED1 ->+3.3v

2. 代码

  • pin_config.h
/**
* @par  Copyright (C): 2016-2022, Shenzhen Yahboom Tech
* @file         pin_config.c
* @author       Gengyue
* @version      V1.0
* @date         2020.05.27
* @brief        硬件引脚与软件GPIO的宏定义
* @details      
* @par History  见如下说明
*                 
* version:	由于K210使用fpioa现场可编程IO阵列,允许用户将255个内部功能映射到芯片外围的48个自由IO上
*           所以把硬件IO和软件GPIO功能抽出来单独设置,这样更容易理解。
*/
#ifndef _PIN_CONFIG_H_
#define _PIN_CONFIG_H_
/*****************************HEAR-FILE************************************/
#include "fpioa.h"

/*****************************HARDWARE-PIN*********************************/
// 硬件IO口,与原理图对应
#define PIN_LED_0             (0)
#define PIN_LED_1             (17)

/*****************************SOFTWARE-GPIO********************************/
// 软件GPIO口,与程序对应
#define LED0_GPIONUM          (0)
#define LED1_GPIONUM          (1)

/*****************************FUNC-GPIO************************************/
// GPIO口的功能,绑定到硬件IO口
//通用gpio共8个,使用同一个中断源,可配置输入输出信号,可配置触发IO口总中断,边沿触发和电平触发。每隔IO可以分配到FPIOA上48个管脚之一
//也就是说,可用的通用 gpio 一共有 8 个, 从 FUNC_GPIO0 可知, 对应功能编号为 FUNC_GPIO0(56) ~ FUNC_GPIO7(63)
//在此处采用了 在 基准 FUNC_GPIO0 基础上 +0、+1 来确定对应的 通用 gpio 编号
#define FUNC_LED0             (FUNC_GPIO0 + LED0_GPIONUM)
#define FUNC_LED1             (FUNC_GPIO0 + LED1_GPIONUM)

#endif /* _PIN_CONFIG_H_ */

  • main.c
/**
* @par  Copyright (C): 2016-2022, Shenzhen Yahboom Tech
* @file         main.c
* @author       Gengyue
* @version      V1.0
* @date         2020.05.27
* @brief        FPIOA映射和GPIO驱动LED灯
* @details      
* @par History  见如下说明
*                 
* version:	V1.0: LED0与LED1交替点亮,时间间隔为1秒。
*/
#include <stdio.h>
#include <unistd.h>
#include "gpio.h"
#include "pin_config.h"

/**
* Function       hardware_init
* @author        Gengyue
* @date          2020.05.27
* @brief         硬件初始化,绑定GPIO口
* @param[in]     void
* @param[out]    void
* @retval        void
* @par History   无
*/
void hardware_init(void)
{
    //绑定 K210芯片实际管脚与其对应的fpioa函数编号
    fpioa_set_function(PIN_LED_0, FUNC_LED0);
    fpioa_set_function(PIN_LED_1, FUNC_LED1);
}

/**
* Function       main
* @author        Gengyue
* @date          2020.05.27
* @brief         主函数,程序的入口
* @param[in]     void
* @param[out]    void
* @retval        0
* @par History   无
*/
int main(void)
{
    hardware_init();// 硬件引脚初始化

    gpio_init();    // 使能GPIO的时钟
    
    // 设置LED0和LED1的GPIO模式为输出
    gpio_set_drive_mode(LED0_GPIONUM, GPIO_DM_OUTPUT);
    gpio_set_drive_mode(LED1_GPIONUM, GPIO_DM_OUTPUT);
    
    // 先关闭LED0和LED1
    gpio_pin_value_t value = GPIO_PV_HIGH;
    gpio_set_pin(LED0_GPIONUM, value);
    gpio_set_pin(LED1_GPIONUM, value);

    while (1)
    {
        sleep(1);
        gpio_set_pin(LED0_GPIONUM, value);
        gpio_set_pin(LED1_GPIONUM, value = !value);
    }
    return 0;
}

通过 main.c 可以看到,总共有如下步骤:

  1. 硬件引脚初始化;
  2. 使能 GPIO 时钟;
  3. 设置LED0和LED1的GPIO模式为输出
  4. 循环控制 LED0 和 LED1 亮灭交替
1. 硬件引脚初始化
void hardware_init(void)
{
    //绑定 K210芯片实际管脚与其对应的fpioa函数编号
    fpioa_set_function(PIN_LED_0, FUNC_LED0);
    fpioa_set_function(PIN_LED_1, FUNC_LED1);
}

PIN_LED_0 是 K210 实际引脚编号,FUNC_LED0 (FUNC_GPIO0 + LED0_GPIONUM)是映射的 fpioa 函数编号
在fpioa_set_function(int number, fpioa_function_t function)中

int fpioa_set_function(int number, fpioa_function_t function)
{
    uint8_t index = 0;
    /* Check parameters */
    // 检查参数
    //1. 0<引脚编号number<FPIOA_NUM_IO(48)
    //2. 0<函数编号<FUNC_MAX(256)
    if(number < 0 || number >= FPIOA_NUM_IO || function < 0 || function >= FUNC_MAX)
        return -1;
    //如果引脚绑定的函数为 保留功能FUNC_RESV0(120),直接设置并返回
    if(function == FUNC_RESV0)
    {
        fpioa_set_function_raw(number, FUNC_RESV0);
        return 0;
    }
    /* Compare all IO */
    //在48个IO FPIOA_NUM_IO 查询
    //如果待绑定的函数 function 已被其他 管脚io占用,设置占用的管脚io绑定保留功能
    for(index = 0; index < FPIOA_NUM_IO; index++)
    {
        if((fpioa->io[index].ch_sel == function) && (index != number))
            fpioa_set_function_raw(index, FUNC_RESV0);
    }
    //绑定 K210 实际管脚 number 与 内置函数编号 function
    //注意,在点亮LED例程,传入的 function:
    // (FUNC_GPIO0 + LED0_GPIONUM) 和 (FUNC_GPIO0 + LED0_GPIONUM) (56+0, 56+1)
    fpioa_set_function_raw(number, function);
    return 0;
}
2. 设置LED0和LED1的GPIO模式为输出

使能 GPIO 时钟 就是字面意思,不再加以分析

    // 设置LED0和LED1的GPIO模式为输出
    // 传参分别为:
    // LED0_GPIONUM(0), GPIO_DM_OUTPUT(3)
    // LED1_GPIONUM(1), GPIO_DM_OUTPUT(3)
    gpio_set_drive_mode(LED0_GPIONUM, GPIO_DM_OUTPUT);
    gpio_set_drive_mode(LED1_GPIONUM, GPIO_DM_OUTPUT);
void gpio_set_drive_mode(uint8_t pin, gpio_drive_mode_t mode)
{
    // 确保 GPIO pin <  GPIO_MAX_PINNO(8,最大通用gpio)
    configASSERT(pin < GPIO_MAX_PINNO);
    //根据功能号获取 IO 管脚号
    //大于等于 0 IO 管脚号
    //小于 0 失败
    int io_number = fpioa_get_io_by_function(FUNC_GPIO0 + pin);
    //确保获取通用管脚号成功
    configASSERT(io_number >= 0);

    fpioa_pull_t pull;
    uint32_t dir;

    switch(mode)
    {
        case GPIO_DM_INPUT:
            pull = FPIOA_PULL_NONE;
            dir = 0;
            break;
        case GPIO_DM_INPUT_PULL_DOWN:
            pull = FPIOA_PULL_DOWN;
            dir = 0;
            break;
        case GPIO_DM_INPUT_PULL_UP:
            pull = FPIOA_PULL_UP;
            dir = 0;
            break;
        case GPIO_DM_OUTPUT:
            pull = FPIOA_PULL_DOWN;
            dir = 1;
            break;
        default:
            configASSERT(!"GPIO drive mode is not supported.") break;
    }
    //设置 IO 的上拉下拉
    fpioa_set_io_pull(io_number, pull);
    set_gpio_bit(gpio->direction.u32, pin, dir);
}

在这个函数中,就可以看出之前明明绑定 k210实际管脚时用的是:

//FUNC_LED0 (FUNC_GPIO0 + LED0_GPIONUM)
fpioa_set_function(PIN_LED_0, FUNC_LED0);

但是设置 GPIO模式为输出 时用的是:

gpio_set_drive_mode(LED0_GPIONUM, GPIO_DM_OUTPUT);

原理就在于 在传入到 gpio_set_drive_mode 函数后,找 函数对应的管脚号用的是:

int io_number = fpioa_get_io_by_function(FUNC_GPIO0 + pin);

其中 pin=LED0_GPIONUM
可能考虑到函数的简洁,函数fpioa_get_io_by_function(uint8_t pin, gpio_drive_mode_t mode)软件GPIO口 LED0_GPIONUMGPIO口的功能 FUNC_LED0的对应关系封装起来了;
结果就导致虽然在 pin_config.h 中定义了

/*****************************SOFTWARE-GPIO********************************/
// 软件GPIO口,与程序对应
#define LED0_GPIONUM          (0)
#define LED1_GPIONUM          (1)

/*****************************FUNC-GPIO************************************/
// GPIO口的功能,绑定到硬件IO口
//通用gpio共8个,使用同一个中断源,可配置输入输出信号,可配置触发IO口总中断,边沿触发和电平触发。每隔IO可以分配到FPIOA上48个管脚之一
//也就是说,可用的通用 gpio 一共有 8 个, 从 FUNC_GPIO0 可知, 对应功能编号为 FUNC_GPIO0(56) ~ FUNC_GPIO7(63)
//在此处采用了 在 基准 FUNC_GPIO0 基础上 +0、+1 来确定对应的 通用 gpio 编号
#define FUNC_LED0             (FUNC_GPIO0 + LED0_GPIONUM)
#define FUNC_LED1             (FUNC_GPIO0 + LED1_GPIONUM)

但在 main.c 中不知道为什么可以通过 LED0_GPIONUM 设置 FUNC_LED0 绑定的 K210 实际管脚的工作方式

标签:function,LED0,LED,K210,开发板,GPIONUM,FUNC,gpio,GPIO
来源: https://www.cnblogs.com/brian-sun/p/16516086.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有