基于STM32F10x.3.5.0库的流水灯程序

来源:互联网 发布:软件专业毕业论文题目 编辑:程序博客网 时间:2024/06/11 21:53

2. 基于STM32F10x.3.5.0库的流水灯程序http://blog.csdn.net/zc1107473010/article/details/45095543

1.LED的管脚在GPIOA ~GPIOD中处于何种位置,从而确定要使能和配置的GPIO模块。

  这里可以通过查看原理图获得,如我的开发板就是PD2,PD3,PD4,PD7

 注意:采用库函数方式,下面这些地址以及寄存器功能初期只需要了解就行,但如果采用寄存器控制,就需要查询STM32中文/英文参考手册8.2,了解寄存器每位所代表意思,通过直接地址操作配置和控制。

#definePERIPH_BASE      ((u32)0x40000000)

#defineAPB2PERIPH_BASE (PERIPH_BASE + 0x10000)

#defineGPIOA_BASE       (APB2PERIPH_BASE + 0x0800)

#defineGPIOA             ((GPIO_TypeDef*) GPIOA_BASE)

以上用来定义GPIOx在外设定义中的地址。

//GPIO相关功能寄存器结构体

typedef struct

{

vu32CRL;  //端口配置寄存器低位

vu32CRH;  //端口配置寄存器高位

vu32IDR;  //端口输入数据寄存器

vu32ODR;  //端口输出数据寄存器

vu32BSRR; //端口位置位/复位寄存器

vu32BRR;  //端口位复位寄存器

vu32LCKR; //端口配置锁定寄存器

}GPIO_TypeDef; //声明GPIO标准功能寄存器

//GPIO复用功能寄存器结构体

typedef struct

{

vu32EVCR; //事件控制寄存器

vu32MAPR; //复用重映射和调试I/O配置寄存器

vu32EXTICR[4]; //外部中断线号0~15配置寄存器

} AFIO_TypeDef; //声明GPIO复用功能寄存器

通过查询了解,如配置PD7位为推挽输出,最大频率50MHZ,且管脚置1,

寄存器配置如下:

GPIOD->CRL &= ~(0x11 << 28);

GPIOD->BRR |= (0x01 << 7);

 

<LED端口的初始化>

2.使能需要的GPIO端口的外设时钟

   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,  ENABLE);

   其实在这之前还要配置系统时钟,以及端口所在总线区域也是在该芯片设计时已经固定的,这里知道GPIOD位于APB2总线即可,具体后面会在系统时钟章节继续深入讲解。

小知识:

    外设模块时钟使能一定在外设配置函数之前,这是因为修改对应端口的寄存器是通过触发器设置,触发器脉冲来自于外设时钟,因此要先根据总线时钟使能外设时钟,否则配置是无效的。

 

4.GPIO配置函数GPIO_Init(GPI0x, GPIO_IntTypeDef *GPIO_IntStruct)

  typedef struct

 {

u16 GPIO_Pin;                           //选中需要的GPI管脚

GPIOSPeed_Typedef   GPIO_SPeed;      //设定工作输出最大频率

GPIOSMODE_Typedef  GPIO_MODE;        //设定管脚工作方式

 }GPIO_IntTypeDef;

速率有三种,工作方式有8种, 如下定义即可完成管脚的配置:

GPIO_IntTypeDef *GPIO_IntStructure;

GPIO_IntStructure.GPIO_Pin = GPIO_Pin_2  | GPIO_Pin_3

                           | GPIO_Pin_4  | GPIO_Pin_7;

GPIO_IntStructure.GPIO_SPeed =GPIO_SPeed_50MHz;  //最大工作频率50MHZ

GPIO_IntStructure.GPIO_MODE =GPIO_Mode_Out_PP;   //设定选中管脚为推挽输出

GPIO_Init(GPIOD , &GPIO_IntStructure);             

 

<对配置好的GPIO口进行操作>

5.流水灯逻辑

这里主要用到两个函数

GPIO_SetBits(GPI0x, u16 GPIO_Pin);   /*对应GPIO端口置1*/

GPIO_ResetBits(GPI0x,u16 GPIO_Pin);  /*对应GPIO端口置0*/

这两个函数很好理解,这里就不多说了。那么就说下流水灯的逻辑。

LED1亮-〉延时->LED1灭-〉LED2亮-〉延时->LED2灭......如此循环就可以实现流水灯。

看到这是不是对流水灯的设计一目了然了呢,其实和传统的如51单片机中实现流水灯的逻辑几乎没什么区别,唯一的区别就是多了端口的配置,这是因为STM32芯片的管脚有8种不同的功能,当我们使用这些管脚,嵌入式芯片并不能直接判断管脚用途,而当我们告诉它之后,就和以前写51程序一样简单了。类似的程序可以写按键控制点亮对应led灯,控制蜂鸣器发声,这里我就不在说明,并没有太大区别。

 小知识:

GPIO的8种输入输出方式

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    复用推挽输出

这8种工作方式的区别

模拟输入  用于模拟量的输入,或者低功耗下省电。

下拉输入  GPIO端口内默认下拉电阻电路导通。初始为低电平,外部高电平动作。

上拉输入  GPIO端口内默认上拉电阻电路导通,初始为高电平,外部低电平动作。

浮空输入  GPIO端口内上下MOSFET均不导通,高阻态,输入状态仅由端口决定。

开漏输出  GPIO端口输出为0时内部下拉电阻电路接地,输出1时端口相当于悬空,即默认只能输出0,如果外部需要输出1,需要外接上拉电阻电路。

推挽输出  GPIO端口输出为0时内部下拉电阻电路接地,输出1时内部接上拉电阻电路,不需要外接上拉电阻电路即可输出0和1。

复用推挽输出 百度看到的超经典回答,因为不在是普通的I/O口所以复用,因为不需要外接上拉电阻所以推挽。例如串口的TX就为发送数据端口,即复用推挽输出。

复用开漏输出 具体解释同上,具体管脚复用功能配置要求可参考STM32中文参考手册8.1.11