久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1886|回復: 4
打印 上一主題 下一主題
收起左側

關于STM32F103RC單片機的GPIO初始化封裝(寄存器)

[復制鏈接]
回帖獎勵 1 黑幣 回復本帖可獲得 1 黑幣獎勵! 每人限 1 次
跳轉到指定樓層
樓主
ID:728915 發表于 2023-2-10 10:04 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
接觸單片機也有兩年了,之前是一直使用庫函數的操作方式,然后逐漸有,提高封裝函數通用性稍微強一點的想法。庫函數因為是有別人寫好的一系列封裝函數,所以庫不變的情況下,還是比較方便的。參考了各位大佬們分享的帖子,后面自己再處理了一下。   

上內容:(用枚是為了收納方便)
/**************GPIO.H文件**************/
#ifndef __GPIO_H
#define __GPIO_H

#include "stm32f10x.h"                  // Device header

typedef enum        //枚舉:PIN腳
{
         PIN0        =        1<<0        ,        PIN1        =        1<<1    ,
         PIN2        =        1<<2    ,        PIN3        =        1<<3    ,
         PIN4        =        1<<4    ,        PIN5        =        1<<5    ,
         PIN6        =        1<<6    ,        PIN7        =        1<<7    ,
         PIN8        =        1<<8    ,        PIN9        =        1<<9    ,
         PIN10        =        1<<10   ,        PIN11        =        1<<11   ,
         PIN12        =        1<<12   ,        PIN13        =        1<<13   ,
         PIN14        =        1<<14   ,        PIN15        =        1<<15   ,
}GPIO_PIN_TypeDef;

typedef enum        //枚舉:引腳輸入/輸出模式
{
         GPIO_MODE_IN_ANALOG         =        0        ,        //模擬輸入模式
         GPIO_MODE_IN_FLOAT                =        1          ,        //浮空輸入模式
         GPIO_MODE_IN_PUPD                =        2          ,   //上拉下拉輸入模式
        
         GPIO_MODE_OUT_PP                  =        0          ,        //推挽輸出
         GPIO_MODE_OUT_OD                =        1          ,        //開漏輸出
         GPIO_MODE_OUT_AFPP                =        2          ,        //復用推挽輸出
         GPIO_MODE_OUT_APOD                =        3          ,        //復用開漏輸出
}GPIO_MODE_TypeDef;

typedef enum        //枚舉:引腳輸出速度
{
        GPIO_SPEED_IN        =        0        ,        //GPIO輸入模式
        GPIO_SPEED_10M        =        1         ,        //GPIO輸出速度10Mhz
        GPIO_SPEED_20M        =        2         ,   //GPIO輸出速度20Mhz
        GPIO_SPEED_50M        =   3        ,   //GPIO輸出速度50Mhz
}GPIO_SPEED_TypeDef;

typedef struct {        //結構體:GPIO引腳配置項目
        GPIO_TypeDef*         GPIO_x;
        uint32_t                   GPIO_PIN_X;
        uint32_t                   GPIO_MODE;
        uint32_t                   GPIO_SPEED;
        uint8_t                        GPIO_InitState;
}GPIO_InitList;

static GPIO_InitList GPIO_Init_List[ 120 ] =   //添加、修改需要配置的GPIO口
{// GPIO_X, PIN腳,引腳輸入/輸出模式,引腳輸出速度 ,初始輸出狀態(高低電平)
        {GPIOC, PIN1 , GPIO_MODE_OUT_PP ,GPIO_SPEED_50M,         1        },
        {},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},
        {},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},
        {},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},
        {},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},
        {},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},
        {},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},
    {GPIOC, PIN12, GPIO_MODE_OUT_PP ,GPIO_SPEED_50M,         0        },
};


//位帶操作,實現51類似的GPIO控制功能
//具體實現思想,參考<<CM3權威指南>>第五章(87頁~92頁)。M4同M3類似,只是寄存器地址變了。
typedef enum        //GPIO宏定義及地址映射
{


        //IO口操作宏定義
        #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
        #define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))
        #define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))

        //IO口地址映射
        #define GPIOA_ODR_Addr    (GPIOA_BASE+12) //0x4002000C
        #define GPIOB_ODR_Addr    (GPIOB_BASE+12) //0x4002040C
        #define GPIOC_ODR_Addr    (GPIOC_BASE+12) //0x4002080C
        #define GPIOD_ODR_Addr    (GPIOD_BASE+12) //0x40020C0C
        #define GPIOE_ODR_Addr    (GPIOE_BASE+12) //0x4002100C
        #define GPIOF_ODR_Addr    (GPIOF_BASE+12) //0x4002140C   
        #define GPIOG_ODR_Addr    (GPIOG_BASE+12) //0x4002180C   
        #define GPIOH_ODR_Addr    (GPIOH_BASE+12) //0x40021C0C   
        #define GPIOI_ODR_Addr    (GPIOI_BASE+12) //0x4002200C     

        #define GPIOA_IDR_Addr    (GPIOA_BASE+8) //0x40020008
        #define GPIOB_IDR_Addr    (GPIOB_BASE+8) //0x40020408
        #define GPIOC_IDR_Addr    (GPIOC_BASE+8) //0x40020808
        #define GPIOD_IDR_Addr    (GPIOD_BASE+8) //0x40020C08
        #define GPIOE_IDR_Addr    (GPIOE_BASE+8) //0x40020808
        #define GPIOF_IDR_Addr    (GPIOF_BASE+8) //0x40021408
        #define GPIOG_IDR_Addr    (GPIOG_BASE+8) //0x40021808
        #define GPIOH_IDR_Addr    (GPIOH_BASE+8) //0x40021C08
        #define GPIOI_IDR_Addr    (GPIOI_BASE+8) //0x40022008
         
        //IO口操作,只對單一的IO口!
        //確保n的值小于16!
        #define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //輸出
        #define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //輸入

        #define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //輸出
        #define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //輸入

        #define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //輸出
        #define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //輸入

        #define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //輸出
        #define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //輸入

        #define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //輸出
        #define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //輸入

        #define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //輸出
        #define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //輸入

        #define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //輸出
        #define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //輸入

        #define PHout(n)   BIT_ADDR(GPIOH_ODR_Addr,n)  //輸出
        #define PHin(n)    BIT_ADDR(GPIOH_IDR_Addr,n)  //輸入

        #define PIout(n)   BIT_ADDR(GPIOI_ODR_Addr,n)  //輸出
        #define PIin(n)    BIT_ADDR(GPIOI_IDR_Addr,n)  //輸出
        
        GPIO_Init_Base_END  = 0,        //結束,防止枚舉內容為空,無實際意義
        
}GPIO_Init_Base_;

void GPIO_Set(GPIO_TypeDef* GPIOx, uint32_t BITx, uint32_t MODE, uint32_t OSPEED_MODE);
void GPIO_Init_(void);

#endif

/**************GPIO.C文件**************/

#include "GPIO.h"  

/**
  * @brief  通用GPIO設置函數
        *                                       
  * @param  @arg GPIOx:GPIOA~GPIOI.
                        @arg BITx:0X0000~0XFFFF.位設置,每個位代表一個IO,第0位代表Px0,第1位代表Px1,依次類推.比如0X0101,代表同時設置Px0和Px8.
                        @arg MODE:模式選擇0~3:輸入模式下,0,模擬輸入;1,浮空輸入(復位狀態);2,上拉/下拉輸入模式;3,保留;
                                                                   輸出模式下,0,通用推挽輸出;1,通用開漏輸出;2,復用推挽輸出;3,復用開漏輸出;        
                        @arg OSPEED_MODE:速度模式選擇0~3:0,輸入(系統復位默認狀態);1:10M輸出;2:20M輸出;3:50M輸出.
  * @retval 無
  */
void GPIO_Set(GPIO_TypeDef* GPIOx, uint32_t BITx, uint32_t MODE, uint32_t OSPEED_MODE)
{  
        u32 pinpos=0,pinposlh=0,pos=0,curpin=0;
        for(pinpos=0;pinpos<16;pinpos++)
        {
                pos=1<<pinpos;        //一個個位檢查
                curpin=BITx&pos;//檢查引腳是否要設置
                if(curpin==pos)        //需要設置
                {
                        if(pinpos < 8)//設置的管腳為0~7
                        {
                                pinposlh = pinpos;
                                GPIOx->CRL &= ~(0xF<<(4*pinposlh));//清除需要設置的位
                                GPIOx->CRL |= (OSPEED_MODE<<(4*pinposlh));//設置新的速度模式
                                GPIOx->CRL |= (MODE<<(4*pinposlh+2));//設置新的輸入輸出模式
                        }
                        else                 //設置的管腳為8~15
                        {
                                pinposlh = pinpos-8;
                                GPIOx->CRH &= ~(0xF<<(4*pinposlh));//清除需要設置的位
                                GPIOx->CRH |= (OSPEED_MODE<<(4*pinposlh));//設置新的速度模式
                                GPIOx->CRH |= (MODE<<(4*pinposlh+2));//設置新的輸入輸出模式
                        }
                }
        }
}
                        


void GPIO_Init_(void)  //GPIO引腳逐一初始化函數
{
        uint8_t GPIO_InitList_Len;
        
        RCC->APB2ENR |= 1<<2|1<<3|1<<4|1<<5|1<<6|1<<7|1<<8; //打開GPIOA-G的7個時鐘,適用STM32F103RC系列單片機

        while(GPIO_InitList_Len <= 120)        //只放在主循環前,while()循環影響不大
        {
                if(GPIO_Init_List[GPIO_InitList_Len].GPIO_x != 0)
                {
                        GPIO_Set(GPIO_Init_List[GPIO_InitList_Len].GPIO_x, GPIO_Init_List[GPIO_InitList_Len].GPIO_PIN_X, GPIO_Init_List[GPIO_InitList_Len].GPIO_MODE, GPIO_Init_List[GPIO_InitList_Len].GPIO_SPEED);
                        if(GPIO_Init_List[GPIO_InitList_Len].GPIO_InitState)        //對初始狀態為高電平的引腳配置,默認低電平。
                        {
                                GPIO_Init_List[GPIO_InitList_Len].GPIO_x -> ODR |= (GPIO_Init_List[GPIO_InitList_Len].GPIO_PIN_X);
                        }        
                        GPIO_InitList_Len ++;
                }
                else
                {
                        GPIO_InitList_Len ++;
                }
        }
}



/**************主函數**************/
#include "GPIO.h"                 

int main(void)
{

        GPIO_Init_();
        
        while (1)
        {
               
        }
        
}


希望各位大佬們不吝賜教,懇請各位大佬們提出寶貴意見與想法
,感謝! STM32F103RC單片機的GPIO初始化封裝.zip (582.06 KB, 下載次數: 7)





評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:307150 發表于 2023-2-11 17:44 | 只看該作者
這個貼很好!!!
回復

使用道具 舉報

板凳
ID:1034262 發表于 2023-2-12 11:22 | 只看該作者
我都是映射成51那種的操作,直接PA0=1; PA0=0;這樣。
回復

使用道具 舉報

地板
ID:1062805 發表于 2023-2-12 13:48 | 只看該作者
可以,思路不錯
回復

使用道具 舉報

5#
ID:728915 發表于 2024-6-27 00:09 | 只看該作者
這個方式,在用作模擬IIC的時候,配置成開漏輸出,可能會有問題,自己踩坑了。。。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲精品日韩精品 | www.毛片.com| 日韩在线小视频 | 成人午夜网站 | 在线观看中文字幕 | 四虎成人网 | 久久小视频 | 黄色录像大片 | 美日韩一区 | 免费网站av | 日韩精品第一页 | 久久av中文字幕 | av片免费观看 | 伊人网在线观看 | 亚洲黄色三级 | 欧美日日夜夜 | 欧美在线亚洲 | 精久久久久 | 成人性色生活片 | 亚洲成人av在线 | 91精品一区 | 久热精品视频 | 欧美日韩第一区 | 国产成人精品一区二区三区在线观看 | 日韩三级视频 | 久久久久久综合 | 欧美一区二区三区的 | 国产乱码一区二区 | 免费毛片在线播放 | av第一页| 日韩精品视频在线免费观看 | 久久久www成人免费精品 | 亚洲免费看片 | 国产精品久久久久久久午夜 | 亚洲精品在线免费 | 国产成人+综合亚洲+天堂 | 天天色网站 | 国产美女免费视频 | 五月天在线 | 国产又黄又爽视频 | 国产资源视频 |