使用stm32f103c8t6完成《嵌入式技术与基础 第六版》相关内容博客作业4 GPIO
零、 创新点
《嵌入式技术与基础 第六版》原书教材随书附赠了一块stm32L431的开发板,配套内容都是以此为基础打造的,甚至作者还专门为此开发了一套ide,但是:
- 现在stm32主流的教程生态用的都是stm32f103c8t6这款芯片,原书的教程虽然能很好的为你解释嵌入式开发的原理,但是要进一步学习,你还是不得不寻找其他教程,购买主流的开发板
- 作者的ide完全是出于本书学习设计的,对于实际开发毫无意义,若将来想做点嵌入式,还需要重新学习一套开发栈
- 全新套书卖100。作为抠门带血生,肯定要考虑二手的,但是二手书通常不会带有原书的附件。单买开发板,某宝60,某鱼甚至没有。起码截至我使用该书学习的时间(2024年3月)是这样的,后期使用此书的前辈多了,估计二手市场会变好。
- 最重要的是,我已经有一个stm32f103c8t6的开发板了
综上,无论是从学习角度还是省钱角度,使用stm32f103c8t6完成《嵌入式技术与基础 第六版》相关内容都是非常合适的
这套博客是广州大学计算机学院嵌入式系统课程的作业,我用stm32f103c8t6开荒,也是为了后来的同学做贡献
一、 底层原理
在程序上来说,arm内核通过对寄存器个别位的读写实现GPIO,每一位都有特殊的定义
GPIOx->CRL
示例
GPIOA->CRL&=0XFFFFFFF0;//其他位置为11,不启用其他引脚
GPIOA->CRL|=0X00000003;//0-3位为0011,意为启用输出且最大速度为50Mhz,且为推挽输出模式
GPIOx->CRH
这个寄存器和GPIOx->CRL大同小异,不同的是这个寄存器是设置高8位(8~15)端口的配置,不再赘述
GPIOx->IDR
示例
unsigned char a;
a=GPIOA->IDR&1<<0;//读取PA0的数值
GPIOx->ODR
示例
GPIOA->ODR|=1<<0;//设置PA0为1
GPIOA->ODR|=0<<0;//设置PA0为0
GPIOx_BSRR
示例
GPIOA->BSRR|=1<<0;//设置PA0为1
GPIOA->BSRR|=1<<16;//设置PA0为0
二、 寄存器编程初体验
写一个跑马灯的程序
/* USER CODE BEGIN WHILE */
RCC->APB2ENR |= (1 << 2); // 使能GPIOA端口的时钟
GPIOB->CRL &= 0X000FFFFF; // 清除GPIOB端口配置低寄存器(CRL)的高5位,为配置这些引脚做准备
GPIOB->CRL |= 0X33300000; // 配置为通用推挽输出模式
while (1)
{
// 绿灯
GPIOA->BSRR = 5;
HAL_Delay(500);
GPIOA->BRR = 5;
HAL_Delay(500);
// 黄灯
GPIOA->BSRR = 6;
HAL_Delay(500);
GPIOA->BRR = 6;
HAL_Delay(500);
// 红灯
GPIOA->BSRR = 7;
HAL_Delay(500);
GPIOA->BRR = 7;
HAL_Delay(500);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
三、 层层封装后的GPIO
通过读写寄存器进行操作的方式,不仅反人类,还缺乏可移植性,所以主流的stm32开发都是用标准库或hal库完成
标准库
GPIO_InitTypeDef GPIO_InitStructure; //定义一个GPIO_InitTypeDef类型的结构体变量
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //开启GPIOB的时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //选择要使用的I/O引脚,此处选择PB5引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置引脚输出模式为推挽输出模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置引脚的输出速度为50MHz
GPIO_Init(GPIOB,&GPIO_InitStructure); //调用初始化库函数初始化GPIOB端口
GPIO_WriteBit(GPIOB, GPIO_Pin_6, Bit_SET);
GPIO_WriteBit(GPIOB, GPIO_Pin_6, Bit_RESET);
HAL库
通过ide配置引脚初始化
HAL_GPIO_WritePin(LED_PORT, LED_PIN, GPIO_PIN_SET); // 设置引脚为高电平
HAL_GPIO_WritePin(LED_PORT, LED_PIN, GPIO_PIN_RESET); // 设置引脚为低电平
关于作者:
- 邮箱:luokairui@carry.fit
- 个人博客:carry blog
- CSDN主页:_:Carry-CSDN博客
- Github主页:C-a-r-r-y
欢迎联系!