找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 13140|回复: 1
打印 上一主题 下一主题
收起左侧

STM32F103VET6的GPIO简表及系统初始化程序

[复制链接]
跳转到指定楼层
楼主
ID:82781 发表于 2015-6-23 14:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本库函数库供检阅 与天津第四项目部
如有错误纯属正常
宏定义结构体:
typedef struct
{ vu32 CRL; 端口配置低寄存器
vu32 CRH; 端口配置高寄存器
vu32 IDR; 端口输入数据寄存器
vu32 ODR; 端口输出数据寄存器
vu32 BSRR; 端口位设置/复位寄存器
vu32 BRR; 端口位复位寄存器
vu32 LCKR; 端口配置锁定寄存器
} GPIO_TypeDef;
说明GPIO的寄存器的宏定义结构体
typedef struct
{ vu32 EVCR; 事件控制寄存器
vu32 MAPR; 复用重映射和调试I/O配置寄存器
vu32 EXTICR[4]; 外部中断线路0-15配置寄存器
} AFIO_TypeDef;
定义复用AFIO端口配置寄存器宏定义结构体
#define PERIPH_BASE ((u32)0x40000000)
#define APB1PERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) ...
#define AFIO_BASE (APB2PERIPH_BASE + 0x0000)
#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800)
#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)
#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)
#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400)
#define GPIOE_ BASE (APB2PERIPH_BASE + 0x1800)
定义物理寄存器的储存组织地址
这个下面的就是结构指针,
#ifndef DEBUG GPIO 121/368 译文英文原版为 UM0427 Oct. 2007 Rev 2, 译文仅供参考,与英文版冲突的,以英文版为准 ..
. #ifdef _AFIO
#define AFIO ((AFIO_TypeDef *) AFIO_BASE)
#endif
/*_AFIO */
#ifdef _GPIOA
#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)
#endif /*_GPIOA */
#ifdef _GPIOB
#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE)
#endif /*_GPIOB */
#ifdef _GPIOC
#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE)
#endif /*_GPIOC */
#ifdef _GPIOD #define GPIOD ((GPIO_TypeDef *) GPIOD_BASE)
#endif /*_GPIOD */
#ifdef _GPIOE #define GPIOE ((GPIO_TypeDef *) GPIOE_BASE)
#endif /*_GPIOE */ ..
.GPIO的库函数目录
函数介绍:
1.     GPIO_DeInit(GPIOA); 将外设GPIOx寄存器重设为缺省值
2.     GPIO_AFIODeInit();将复用功能(重映射事件控制和EXTI设置)重设为缺省值
3.     typedef struct
{ u16 GPIO_Pin;//管教寄存器
GPIOSpeed_TypeDef GPIO_Speed;//管教速度寄存器
GPIOMode_TypeDef GPIO_Mode;//管教模式寄存器
} GPIO_InitTypeDef;//这个宏结构定义并非函数,而是他的寄存器的封装,要用它去定义变量,系统在这里编译时并不分配内存
GPIO_Pin
该参数选择待设置的GPIO管脚,使用操作符“|”可以一次选中多个管脚。可以使用下表中的任意组合。
GPIO_Pin_None 无管脚被选中
GPIO_Pin_0 选中管脚0
GPIO_Pin_1 选中管脚1
GPIO_Pin_2 选中管脚2
GPIO_Pin_3 选中管脚3
GPIO_Pin_4 选中管脚4
GPIO_Pin_5 选中管脚5
GPIO_Pin_6 选中管脚6
GPIO_Pin_7 选中管脚7
GPIO_Pin_8 选中管脚8
GPIO_Pin_9 选中管脚9
GPIO_Pin_10 选中管脚10
GPIO_Pin_11 选中管脚11
GPIO_Pin_12 选中管脚12
GPIO_Pin_13 选中管脚13
GPIO_Pin_14 选中管脚14
GPIO_Pin_15 选中管脚15
GPIO_Pin_All 选中全部管脚
GPIO_Speed
GPIO_Speed用以设置选中管脚的速率
GPIO_Speed_10MHz 最高输出速率10MHz
GPIO_Speed_2MHz 最高输出速率2MHz
GPIO_Speed_50MHz 最高输出速率50MHz
GPIO_Mode
GPIO_Mode用以设置选中管脚的工作状态
GPIO_Mode_AIN 模拟输入
GPIO_Mode_IN_FLOATING 浮空输入
GPIO_Mode_IPD 下拉输入
GPIO_Mode_IPU 上拉输入
GPIO_Mode_Out_OD 开漏输出
GPIO_Mode_Out_PP 推挽输出
GPIO_Mode_AF_OD 复用开漏输出
GPIO_Mode_AF_PP 复用推挽输出
注意: 􀂄 当某管脚设置为上拉或者下拉输入模式,使用寄存器Px_BSRRPxBRR 􀂄 GPIO_Mode允许同时设置GPIO方向(输入/输出)和对应的输入/输出设置,:位[7:4]对应GPIO方向,位[4:0]对应配置。
GPIO方向有如下索引
- GPIO输入模式 = 0x00
- GPIO输出模式 = 0x01
给出了所有GPIO_Mode的索引和编码
例子:
GPIO_InitTypeDef GPIO_InitStructure;//定义一个GPIO_InitTypeDef结构变量GPIO_InitStructure
这里注意宏结构和结构变量的区别
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; 引脚选择全部
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;速度选择最高输出速率10MHz
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//这个函数才是最后的执行函数最重要以上是设置
原型:
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
可以看出定义了两个指针参数:GPIO_TypeDef* GPIOxGPIO_InitTypeDef* GPIO_InitStruct
第一个表示定义一个GPIO_TypeDef型结构指针变量GPIOx他可传递一下参数:
CRL 端口配置低寄存器
CRH 端口配置高寄存器
IDR 端口输入数据寄存器
ODR 端口输出数据寄存器
BSRR 端口位设置/复位寄存器
BRR 端口位复位寄存器
LCKR 端口配置锁定寄存器
可以这样访问参数:GPIOx-> IDR=0x多少多少;因为他是指针
第二个表示定义一个GPIO_InitTypeDef型结构指针变量GPIO_InitStruct他可传递一下参数:
GPIO_Pin;//管教寄存器
GPIOSpeed_TypeDef GPIO_Speed;//管教速度寄存器
GPIOMode_TypeDef GPIO_Mode;//管教模式寄存器
可以这样访问参数:GPIO_InitStruct-> GPIO_Pin =0X多少多少;因为他是指针
注意:两个都是指针固然不假但是比较后发现问题:
GPIO_Init(GPIOA, &GPIO_InitStructure);
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
前者没有&后者有&,然后回头看定义会发现GPIOX是已经定义了的地址
#ifdef _AFIO #define AFIO ((AFIO_TypeDef *) AFIO_BASE) #endif /*_AFIO */ #ifdef _GPIOA #define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) #endif /*_GPIOA */ #ifdef _GPIOB #define GPIOB ((GPIO_TypeDef *) GPIOB_BASE) #endif /*_GPIOB */ #ifdef _GPIOC #define GPIOC ((GPIO_TypeDef *) GPIOC_BASE) #endif /*_GPIOC */ #ifdef _GPIOD #define GPIOD ((GPIO_TypeDef *) GPIOD_BASE) #endif /*_GPIOD */ #ifdef _GPIOE #define GPIOE ((GPIO_TypeDef *) GPIOE_BASE) #endif /*_GPIOE */
所以它本身就是一个指向物理寄存器地址的指针,并且被赋予首地址,现在又定义了一个指针参量相当于把它的值赋给后者表示为:
例如:GPIO_TypeDef* GPIOA=((GPIO_TypeDef *) GPIOA_BASE)
第二个不同了在定义中未发现他的地址定义,而且他还是个结构类型
GPIO_InitTypeDef* GPIO_InitStruct,只是定义了一个GPIO_InitTypeDe型结构指针变量GPIO_InitStruct,而前面有个GPIO_InitTypeDe变量跟他同名是为了可读性,如果不加&显然是不对的&表示取出变量GPIO_InitStruct的地址所给指针变量GPIO_InitStruct以指向他的首地址。有点绕,但是就是一个指针的赋值问题。
4.     GPIO_InitTypeDef GPIO_InitStructure;变量说明
GPIO_StructInit(&GPIO_InitStructure);//函数把GPIO_InitStruct中的每一个参数按缺省值填入
缺省值
GPIO_Pin GPIO_Pin_All
GPIO_Speed GPIO_Speed_2MHz
GPIO_Mode GPIO_Mode_IN_FLOATING
5u8 ReadValue; 变量说明
ReadValue = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_7); 读取指定端口管脚的输入
6.u16 ReadValue;
ReadValue = GPIO_ReadInputData(GPIOC); 读取指定的GPIO端口输入
7. u8 ReadValue;
ReadValue = GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_7); 读取指定端口管脚的输出
8. u16 ReadValue; ReadValue = GPIO_ReadOutputData(GPIOC); 读取指定的GPIO端口输出
9GPIO_SetBits(GPIOA, GPIO_Pin_10 | GPIO_Pin_15); 设置指定的数据端口位
10GPIO_ResetBits(GPIOA, GPIO_Pin_10 | GPIO_Pin_15); 清除指定的数据端口位
11GPIO_WriteBit(GPIOA, GPIO_Pin_15, Bit_SET); 设置或者清除指定的数据端口位
GPIOxx可以是ABCD或者E,来选择GPIO外设
GPIO_Pin:待设置或者清除指的端口位该参数可以取GPIO_Pin_x(x可以是0-15)的任意组合
BitVal: 该参数指定了待写入的值该参数必须取枚举BitAction的其中一个值
Bit_RESET: 清除数据端口位
Bit_SET: 设置数据端口位
12GPIO_Write(GPIOA, 0x1101); 向指定GPIO数据端口写入数据
13GPIO_PinLockConfig(GPIOA, GPIO_Pin_0 | GPIO_Pin_1); 锁定GPIO管脚设置寄存器
14GPIO_EventOutputConfig(GPIO_PortSourceGPIOE, GPIO_PinSource5); 选择GPIO管脚用作事件输出
GPIO_PortSourceGPIOE选择GPIOE
GPIO_PinSource5事件输出的管脚5
15.GPIO_EventOutputConfig(GPIO_PortSourceGPIOC, GPIO_PinSource6);
GPIO_EventOutputCmd(ENABLE); 使能或者失能事件输出
事件输出的新状态
这个参数可以取:ENABLE或者DISABLE
16. 例:
/* I2C1_SCL on PB.08, I2C1_SDA on PB.09 */
GPIO_PinRemapConfig(GPIO_Remap_I2C1, ENABLE); 改变指定管脚的映
GPIO_Remap_SPI1
SPI1复用功能映射
GPIO_Remap_I2C1
I2C1复用功能映射
GPIO_Remap_USART1
USART1复用功能映射
GPIO_PartialRemap_USART3
USART2复用功能映射
GPIO_FullRemap_USART3
USART3复用功能完全映射
GPIO_PartialRemap_TIM1
USART3复用功能部分映射
GPIO_FullRemap_TIM1
TIM1复用功能完全映射
GPIO_PartialRemap1_TIM2
TIM2复用功能部分映射1
GPIO_PartialRemap2_TIM2
TIM2复用功能部分映射2
GPIO_FullRemap_TIM2
TIM2复用功能完全映射
GPIO_PartialRemap_TIM3
TIM3复用功能部分映射
GPIO_FullRemap_TIM3
TIM3复用功能完全映射
GPIO_Remap_TIM4
TIM4复用功能映射
GPIO_Remap1_CAN
CAN复用功能映射1
GPIO_Remap2_CAN
CAN复用功能映射2
GPIO_Remap_PD01
PD01复用功能映射
GPIO_Remap_SWJ_NoJTRST
JTRSTSWJ完全使能(JTAG+SW-DP
GPIO_Remap_SWJ_JTAGDisable
JTAG-DP失能 + SW-DP使能
GPIO_Remap_SWJ_Disable
SWJ完全失能(JTAG+SW-DP
17. GPIO_EXTILineConfig(GPIO_PortSource_GPIOB, GPIO_PinSource8); 选择GPIO管脚用作外部中断线路

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:82781 发表于 2015-6-23 14:27 | 只看该作者
                                                                                                昨天的彷徨和沮丧,今天的曙光,迈进ARM世界的一小步

本程序为STM32F103VET6的GPIO系统初始化程序,定义了RCC寄存器和系统时钟,昨天的问题也得到解决,我的程序没错,错的是由于昨天设置的时钟频率为72M所以体现不出等在闪烁!以下函数均使用ST公司的固件库。        


void mysysint()//系统初始化程序
{
ErrorStatus HSEStartUpStatus;//说明标志位
RCC_DeInit();//所有外设全部缺省设置

/* Enable HSE */
RCC_HSEConfig(RCC_HSE_ON);
/* Wait till HSE is ready and if Time out is reached exit */
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if(HSEStartUpStatus == SUCCESS)//启动成功
{
/*这两条FLASH指令必须加上,不知为啥?不加上就运行几秒后出错,参照系统初始化*/
/* Enable The Prefetch Buffer */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);//FLASH缓存开启
/* Configure the Latency cycle: Set 2 Latency cycles */
  FLASH_SetLatency(FLASH_Latency_2);  //设置FLASH这些位表示SYSCLK(系统时钟)周期与闪存访问时间的比例,为010:两个等待状态,当 48MHz < SYSCLK ≤ 72MHz
/* Set PLL clock output to 72MHz using HSE (8MHz) as entry clock */
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_7);//外部时钟为8M,PLL的输入时钟=8MHZ,倍频系数9,

/* Configure HCLK such as HCLK = SYSCLK */
RCC_HCLKConfig(RCC_SYSCLK_Div1);//设置了啦AHB分频器的分频系数=1,即HCLK=SYSCLK=72MHZ
/* Configure PCLK1 such as PCLK1 = HCLK/2 */
RCC_PCLK1Config(RCC_HCLK_Div2);//设置了APB1外设的时钟频率最大是36M这里是APB1的分频器设为2,PCLK1=HCLK/2=72/2=36MHZ正好是最大值
/* Configure PCLK2 such as PCLK2 = HCLK */
RCC_PCLK2Config(RCC_HCLK_Div1);//设置PLCK2=HCLK=72MHZ,的APB2分频器=1
/* Select the PLL as system clock source */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//设置了SYSCLK的提供者为PLL,频率由上面算出=72MHZ
/* disable PLL Ready interrupt */
RCC_ITConfig(RCC_IT_PLLRDY, DISABLE);//PLL中断关闭
/* disable PLL Ready interrupt */
RCC_ITConfig(RCC_IT_HSERDY,DISABLE);//HSE中断关闭
/* disable PLL Ready interrupt */
RCC_ITConfig(RCC_IT_HSIRDY, DISABLE); //HSI中断关闭
/* disable PLL Ready interrupt */
RCC_ITConfig(RCC_IT_LSERDY, DISABLE); //LSE中断关闭
/* disable PLL Ready interrupt */
RCC_ITConfig(RCC_IT_LSIRDY, DISABLE); //LSI中断关闭

/* PLL clock divided by 1.5 used as USB clock source */
RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5);//设置USB的时钟为=72、1.5=48mhz
/* Configure ADCCLK such as ADCCLK = PCLK2/2 */
RCC_ADCCLKConfig(RCC_PCLK2_Div2);//设置ADC时钟=PCLK2/2= 36MHZ
/* disable the LSE */
RCC_LSEConfig(RCC_LSE_OFF);//外部低速晶振关闭

/*DISable the RTC clock */
RCC_RTCCLKCmd(DISABLE);
/* DISable the Clock Security System */
RCC_ClockSecuritySystemCmd(DISABLE);
/* Enable the PLL */
RCC_PLLCmd(ENABLE);//使能PLL

int main(void)
{
mysysint();
  /* GPIOD Periph clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);//使能时钟
/* Configure PD0 and PD2 in output pushpull mode */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9| GPIO_Pin_10| GPIO_Pin_11;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOD, &GPIO_InitStructure);
  
  while (1)
  {
      /* Set PD0 and PD2 */
   /* Set the GPIOA port pin 10 and pin 15 */
  GPIO_SetBits(GPIOD, GPIO_Pin_11 | GPIO_Pin_8);//GPIOD->BSRR = 0x00000f00;//置为PD8-PD11
delay(0xfffff);
   /* Clears the GPIOA port pin 10 and pin 15 */
    GPIO_ResetBits(GPIOD, GPIO_Pin_11 | GPIO_Pin_8);//GPIOD->BRR  = 0x00000f00;

delay(0xfffff);
  
  }
}


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表