zoukankan      html  css  js  c++  java
  • 智能车学习(十四)——K60单片机GPIO学习

    一、头文件:

    #ifndef __MK60_GPIO_H__
    #define __MK60_GPIO_H__
    
    #include "MK60_gpio_cfg.h"
    
    /*
     * 定义管脚方向
     */
    typedef enum GPIO_CFG
    {
        //这里的值不能改!!!
        GPI         = 0,                                //定义管脚输入方向      GPIOx_PDDRn里,0表示输入,1表示输出
        GPO         = 1,                                //定义管脚输出方向
    } GPIO_CFG;
    
    #define HIGH  1u
    #define LOW   0u
    
    extern  GPIO_MemMapPtr      GPIOX[PTX_MAX];
    #define GPIOX_BASE(PTxn)     GPIOX[PTX(PTxn)]       //GPIO模块的地址
    
    
    
    /****************************外部使用****************************/
    
    extern void    gpio_init  (PTXn_e, GPIO_CFG, uint8 data);    //初始化gpio
    extern void    gpio_ddr   (PTXn_e, GPIO_CFG);                //设置引脚数据方向
    extern void    gpio_set   (PTXn_e,           uint8 data);    //设置引脚状态
    extern void    gpio_turn  (PTXn_e);                          //反转引脚状态
    extern uint8   gpio_get   (PTXn_e);                          //读取引脚状态
    
    
    
    //如下 4个 函数 的 PTxn 只能是 宏定义,不能是 变量
    #define GPIO_SET(PTxn,data)       (PTXn_T(PTxn,OUT)= (data))    //设置输出电平
    #define GPIO_TURN(PTxn)           (PTXn_T(PTxn,T)= 1)           //翻转输出电平
    #define GPIO_GET(PTxn)            (PTXn_T(PTxn,IN))             //读取引脚输入状态
    #define GPIO_DDR(PTxn,ddr)        (PTXn_T(PTxn,DDR) = ddr)      //输入输出状态
    
    
    //如下  函数 的 PTxn 可以是  宏定义,也可以是 变量
    
    //n位操作
    #define GPIO_SET_NBIT(NBIT,PTxn,data)   GPIO_PDOR_REG(GPIOX_BASE(PTxn)) =   (                                                   
                                                                                    (                                               
                                                                                        GPIO_PDOR_REG(GPIOX_BASE(PTxn))             
                                                                                        &                                           
                                                                                        ((uint32)( ~(((1<<NBIT)-1)<<PTn(PTxn))))    
                                                                                    )                                               
                                                                                    |   ((data)                                     
                                                                                        &(                                          
                                                                                            ((1<<NBIT)-1)                           
                                                                                                <<PTn(PTxn)                         
                                                                                         ))                                         
                                                                                )
    
    
    #define GPIO_DDR_NBIT(NBIT,PTxn,ddr)   GPIO_PDDR_REG(GPIOX_BASE(PTxn))  =   (                                                   
                                                                                    (                                               
                                                                                        GPIO_PDDR_REG(GPIOX_BASE(PTxn))             
                                                                                        &                                           
                                                                                        ((uint32)( ~(((1<<NBIT)-1)<<PTn(PTxn))))    
                                                                                    )                                               
                                                                                    |   ((ddr)                                      
                                                                                        &(                                          
                                                                                            ((1<<NBIT)-1)                           
                                                                                            <<PTn(PTxn)                             
                                                                                        ))                                          
                                                                                )
    
    #define GPIO_T_NBIT(NBIT,PTxn,data)   GPIO_PTOR_REG(GPIOX_BASE(PTxn))  =   (                                                    
                                                                                    (                                               
                                                                                        GPIO_PTOR_REG(GPIOX_BASE(PTxn))             
                                                                                        &                                           
                                                                                        ((uint32)( ~(((1<<NBIT)-1)<<PTn(PTxn))))    
                                                                                    )                                               
                                                                                    |   ((data)                                     
                                                                                        &(                                          
                                                                                            ((1<<NBIT)-1)                           
                                                                                            <<PTn(PTxn)                             
                                                                                        ))                                          
                                                                                )
    
    
    #define GPIO_GET_NBIT(NBIT,PTxn)    (( GPIO_PDIR_REG(GPIOX_BASE(PTxn))>>PTn(PTxn) ) & ((1<<NBIT)-1))
    
    
    #endif      //__MK60_GPIO_H__

    二、源文件:

    /*
     * 包含头文件
     */
    #include "common.h"
    #include "MK60_port.h"
    #include "MK60_gpio.h"
    
    /*
     * 定义数组
     */
    GPIO_MemMapPtr GPIOX[PTX_MAX] = {PTA_BASE_PTR, PTB_BASE_PTR, PTC_BASE_PTR, PTD_BASE_PTR, PTE_BASE_PTR}; //定义五个指针数组保存 GPIOX 的地址
    
    /*!
     *  @brief      初始化gpio
     *  @param      PTxn    端口
     *  @param      cfg     引脚方向,0=输入,1=输出
     *  @param      data    输出初始状态,0=低电平,1=高电平 (对输入无效)
     *  @since      v5.0
     *  Sample usage:       gpio_init (PTA8, GPI,0);    //初始化 PTA8 管脚为输入
     */
    void gpio_init (PTXn_e ptxn, GPIO_CFG cfg, uint8 data)
    {
        //复用管脚为GPIO功能
        port_init( ptxn, ALT1);
    
        //端口方向控制输入还是输出
        if(  cfg == GPI )
        {
            //设置端口方向为输入
            GPIO_PDDR_REG(GPIOX_BASE(ptxn)) &= ~(1 << PTn(ptxn));       // GPIO PDDR 管脚号 清0,即对应管脚配置为端口方向输入
        }
        else
        {
            //设置端口方向为输出
            GPIO_PDDR_REG(GPIOX_BASE(ptxn)) |= (1 << PTn(ptxn));        // GPIO PDDR 管脚号 置1,即对应管脚配置为端口方向输出
    
            //端口输出数据
            if(data == 0)
            {
                GPIO_PDOR_REG(GPIOX_BASE(ptxn)) &= ~(1 << PTn(ptxn));   // GPIO PDOR 管脚号 清0,即对应管脚配置为端口输出低电平
            }
            else
            {
                GPIO_PDOR_REG(GPIOX_BASE(ptxn))  |= (1 << PTn(ptxn));   // GPIO PDOR 管脚号 置1,即对应管脚配置为端口输出高电平
            }
        }
    }
    
    /*!
     *  @brief      设置引脚数据方向
     *  @param      PTxn    端口
     *  @param      cfg     引脚方向,0=输入,1=输出
     *  @since      v5.0
     *  Sample usage:       gpio_ddr (PTA8, GPI);    //设置 PTA8 管脚为输入
     */
    void  gpio_ddr   (PTXn_e ptxn, GPIO_CFG cfg)
    {
        //端口方向控制输入还是输出
        if(  cfg == GPI )
        {
            //设置端口方向为输入
            GPIO_PDDR_REG(GPIOX_BASE(ptxn)) &= ~(1 << PTn(ptxn));           // GPIO PDDR 管脚号 清0,即对应管脚配置为端口方向输入
        }
        else
        {
            //设置端口方向为输出
            GPIO_PDDR_REG(GPIOX_BASE(ptxn)) |= (1 << PTn(ptxn));            // GPIO PDDR 管脚号 置1,即对应管脚配置为端口方向输出
        }
    }
    
    /*!
     *  @brief      设置引脚状态
     *  @param      PTxn    端口
     *  @param      data    输出初始状态,0=低电平,1=高电平 (对输入无效)
     *  @since      v5.0
     *  @warning    务必保证数据方向为输出(DEBUG模式下,有断言进行检测)
     *  Sample usage:       gpio_set (PTA8, 1);    // PTA8 管脚 输出 1
     */
    void gpio_set (PTXn_e ptxn, uint8 data)
    {
        ASSERT( BIT_GET( GPIO_PDDR_REG(GPIOX_BASE(ptxn)) , PTn(ptxn)) == GPO ); // 断言,检测 输出方向是否为输出
                                                                                // 获取 GPIO PDDR 管脚号 ,比较是否为输出
    
        //端口输出数据
        if(data == 0)
        {
            GPIO_PDOR_REG(GPIOX_BASE(ptxn)) &= ~(1 << PTn(ptxn));   // GPIO PDOR 管脚号 清0,即对应管脚配置为端口输出低电平
        }
        else
        {
            GPIO_PDOR_REG(GPIOX_BASE(ptxn))  |= (1 << PTn(ptxn));   // GPIO PDOR 管脚号 置1,即对应管脚配置为端口输出高电平
        }
    }
    
    
    /*!
     *  @brief      反转引脚状态
     *  @param      PTxn    端口
     *  @since      v5.0
     *  @warning    务必保证数据方向为输出(DEBUG模式下,有断言进行检测)
     *  Sample usage:       gpio_turn (PTA8);    // PTA8 管脚 输出 反转
     */
    void gpio_turn (PTXn_e ptxn)
    {
        ASSERT( BIT_GET( GPIO_PDDR_REG(GPIOX_BASE(ptxn)) , PTn(ptxn)) == GPO ); // 断言,检测 输出方向是否为输出
                                                                                // 获取 GPIO PDDR 管脚号 ,比较是否为输出
    
        GPIO_PTOR_REG( GPIOX_BASE(ptxn))  =  1 << (PTn(ptxn ));                 // GPIO PTOR ptxn 置1,其他清0 ,即对应管脚配置为端口输出反转,其他位不变
                                                                                // 此处不能用 BIT_SET 这个宏来置1 ,因为必须保证其他位 不变,其他位直接清0即可
    }
    
    /*!
     *  @brief      读取引脚输入状态
     *  @param      PTxn    端口
     *  @return     管脚的状态,1为高电平,0为低电平
     *  @since      v5.0
     *  @warning    务必保证数据方向为输入(DEBUG模式下,有断言进行检测)
     *  Sample usage:       uint8 pta8_data = gpio_get (PTA8);    // 获取 PTA8 管脚 输入电平
     */
    uint8 gpio_get(PTXn_e ptxn)
    {
        ASSERT( BIT_GET( GPIO_PDDR_REG(GPIOX_BASE(ptxn)) , PTn(ptxn)) == GPI ); // 断言,检测 输出方向是否为输入
                                                                                // 获取 GPIO PDDR 管脚号 ,比较是否为输入
    
        return ((GPIO_PDIR_REG(GPIOX_BASE(ptxn)) >> PTn(ptxn )) & 0x01);        // 获取 GPIO PDIR ptxn 状态,即读取管脚输入电平
    }

     

     

     

     

    三、小结:

        主要是学会怎么调用,出现问题的话,检查寄存器的配置(不过一般不需要)。

  • 相关阅读:
    Swift
    Swift
    Swift
    Swift
    Swift
    Swift
    Swift
    C++生产和使用的临时对象
    RecyclerView0基于使用
    Docker创建MySQL集装箱
  • 原文地址:https://www.cnblogs.com/BlueMountain-HaggenDazs/p/4993121.html
Copyright © 2011-2022 走看看