长沙 网站优化,个人域名免费网站,网站建设品牌公司哪家好,网络直播平台在开始之前记得先准备好环境#xff1a;
STM32F103核心板下载教程.pdf 林何/STM32F103C8 - 码云 - 开源中国 (gitee.com) 一、STM32的GPIO模块数据手册详解 每个GPIO端口对应16个引脚#xff0c;例GPIOA#xff08;PA0~PA15#xff09;内核cpu就可以通过APB2总线对寄存器… 在开始之前记得先准备好环境
STM32F103核心板下载教程.pdf · 林何/STM32F103C8 - 码云 - 开源中国 (gitee.com) 一、STM32的GPIO模块数据手册详解 每个GPIO端口对应16个引脚例GPIOAPA0~PA15内核cpu就可以通过APB2总线对寄存器读写完成输出电平和读取电平的功能 1.GPIO和APIO GPIO通用输入/输出IO APIO备用输入/输出IO 2.GPIO功能描述 3.配置模式
【STM32】GPIO工作原理八种工作方式超详细分析附电路图-CSDN博客
1.输入浮动输入上拉输入下拉数字状态 都是数字模式数字IO只关心电平是1还是0 输入浮空:就是当电平输入进来后直接输入到寄存器中【不对其进行操作】 输入上拉在内部有一个上拉电阻将电平拉高只能外部接地才能将电平拉低如果TTL肖特基触发器输入的是高电平或者干扰信号则会将其过滤调。 2.模拟输入模拟状态 AD转换 可以工作在模拟电路或者数字电路 3.输出 开漏输出 推挽输出 4.备用 将不用的引脚配置成备用引脚GPIO才可以被使用 4.输出字节数控制 1输出32位字使用GPIO_CRL---效率低但是兼容性好 2输入小于32位字使用CPIOx_BSRR--效率高但是兼容性差 5.I/O 端口位框图 6.端口位配置表 7.输出模式位 8.外部中断/唤醒线 将IO口和相对应的中断映射起来 9.GPIO寄存器描述
1. 端口配置低寄存器(GPIOx_CRL) 由于每个GPIO口需要4位来进行配置输入输出模式2位配置MODE2位配置CNF这样的话每组16个GPIO口则需要64位这也就表明需要两个32位寄存器。于是GPIOx_CRL用于配置GPIO0-GPIO7的输入输出模式。同理GPIOx_CRH则用于配置GPIO8-GPIO15的输入输出模式。 控制PX0---PX7引脚工作模式 四个位控制一个引脚 2. 端口配置高寄存器(GPIOx_CRH) 控制PX8---PX15引脚工作模式 3.端口输入数据寄存器(GPIOx_IDR) 4. 端口输出数据寄存器(GPIOx_ODR) 5. 端口位设置/复位寄存器(GPIOx_BSRR) 如果想要将bit7和bit6置为0则表示要将bit7和bit6写为1其他位置为0 对复位上写1表示复位 对置位上写1表示置为 如果置位和复位同时设置则置位起作用。 6.端口位复位寄存器(GPIOx_BRR) 7.端口配置锁定寄存器(GPIOx_LCKR) 8.复用功能I/O和调试配置(AFIO) 二、原理图分析
1.硬件接线 1杜邦线连接到P0端口到LCD的J19接口这样相当于8个LED分别对应PB8-PB15 2因为GPIO接到LCD的负极所以输入0亮输入1暗 三、MDK工程建立 与前面51建立工程是一样的 1.注意点1 2.注意点2 单片机中用到的c语言其实不是原始c语言而是有点定制性c语言 之前认识整个程序从main函数开始执行main执行完整个程序就结束 起始代码从CPU复位开始执行的第一句指令到main函数之前所做的事情就是起始代码 3.起始代码 1起始代码是从哪里来的编译环境提高的STM32CPU提供的 2不同CPU的起始代码一般是不同的 3起始代码是用汇编写的 四、写代码控制GPIO点亮和熄灭
1.寄存器现象确认 我们使用的是P0端口对应PB8-PB15所以我们要去对应查找PB的寄存器起始地址 1STM32 PortB的起始是0x4001 0c00 2.有可能使用到的GPIO的地址 因为我们是PB8-PB15所以我们只使用CRH 3.C语言操作寄存器 1ARM是内存与IO统一编址的所以ARM中的所有外设都是通过寄存器的方式来操作的 2每一个寄存器都有地址c语言通过这些地址来操作这些寄存器位用到的c语言的技巧主要是c与的位操作和c语言指针 3常见面试题用c语言向内存地址0x3000 0004写入16 *unsigned int *0x3000 000416 等价于 unsigned int *p(unsigned int *)0x3000 0004 *p16; 4.解析寄存器
1.端口配置高寄存器(GPIOx_CRH)-高8位 //向CRH寄存器写内容将GPIO_GPB15配置为输出模式【此时高位有用】//推挽输出模式输出的速率为50MHZ【0011 0011 0011 0011.。。】*((unsigned int *)GPIOB_CRH)0x33333333;//表示将GPIO_CRH的值设置为0x33333333 2.端口输出数据寄存器(GPIOx_ODR) //向CRH寄存器写内容将GPIO_GPB15配置为输出模式【此时高位有用】//推挽输出模式输出的速率为50MHZ【0011 0011 0011 0011.。。】*((unsigned int *)GPIOB_CRH)0x33333333;//表示将GPIO_CRH的值设置为0x33333333 5.注意点 记得在操作GPIO的时候要先打开时钟 #define GPIOB_CRH 0x40010C04
#define GPIOB_ODR 0x40010C0C#define RCC_APB2ENR 0x40021018void main(void){//STM32所有外设默认关闭//所以我们在打开时钟*((unsigned int *)RCC_APB2ENR)0x00000008;//向CRH寄存器写内容将GPIO_GPB15配置为输出模式//推挽输出模式输出的速率为50MHZ【0011 0011 0011 0011.。。】*((unsigned int *)GPIOB_CRH)0x33333333;//表示将GPIO_CRH的值设置为0x33333333//输出1点亮LED//ff对应15-8位*((unsigned int *)GPIOB_ODR)0x0000f000;while(1);}五、其他寄存器的测试
1.端口位设置/清除寄存器(GPIOx_BSRR) 将bit8-bit15置0变亮因为我们前面是使用了GPIO_GRH所以只能控制8-15个引脚所以此时改变0-7是无效的 //使用寄存器【GPIOB_BSRR】将bit8-bit15置0此时表示全亮 //*((unsigned int *)GPIOB_BSRR)0x00000000;//因为前面我们是控制GPIOB_CRH所以只有8-15位才起效果0-7无论设置什么都无所谓//*((unsigned int *)GPIOB_BSRR)0x000000ff;//此时全亮,与上面效果一样//0101 0101//*((unsigned int *)GPIOB_BSRR)0x00005500;//此时2,4,6,8亮//此时led1led3不亮其他亮//使用置位*((unsigned int *)GPIOB_BSRR)0x00005500;//此时2,4,6,8亮//使用复位将高4位全部复位*((unsigned int *)GPIOB_BSRR)0xf0000000;
2.端口位清除寄存器(GPIOx_BRR) 只能操作bit0-bit15 BRR只能用来复位不能置位所以只能将其置为0而不能置为1 //使用寄存器【GPIOB_BRR】将bit8-bit15置0此时表示全亮 //GPIOB_BRR:只能进行复位意思是只能将电平置为0//前面16-32是无效位*((unsigned int *)GPIOB_BRR)0x00000000;//全亮*((unsigned int *)GPIOB_BRR)0x0000ffff;//全亮//*((unsigned int *)GPIOB_BRR)0x0000ff00;//只亮高4位led的4-7
六、总结 对数据操作的三种方法 ODR可以进行任何操作但是只能一次性操作32位效率低但是移植性高【其次考虑】 BSRR原子操作效率高移植性差【优先考虑】 BRR只能进行复位不能置位原子操作效率高移植性差 1.代码
#define GPIOB_CRH 0x40010C04
#define GPIOB_CRL 0x40010C00
#define GPIOB_ODR 0x40010C0C
#define GPIOB_BSRR 0x40010C10
#define GPIOB_BRR 0x40010C14#define RCC_APB2ENR 0x40021018void main(void){//STM32所有外设默认关闭//所以我们在打开时钟*((unsigned int *)RCC_APB2ENR)0x00000008;//向CRH寄存器写内容将GPIO_GPB15配置为输出模式【此时高位有用】//推挽输出模式输出的速率为50MHZ【0011 0011 0011 0011.。。】*((unsigned int *)GPIOB_CRH)0x33333333;//表示将GPIO_CRH的值设置为0x33333333//输出0点亮LED//ff对应15-8位//*((unsigned int *)GPIOB_ODR)0x00000000;//使用寄存器【GPIOB_BSRR】将bit8-bit15置0此时表示全亮 //*((unsigned int *)GPIOB_BSRR)0x00000000;//因为前面我们是控制GPIOB_CRH所以只有8-15位才起效果0-7无论设置什么都无所谓//*((unsigned int *)GPIOB_BSRR)0x000000ff;//此时全亮,与上面效果一样//0101 0101//*((unsigned int *)GPIOB_BSRR)0x00005500;//此时2,4,6,8亮//此时led1led3不亮其他亮//使用置位//*((unsigned int *)GPIOB_BSRR)0x00005500;//此时2,4,6,8亮//使用复位将高4位全部复位//*((unsigned int *)GPIOB_BSRR)0xf0000000;//使用寄存器【GPIOB_BRR】将bit8-bit15置0此时表示全亮 //GPIOB_BRR:只能进行复位意思是只能将电平置为0//前面16-32是无效位*((unsigned int *)GPIOB_BRR)0x00000000;//全亮*((unsigned int *)GPIOB_BRR)0x0000ffff;//全亮//*((unsigned int *)GPIOB_BRR)0x0000ff00;//只亮高4位led的4-7while(1);}2.对宏定义的封装 #define GPIOB_CRH 0x40010C04
#define GPIOB_CRL 0x40010C00
#define GPIOB_ODR 0x40010C0C
#define GPIOB_BSRR 0x40010C10
#define GPIOB_BRR 0x40010C14#define RCC_APB2ENR 0x40021018#define rGPIOB_CRH (*((unsigned int *)GPIOB_CRH))
#define rGPIOB_ODR (*((unsigned int *)GPIOB_ODR))
#define rGPIOB_BSRR (*((unsigned int *)GPIOB_BSRR))
#define rGPIOB_BRR (*((unsigned int *)GPIOB_BRR))
#define rRCC_APB2ENR (*((unsigned int *)RCC_APB2ENR))void main(void){rRCC_APB2ENR 0x00000008;rGPIOB_CRH 0x33333333;rGPIOB_ODR 0x0000aa00;
}