1,365
社区成员
发帖
与我相关
我的任务
分享目录
•STM32是ST公司基于ARM Cortex-M内核开发的32位微控制器
•STM32常应用在嵌入式领域,如智能车、无人机、机器人、无线通信、物联网、工业控制、娱乐电子产品等
•STM32功能强大、性能优异、片上资源丰富、功耗低,是一款经典的嵌入式微控制器
•ARM既指ARM公司,也指ARM处理器内核
•ARM公司是全球领先的半导体知识产权(IP)提供商,全世界超过95%的智能手机和平板电脑都采用ARM架构
•ARM公司设计ARM内核,半导体厂商完善内核周边电路并生产芯片


可以看出芯片上的外设非常多,那怎么使用这些外设就成了头疼的问题,所以ST公司就提供了丰富的库函数,接下来简单说一下如何使用从零使用这些库函数
•GPIO(General Purpose Input Output)通用输入输出口
•可配置为8种输入输出模式
•引脚电平:0V~3.3V,部分引脚可容忍5V
•输出模式下可控制端口输出高低电平,用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等
•输入模式下可读取端口的高低电平或电压,用于读取按键输入、外接模块电平信号输入、ADC电压采集、模拟通信协议接收数据等

可以看到使用GPIO口首先要开启APB2外设时钟 ,再配置GPIO口使用一长串看不懂 ,不要急,一步一步考来
当我们按照网上的教程创建了一个工程文件却有

1.首先要打开外设的是时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //打开外设时钟
这里打开的就是GPIOB口的外设时钟
这行代码就是从找到的

可以打开stm32fl10x_rcc.h中划到最终下面

void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
然后快速找到需要的函数即可右键跳转到函数的定义查看他 参数是什么

知道参数和用法之后就可以开启GPIOB的外设时钟了
第一个参数就是选择要使用的外设
第二个参数就是选择使能
接下来就是初始化GPIOB的某个引脚口,这里选择的是PB5这个引脚
//创建结构体变量
GPIO_InitTypeDef GPIO_InitStructure;
//设置为推挽输出模式
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
//选择由于要使用 PB5引脚口,所以配置Pin5作为输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 ;
//选择 输出速度为50MHZ
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//最后将参数填进去初始化
GPIO_Init(GPIOB, &GPIO_InitStructure);
打开atm32f10x.gpio.h找我们需要的函数

需要的是
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
来初始化GPIO口,接下来跳转定义查看参数如何使用
英文翻译之后得知
第一个参数是要初始化的GPIOX口
第二个参数是一个结构体变量 用于设置工作模式,引脚口和输出速度
在得知之后便可以配置引脚口了
void LED_Init(void)
{
//打开外设时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
//创建结构体变量
GPIO_InitTypeDef GPIO_InitStructure;
//设置为推挽输出模式
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
//选择由于要使用 PB5引脚口,所以配置Pin5作为输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 ;
//选择 输出速度为50MHZ
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//最后将参数填进去初始化
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
配置完成后就 可以使用PB5这个引脚口了
可以使用官方提供的函数来拉低拉高引脚的高低电平,当然官方还提高拱了很多类似的函数不一一介绍
void LED1_ON(void)
{
GPIO_ResetBits(GPIOB, GPIO_Pin_5);// 拉低引脚输出电平
}
void LED1_OFF(void)
{
GPIO_SetBits(GPIOB, GPIO_Pin_5); //拉高引脚输出电平
}
到这里就基本配置完毕了
在介绍一下GPIO口的工作模式

大家看看就行,不一一介绍了

void Key_Init(void)
{
//打开GPIO和AFIO的外设时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//初始化GPIO_Pin_15口
GPIO_InitTypeDef GPIO_InitStructure;//创立参数结构体
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //选择工作模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15 ; //选择GPIO引脚接口
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //选择输出速度
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIO口
//初始化EXTI
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource15);//用于配置EXIT外部中断/事件的GPIO中断源,传入的参数是GPIO和相应的IO口
EXTI_InitTypeDef EXTI_InitStructure; //创立参数结构体
EXTI_InitStructure.EXTI_Line = EXTI_Line15; //将EXTI的第15个线路配置为中断模式
EXTI_InitStructure.EXTI_LineCmd =ENABLE ; //开启中断
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt ;// EXTI_Mode_Interrupt选择中断模式 EXTI_Mode_Event选择事件模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
EXTI_Init(&EXTI_InitStructure);//初始化EXTI
//初始化NVIC
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //选择优先级
NVIC_InitTypeDef NVIC_InitStructure; //创立参数结构体
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;//选择通道
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //选择指定通道使能(打开通道)
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =1 ;//抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //响应优先级
NVIC_Init(&NVIC_InitStructure);
}
void EXTI15_10_IRQHandler(void)//中断程序
{
if(EXTI_GetITStatus(EXTI_Line15) == SET)//由于中断源10到中断源15都能进入本中断函数,所以要判断是否是自己想要的中断源
{
EXTI_ClearITPendingBit(EXTI_Line15);//清楚标志位
}
}

/****************************************************************************
* 名 称:void Timer2_Init(void)
* 功 能:初始化定时器2
* 入口参数:无
* 出口参数:无
* 说 明:将定时器2以每次300ms的时间触发中断程序
* 调用方法:无
****************************************************************************/
void Timer2_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //打开外设时钟
TIM_InternalClockConfig(TIM2);//打开选择内部时钟作为输出源
//初始化时基单元
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1 ; //时钟分频模式(滤波),但是采用内部时钟采样型号稳定配不配这个没关系
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//选择定时器计数模式,选择向上计数
TIM_TimeBaseInitStructure.TIM_Period = 3000-1; //ARR自动重装其的值
TIM_TimeBaseInitStructure.TIM_Prescaler = 7200-1;//PSC预分频器的值
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重复计数器 当计时器溢出x次时才执行中断
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//打开TIM2的更行中断
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //选择优先级
NVIC_InitTypeDef NVIC_InitStructure; //创立参数结构体
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;//选择通道
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //选择指定通道使能(打开通道)
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =2 ;//抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //响应优先级
NVIC_Init(&NVIC_InitStructure);
}
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
{
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
}