注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
yuhua8688的个人空间 https://home.eeworld.com.cn/space-uid-172442.html [收藏] [复制] [分享] [RSS]
日志

《玩单片机 + 玩Python = 玩游戏》玩转单片机---1.GPIO 读写

已有 408 次阅读2022-2-10 15:34 |个人分类:Meta Coding

 

 

/*
 * Copyright (c) 2021-2022, Meta Coding
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author            Notes
 * 2022-02-10     Jone.Chen        first version
 */

#ifndef __DRV_GPIO_H__
#define __DRV_GPIO_H__


#include <board.h>
#include <rtthread.h>
#include "HAL_gpio.h"

//PORT宏定义
#define __TKM32_PORT(port)  GPIO##port##_BASE
#define PPORT(PORTx)    ( ((rt_base_t)__TKM32_PORT(PORTx) - (rt_base_t)GPIOA_BASE)/(0x0400UL) )
//__TKM32_PORT(A) ---展开宏---> GPIOA_BASE
//PPORT(A) ---展开宏---> ( ((rt_base_t)GPIOA_BASE - (rt_base_t)GPIOA_BASE)/(0x0400UL) ) ------> 0

//PIN 索引 宏定义
#define GET_PIN(PORTx,PIN)  (PPORT(PORTx)<3?(16*PPORT(PORTx)+PIN):PPORT(PORTx)==3?40+PIN:55+PIN)
//GET_PIN(A,0) ---展开宏---> (0<3?(16*0+0):0==3?40+0:55+0)  ------> 0
//因TKM32 gpio不是每个都是16个IO,不能全用(16*PPORT(PORTx)+PIN)方式获取索引



//pins[]数组索引的宏定义
#define __TKM32_PIN(index, gpio, gpio_index)                                \
    {                                                                       \
        index, GPIO##gpio, GPIO_Pin_##gpio_index                            \
    }
//__TKM32_PIN(0 ,  A, 0 ) ---展开宏---> 0,GPIOA,GPIO_Pin_0


/* TKM32 GPIO driver */
//pins[] 结构体
struct pin_index
{
    int index;
    GPIO_TypeDef *gpio;
    uint32_t pin;
};


int rt_hw_pin_init(void);

#endif /* __DRV_GPIO_H__ */




/*
 * Copyright (c) 2021-2022, Meta Coding
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author            Notes
 * 2022-02-10     Jone.Chen        first version
 */

#include <board.h>
#include "drv_gpio.h"
#include <drivers/pin.h>
#include <rthw.h>

#ifdef RT_USING_PIN
//存储所有Pin的数组
static const struct pin_index pins[] = 
{
#if defined(GPIOA)
    __TKM32_PIN(0 ,  A, 0 ),  //PA0 索引0
    __TKM32_PIN(1 ,  A, 1 ),  //PA1 索引1
#endif /* defined(GPIOA) */
//..............
#if defined(GPIOE)
    __TKM32_PIN(78,  E, 23), //PE23 索引78
#endif /* defined(GPIOE) */

};

//计算Pin总数
#define ITEM_NUM(items) sizeof(items) / sizeof(items[0])

//用索引值 pin 获取一个GPIO_Pin的索引结构体
static const struct pin_index *get_pin(uint8_t pin)
{
    const struct pin_index *index;

    if (pin < ITEM_NUM(pins))
    {
        index = &pins[pin];
        if (index->index == -1)
            index = RT_NULL;
    }
    else
    {
        index = RT_NULL;
    }

    return index;
};

static void tkm32_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value)
{
    const struct pin_index *index;

    index = get_pin(pin);
    if (index == RT_NULL)
    {
        return;
    }
		//控制gpio硬件动作
		GPIO_WriteBit(index->gpio, index->pin, (BitAction)value);
}

static int tkm32_pin_read(rt_device_t dev, rt_base_t pin)
{
    int value;
    const struct pin_index *index;

    value = PIN_LOW;

    index = get_pin(pin);
    if (index == RT_NULL)
    {
        return value;
    }
		//读取gpio硬件值
    value = GPIO_ReadInputDataBit(index->gpio, index->pin);
    return value;
}

static void tkm32_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
{
    const struct pin_index *index;
    GPIO_InitTypeDef GPIO_InitStruct;

    index = get_pin(pin);
    if (index == RT_NULL)
    {
        return;
    }

    /* Configure GPIO_InitStructure */
    GPIO_InitStruct.GPIO_Pin = index->pin;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

    if (mode == PIN_MODE_OUTPUT)
    {
        /* output setting */
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
    }
    else if (mode == PIN_MODE_INPUT)
    {
        /* input setting: not pull. */
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    }
    else if (mode == PIN_MODE_INPUT_PULLUP)
    {
        /* input setting: pull up. */
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
    }
    else if (mode == PIN_MODE_INPUT_PULLDOWN)
    {
        /* input setting: pull down. */
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD;//下拉输入
    }
    else if (mode == PIN_MODE_OUTPUT_OD)
    {
        /* output setting: od. */
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD;//开漏输入
    }

    GPIO_Init(index->gpio, &GPIO_InitStruct);
}

rt_inline rt_int32_t bit2bitno(rt_uint32_t bit)
{
    int i;
    for (i = 0; i < 32; i++)
    {
        if ((0x01 << i) == bit)
        {
            return i;
        }
    }
    return -1;
}


const static struct rt_pin_ops _tkm32_pin_ops = //填充ops结构体
{
    tkm32_pin_mode,
    tkm32_pin_write,
    tkm32_pin_read,
};


int rt_hw_pin_init(void)
{
#if defined(GPIOA)
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);//使能时钟
#endif
//..............


    return rt_device_pin_register("pin", &_tkm32_pin_ops, RT_NULL);//注册驱动
}
INIT_BOARD_EXPORT(rt_hw_pin_init);  
#endif /* RT_USING_PIN */

 

本文来自论坛,点击查看完整帖子内容。

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章