以下是底层实现代码:建议复制后直接放在SYS.C文件中
**************************************************************************************
//GPIO端口配置函数
//
//输入参数:
//GPIOx:直接填写0~6代表GPIOA~G, 或使用宏定义
//BITx: 端口位号(即端口数字号,如PA4则参数为4)
//Mode: 端口模式,共8种,请使用模式的宏定义或直接填写数值,
// 函数不检查该参数,请勿超出这8种的范围自创模式!!!
//Speed:端口速度, 共3种,请使用速度的宏定义或直接填写数值(1/2/3),
// 该参数仅在输出模式下有作用,设输入模式时,可以随便填一个值
//返回值: 无. 端口组或端口号超出范围时将直接返回.
//该函数没有使用库函数, 使用时也无须包含stm32f10x_gpio.h
//使用示例: My_GPIO_Init(GPIO_D, 5, Mode_Out_OD, Speed_50MHz); 即可设置PD5为开漏输出
void My_GPIO_Init(u8 GPIOx, u8 BITx, u8 Mode, u8 Speed)
{
GPIO_TypeDef *pAddr; //指向GPIO寄存器组基址的地址指针
u32 currentmode = 0x00, pinpos = 0x00, pos = 0x00;
u32 tmpreg = 0x00, pinmask = 0x00;
if(GPIOx>6 || BITx>15) return; //端口参数超出范围,直接返回
pAddr=(GPIO_TypeDef *)(GPIOA_BASE+0x400*GPIOx); //计算对应的GPIO端口基址, 每组端口占用地址空间为400H
/*---------------------------- GPIO 模式配置 -----------------------*/
currentmode = ((u32)Mode) & ((u32)0x0F); //取模式参数低4位存入currentmode
if ( Mode & 0x10) //如果第5位为1,则为输出模式
{
currentmode |= (u32)(Speed & 0x03); //仅在输出模式下,速度参数才有效
}
/*---------------------------- GPIO CRL 配置 ------------------------*/
if ( BITx <8 ) //如果端口线号<8, 则配置CRL
{
pinpos=BITx;
tmpreg = pAddr->CRL; //取CRL原有值
pos = pinpos << 2; //BIT位置计算,每线占4BIT
/* 清0相应的CRL寄存器BIT位 */
pinmask = ((u32)0x0F) << pos;
tmpreg &= ~pinmask;
/* 写模式配置相应的BIT位 */
tmpreg |= (currentmode << pos);
pAddr->CRL = tmpreg; //完成CRL配置
}
/*---------------------------- GPIO CRH 配置 ------------------------*/
else //端口线号>=8, 则配置CRL
{
tmpreg = pAddr->CRH; //取CRH原有值
pinpos=BITx-0x08;
pos = pinpos << 2;
/* 清0相应的CRH寄存器BIT位 */
pinmask = ((u32)0x0F) << pos;
tmpreg &= ~pinmask;
/* 写模式配置相应的BIT位 */
tmpreg |= (currentmode << pos);
pAddr->CRH = tmpreg; //完成CRH配置
} //最后如果是上拉下拉输入模式,则初始化一下相应端口电平
if (Mode == Mode_IPD) pAddr->BRR=1<<BITx; /* 对于下拉输入模式,则复位端口 */
else if(Mode == Mode_IPU) pAddr->BSRR=1<<BITx; /* 对于上拉输入模式,则置位端口 */
} |