|
接觸單片機(jī)也有兩年了,之前是一直使用庫函數(shù)的操作方式,然后逐漸有,提高封裝函數(shù)通用性稍微強(qiáng)一點的想法。庫函數(shù)因為是有別人寫好的一系列封裝函數(shù),所以庫不變的情況下,還是比較方便的。參考了各位大佬們分享的帖子,后面自己再處理了一下。
上內(nèi)容:(用枚是為了收納方便)
/**************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 , //復(fù)用推挽輸出
GPIO_MODE_OUT_APOD = 3 , //復(fù)用開漏輸出
}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 { //結(jié)構(gòu)體: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腳,引腳輸入/輸出模式,引腳輸出速度 ,初始輸出狀態(tài)(高低電平)
{GPIOC, PIN1 , GPIO_MODE_OUT_PP ,GPIO_SPEED_50M, 1 },
{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},
{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},
{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},
{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},
{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},
{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},
{GPIOC, PIN12, GPIO_MODE_OUT_PP ,GPIO_SPEED_50M, 0 },
};
//位帶操作,實現(xiàn)51類似的GPIO控制功能
//具體實現(xiàn)思想,參考<<CM3權(quán)威指南>>第五章(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, //結(jié)束,防止枚舉內(nèi)容為空,無實際意義
}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設(shè)置函數(shù)
*
* @param @arg GPIOx:GPIOA~GPIOI.
@arg BITx:0X0000~0XFFFF.位設(shè)置,每個位代表一個IO,第0位代表Px0,第1位代表Px1,依次類推.比如0X0101,代表同時設(shè)置Px0和Px8.
@arg MODE:模式選擇0~3:輸入模式下,0,模擬輸入;1,浮空輸入(復(fù)位狀態(tài));2,上拉/下拉輸入模式;3,保留;
輸出模式下,0,通用推挽輸出;1,通用開漏輸出;2,復(fù)用推挽輸出;3,復(fù)用開漏輸出;
@arg OSPEED_MODE:速度模式選擇0~3:0,輸入(系統(tǒng)復(fù)位默認(rèn)狀態(tài));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;//檢查引腳是否要設(shè)置
if(curpin==pos) //需要設(shè)置
{
if(pinpos < 8)//設(shè)置的管腳為0~7
{
pinposlh = pinpos;
GPIOx->CRL &= ~(0xF<<(4*pinposlh));//清除需要設(shè)置的位
GPIOx->CRL |= (OSPEED_MODE<<(4*pinposlh));//設(shè)置新的速度模式
GPIOx->CRL |= (MODE<<(4*pinposlh+2));//設(shè)置新的輸入輸出模式
}
else //設(shè)置的管腳為8~15
{
pinposlh = pinpos-8;
GPIOx->CRH &= ~(0xF<<(4*pinposlh));//清除需要設(shè)置的位
GPIOx->CRH |= (OSPEED_MODE<<(4*pinposlh));//設(shè)置新的速度模式
GPIOx->CRH |= (MODE<<(4*pinposlh+2));//設(shè)置新的輸入輸出模式
}
}
}
}
void GPIO_Init_(void) //GPIO引腳逐一初始化函數(shù)
{
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系列單片機(jī)
while(GPIO_InitList_Len <= 120) //只放在主循環(huán)前,while()循環(huán)影響不大
{
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) //對初始狀態(tài)為高電平的引腳配置,默認(rèn)低電平。
{
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 ++;
}
}
}
/**************主函數(shù)**************/
#include "GPIO.h"
int main(void)
{
GPIO_Init_();
while (1)
{
}
}
希望各位大佬們不吝賜教,懇請各位大佬們提出寶貴意見與想法
,感謝!
STM32F103RC單片機(jī)的GPIO初始化封裝.zip
(582.06 KB, 下載次數(shù): 7)
2023-2-10 14:24 上傳
點擊文件名下載附件
|
評分
-
查看全部評分
|