历史上的今天
今天是:2024年12月03日(星期二)
2021年12月03日 | STM32 LED跑马灯-库函数
2021-12-03 来源:eefocus
一,GPIO知识回顾
1,四种输入模式:
输入浮空
输入上拉
输入下拉
模拟输入
2,四种输出模式:
开漏输出
开漏复用输出
推挽输出
推挽复用输出
3,三种最大输出速度
2MHz
10MHz
50MHz
每组GPIO共16个IO口,含下7个寄存器
GPIOx_CRL : 端口配置低寄存器
GPIOx_CRH : 端口配置高寄存器
GPIOx_IDR : 端口输入寄存器
GPIOx_ODR : 端口输出寄存器
GPIOx_BSRR : 端口位设置/清除寄存器
GPIOx_BRR : 端口位清除寄存器
GPIOx_LCKR : 端口配置锁存寄存器
二,LED硬件连接:

LED0连接PB5引脚
LED1连接PE5引脚
三,LED跑马灯实现流程
1,使能GPIO时钟
使用IO口前先要使能相应的GPIO时钟
2,初始化IO口 GPIO_Init()
配置IO口的引脚工作方式(最大速度,输入/输出模式)
3,操作IO口输出高低电平
控制响应IO口输出高电平或低电平
四,源码分析
1,GPIO初始化函数
stm32f10x_gpio.h头文件中找到GPIO_Init函数声明
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
1
stm32f10x_gpio.c中找到GPIO_Init函数的实现
/**
* @brief Initializes the GPIOx peripheral according to the specified
* parameters in the GPIO_InitStruct.
* @param GPIOx: where x can be (A..G) to select the GPIO peripheral.
* @param GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that
* contains the configuration information for the specified GPIO peripheral.
* @retval None
*/
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
{
uint32_t currentmode = 0x00, currentpin = 0x00, pinpos = 0x00, pos = 0x00;
uint32_t tmpreg = 0x00, pinmask = 0x00;
/* Check the parameters */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode));
assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin));
/*---------------------------- GPIO Mode Configuration -----------------------*/
currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F);
if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x10)) != 0x00)
{
/* Check the parameters */
assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed));
/* Output mode */
currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed;
}
/*---------------------------- GPIO CRL Configuration ------------------------*/
/* Configure the eight low port pins */
if (((uint32_t)GPIO_InitStruct->GPIO_Pin & ((uint32_t)0x00FF)) != 0x00)
{
tmpreg = GPIOx->CRL;
for (pinpos = 0x00; pinpos < 0x08; pinpos++)
{
pos = ((uint32_t)0x01) << pinpos;
/* Get the port pins position */
currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
if (currentpin == pos)
{
pos = pinpos << 2;
/* Clear the corresponding low control register bits */
pinmask = ((uint32_t)0x0F) << pos;
tmpreg &= ~pinmask;
/* Write the mode configuration in the corresponding bits */
tmpreg |= (currentmode << pos);
/* Reset the corresponding ODR bit */
if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
{
GPIOx->BRR = (((uint32_t)0x01) << pinpos);
}
else
{
/* Set the corresponding ODR bit */
if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
{
GPIOx->BSRR = (((uint32_t)0x01) << pinpos);
}
}
}
}
GPIOx->CRL = tmpreg;
}
/*---------------------------- GPIO CRH Configuration ------------------------*/
/* Configure the eight high port pins */
if (GPIO_InitStruct->GPIO_Pin > 0x00FF)
{
tmpreg = GPIOx->CRH;
for (pinpos = 0x00; pinpos < 0x08; pinpos++)
{
pos = (((uint32_t)0x01) << (pinpos + 0x08));
/* Get the port pins position */
currentpin = ((GPIO_InitStruct->GPIO_Pin) & pos);
if (currentpin == pos)
{
pos = pinpos << 2;
/* Clear the corresponding high control register bits */
pinmask = ((uint32_t)0x0F) << pos;
tmpreg &= ~pinmask;
/* Write the mode configuration in the corresponding bits */
tmpreg |= (currentmode << pos);
/* Reset the corresponding ODR bit */
if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
{
GPIOx->BRR = (((uint32_t)0x01) << (pinpos + 0x08));
}
/* Set the corresponding ODR bit */
if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
{
GPIOx->BSRR = (((uint32_t)0x01) << (pinpos + 0x08));
}
}
}
GPIOx->CRH = tmpreg;
}
}
GPIO_Init函数两个入参为GPIO_TypeDef和GPIO_InitTypeDef两个结构体指针
GPIO_TypeDef参数:
stm32f10x.h中找到GPIO_TypeDef结构体声明
/**
* @brief General Purpose I/O
* 定义了GPIO的7个寄存器
*/
typedef struct
{
__IO uint32_t CRL; // 端口配置低寄存器
__IO uint32_t CRH; // 端口配置高寄存器
__IO uint32_t IDR; // 端口输入寄存器
__IO uint32_t ODR; // 端口输出寄存器
__IO uint32_t BSRR; // 端口位设置/清除寄存器
__IO uint32_t BRR; // 端口位清除寄存器
__IO uint32_t LCKR; // 端口配置锁存寄存器
} GPIO_TypeDef;
GPIO_TypeDef有效性判断:
/** @defgroup GPIO_Exported_Types
* GPIOA->GPIOG
*/
#define IS_GPIO_ALL_PERIPH(PERIPH) (((PERIPH) == GPIOA) ||
((PERIPH) == GPIOB) ||
((PERIPH) == GPIOC) ||
((PERIPH) == GPIOD) ||
((PERIPH) == GPIOE) ||
((PERIPH) == GPIOF) ||
((PERIPH) == GPIOG))
GPIO_InitTypeDef参数:
stm32f10x_gpio.h中找到GPIO_InitTypeDef结构体声明
/**
* @brief GPIO Init structure definition
* GPIO_InitTypeDef结构体-设置IO口,速度,工作模式
*/
typedef struct
{
uint16_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured.
This parameter can be any value of @ref GPIO_pins_define */
GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins.
This parameter can be a value of @ref GPIOSpeed_TypeDef */
GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins.
This parameter can be a value of @ref GPIOMode_TypeDef */
}GPIO_InitTypeDef;
GPIO_InitStruct->GPIO_Speed有效性校验
/**
* @brief Output Maximum frequency selection
*/
typedef enum
{
GPIO_Speed_10MHz = 1,
GPIO_Speed_2MHz,
GPIO_Speed_50MHz
}GPIOSpeed_TypeDef;
#define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_Speed_10MHz) || ((SPEED) == GPIO_Speed_2MHz) ||
((SPEED) == GPIO_Speed_50MHz))
GPIO_InitStruct->GPIO_Mode有效性校验
/**
* @brief Configuration Mode enumeration
* 八种输入/输出模式
*/
typedef enum
{ GPIO_Mode_AIN = 0x0, // 模拟输入
GPIO_Mode_IN_FLOATING = 0x04, // 浮空输入
GPIO_Mode_IPD = 0x28, // 下拉输入
GPIO_Mode_IPU = 0x48, // 上拉输入
GPIO_Mode_Out_OD = 0x14, // 开漏输出
GPIO_Mode_Out_PP = 0x10, // 推挽输出
GPIO_Mode_AF_OD = 0x1C, // 复用开漏输出
GPIO_Mode_AF_PP = 0x18 // 复用推挽输出
}GPIOMode_TypeDef;
#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Mode_AIN) ||
((MODE) == GPIO_Mode_IN_FLOATING) ||
((MODE) == GPIO_Mode_IPD) ||
((MODE) == GPIO_Mode_IPU) ||
((MODE) == GPIO_Mode_Out_PP) ||
((MODE) == GPIO_Mode_AF_OD) ||
((MODE) == GPIO_Mode_AF_PP))
GPIO_InitStruct->GPIO_Pin有效性校验
/** @defgroup GPIO_pins_define
* GPIO_Pin_0->GPIO_Pin_15
*/
#define GPIO_Pin_0 ((uint16_t)0x0001) /*!< Pin 0 selected */
上一篇:新建工程模板-库函数
史海拾趣
|
西门子PLCS7200系列,当PLC断电处于RUN状态时,此时若PLC通电,则PLC会自动运行,这种情况可能会造成设备的损坏甚至现场人员的伤亡,所以应加以处理, 利用特殊位继电器SM0.3可以避免这种情况的发生, … 查看全部问答> |
|
2、书写Debug版和Release版的程序 ---------------- 程序在开发过程中必然有许多程序员加的调试信息。我见过许多项目组,当程序开发结束时,发动群众删除程序中的调试信息,何必呢?为什么不像VC++那样建立两个版本的目标代码?一个是debug版本的 ...… 查看全部问答> |
|
如下图: 这是BGA布线规则中的图,VIA 分别朝左上、左下、右上、右下方向打,但是为什么在内部打不了过孔啊?还有就是只要修改一个过孔的尺寸,整个的过孔都改了,这怎么回事啊? [ 本帖最后由 静若幽兰 于 2010-5-14 18:13 编辑 ]… 查看全部问答> |
|
[笔记].在Quartus II中使用JTAG模式固化程序到EPCS中的方法.[Quartus II] 范例 流水灯 图1 流水灯范例 实现步骤 步骤1: 在Quartus II中,单击File->Convert Programming Files..。打开编程文件转换程序,如图2所示。 图2 编程文件转换程序界面 在此界面中。在Programming file&nb ...… 查看全部问答> |
|
ZLG/FS文件系统读SD卡数据的OSFileRead函数怎么用 uint32 OSFileRead(void *Buf, uint32 Size, HANDLE Handle); Buf是保存读到的数据的指针,size是要读的字节数,Handle是文件句柄,返回值是实际读到的字节数。 我是这样用的: char *FileNameRead = \"A:\\\\toRead.txt\"; char ReadFileDat ...… 查看全部问答> |
|
115200下,PC端给PDA发送数据,每100ms发送530bytes,有时会有数据丢失。 调用ClearCommError发现输入缓冲区中才60多个bytes,肯定还没满,状态返回CE_OVERRUN,硬件溢出了,天。有没有别的办法,除了改驱动,加流控。 读写我是有单独线程来完成 ...… 查看全部问答> |
|
STM32的启动方式了解 但是对其的调试方式和储存介质一直糊涂 目前知道 调试可以在 片内的FLASH 和 RAM来进行,不知我用FSMC外挂的SRAM 可以不? 我将一段代码COPY到外部SRAM ,然后跳过去,没好使,不知是跳的问题 还是跳过去不能运行? ...… 查看全部问答> |




