对单片机上一个小灯进行操作
在kill软件空白处右键,如图,添加stm32头文件
#include "stm32f10x.h" // Device header
新建main()主函数进行程序主体的编写
1.首先开启外设时钟,添加代码块
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//开启GPIOC的外设时钟
在这里引入GPIO外设时钟的概念,什么是GPIO外设时钟?
以下为引用文段
GPIOC外设时钟是指用于控制GPIOC外设的时钟信号。在嵌入式系统中,GPIO(General Purpose Input/Output)是一种通用的输入/输出接口,用于与外部设备进行数据交互。每个GPIO引脚都需要一个时钟信号来控制其输入和输出操作。GPIOC外设时钟就是用来控制GPIOC外设的时钟信号。
GPIOC外设时钟的开启和关闭对于系统的功耗和性能都有一定的影响。如果一组GPIO引脚都没有被使用过,那么可以直接关闭该组GPIO的时钟信号以节省功耗。但是如果该组GPIO引脚中有被使用过的引脚,那么时钟信号不能关闭,需要将使用过的引脚配置为模拟输入以保持其状态。
需要注意的是,用于串口唤醒等特殊功能的引脚不能配置为模拟输入,也不能关闭其时钟信号。在进行GPIO初始化之前,建议先将GPIO进行复位操作,以确保其状态正确。
在低功耗模式下,进入STOP模式时,GPIO会保留原本的状态,因此可以将不需要保留状态的GPIO配置为模拟输入以节省功耗。而在进入SLEEP模式时,时钟信号并不会关闭,因此需要手动关闭时钟,并将开启后不再需要保留状态的GPIO配置为模拟输入。
总之,GPIOC外设时钟的配置和控制对于系统的功耗和性能优化非常重要,需要根据具体的应用场景和需求进行合理的配置和操作。
我找到了更简单的解释:
时钟是单片机的脉搏,时钟频率决定了单片机执行一条指令的时间,外设模块和我们的业务需求相关度大,其中GPIO,定时器,串口,spi,iic,usb是常见的外设模块
什么是GPIO
GPIO管脚:引脚图中的 PA、PB、PC、PD 等均属于 GPIO 引脚。从引脚图可以看出,GPIO 占用了 STM32 芯片大部分的引脚。并且每一个端口都有 16 个引脚,比如 PA 端口,它有 PA0-PA15。其他的 PB、PC 等端口是一样的。
关于GOPIO更详细些的介绍
我们这里用到了连着GPIO口的led,所以要开启GPIO外设时钟
2.调用函数配置寄存器
首先定义一个结构体,用于传递各项参数,包括寄存器模式,寄存器操作的引脚位置,和输出速度
GPIO_InitTypeDef GPIO_InitStructure;//给结构体命名
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //寄存器模式设置为通用推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; //寄存器引脚设置为13
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //输出速度设置为50MHz
然后才调用函数,来配置寄存器
GPIO_Init(GPIOC, &GPIO_InitStructure);
可以看到,函数调用时,引用了我们构造的结构体,所以结构体的定义一定要在调用结构体之前实现,
同时结构体的形式也有一定规定
点击选中函数,右键跳转定义
/**
* @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
*/
在其中,我们可以读到
GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that contains the configuration information for the specified GPIO peripheral.
GPIO_InitStruct这个结构体要包含GPIO的配置信息
该代码全文为
/**
* @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_Mode GPIO_Pin GPIO_Speed 的结构体成员名
3.对引脚进行操作
灭灯
GPIO_SetBits(GPIOC, GPIO_Pin_13); //将PC13设置为高电平,LED灭
或开灯
GPIO_ResetBits(GPIOC, GPIO_Pin_13); //将PC13设置为低电平,LED亮
最后设置一个while(1)死循环就完成程序了
完全体如上