1. 时钟系统
为什么要有时钟系统?
- 为了统一管理,比如单片机内部外设比如GPIO、TIM等等统一口号
- 为了节能,现在芯片越来越注重低功耗,因此在一个单片机系统中如果希望某些器件工作快一点就把它的频率设置高一点,反之就设置低一点。
1.1 时钟树图
数据手册
1.2 配置时钟
使用CUBEMAX配置时钟可视化非常方便,值得注意的是,这里的时钟初始化配置的只是总线上的时钟,外设的时钟并没有打开,当我们使用对应的外设的时候还需要打开对应外设的时钟。
2. GPIO
2.1 GPIO模式
-
推挽输出 这个模式提高反应速度,当输出控制输出高电平时,PMOS导通,I/O口高电平。当输出控制低电平的时候,NMOS导通,I/O锁定在低电平。 -
开漏输出 这个好处一是可以提高I/O的驱动外部负载的能力,二是可以实现电平的转换 -
复用推挽输出 -
输入上拉模式 这个模式用于比如读取外部按键的电平,如果没有这个上拉电阻电平就会不稳定,这个上拉电阻就会稳定的高电平。 -
输入下拉模式 -
输入模拟模式 绕过肖特基二极管(整理波形的作用),直接读取I/O口电平。 -
输入复用模式
代码
GPIO初始化
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
执行任务
while (1)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
HAL_Delay(5000);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
HAL_Delay(5000);
if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0))
{
HAL_Delay(10);
if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0))
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
}
else
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
}
}
}
这里任务1和任务2时间上会有冲突,因为这是一个死循环,当执行1的时候就执行不了2.这就是单片机轮询的缺点,可能和其他任务冲突,优点是简单,新手也可以看懂。
|