stm32gpio寄存器小小心得

寄存器配置io口的时候,一开始总会有很多的疑问。虽然看了某些教程,但是有些东西还是似懂非懂的状态。所以带着深入理解的态度,我再次重温了gpio的配置。
对于STM32F1的IO可以配置成8种模式,三种最大输出速度。也就是每组IO口有7个寄存器,也就是说7个寄存器可以控制一组16个IO口。
这个7个寄存器分别是:
位配置寄存器,主要是:模式的选择以及输出速度的选择。
GPIOx_CRL
GPIOx_CRH
数据寄存器,主要是:一个是输入数据寄存器。一个是输出数据寄存器。
GPIOx_IDR
GPIOx_ODR
一个32位置位/复位数据寄存器
GPIOx_BSRR
一个16位复位寄存器
GPIOx_BRR
一个32位锁存器
GPIOx_LCKR
假设:PB5和PE5和外部的LED相连。通过配置相应的寄存器来驱动LED灯。
寄存器版本步骤是三部:
第一步:使能IO端口时钟。
在配置 STM32 外设的时候,任何时候都要先使能该外设的时钟。 GPIO 是挂载在 APB2 总线上的外设,相应的寄存器是:APB2 外设时钟使能寄存器(RCC_APB2ENR)
GPIOB与GPIOE是在寄存器:RCC_APB2ENR的第三位和第六位。我们只需要把相应的位设置为1即可。
相应的寄存器

通过查找相应的寄存器使能GPIOB。
RCC->APB2ENR |= 1<<3 ; //一般情况下我们不直接赋值,主要是为了保持其他位不变。
同样我们可以使能GPIOE:RCC->APB2ENR |= 1<<6;

第二步:初始化IO口模式
在使能了相应的端口以后,我们需需要设置相应的IO口模式。配置模式有2个32位的寄存器CRL和CRH。GPIOB与GPIOE都是低八位,因此只需要我们配置寄存器CRL。
每个IO口需要配置4位,低两位输出模式选择,高两位是配置模式。
配置io模式以及输出速度对应的寄存器的各位
选择模式:输出模式,最大速度50MHZ。复用推挽输出。
程序可以写成:
在我们设置相应的位之前,我们先把要设置的位清零。(利用和1相与不变,和0相与清零)
GPIOB->CRL &=0xFF0FFFFF;
然后选择模式:
GPIOB->CRL |=0x00300000; //PB5的工作模式
模式配置详细图
这里我开始有很大的疑惑,后来总结了一下:配置模式先看MODEy[1:0]位,它先决定是输出还是输入模式;其次再看CNFy[1:0]位来决定io口是什么类型记得输入或者输出。
模式配置
初始化我们设置输出为1,通过寄存器ODR设置。
GPIOB->ODR |= 1<<5; //移位操作应该很简单的
同样可以设置GPIOE的模式以及PE5的状态。
GPIOE->CRL &=0xFF0FFFFF;
GPIOE->CRL |= 0x00300000; //PE5的工作模式
GPIOE->ODR |= 1<<5;
第三步骤:操作IO口
操作寄存器ODR或者寄存器BRR/BSRR.
通过配置PB5和PE5相应输出寄存器ODR的位置位或者清零。
GPIOE->ODR |= 1<<5;
调用延时函数delay;
GPIOB->ODR &= ~(1<<5);

或者配置寄存器BRR/BSRR.
通过BSRR的低16位置1,
GPIOB->BSRR |= 1<<5;
调用延时函数delay;
通过BSRR的低16位置0,
GPIOB->BRR |= 1<<5;
下面贴出初始化oled屏的代码以及部分注释: void OLED_Init(void)
{

RCC->APB2ENR|=1<<3;    //使能PORTB时钟       
GPIOB->CRL&=0XFFF0FFFF; //清零
GPIOB->CRL|=0X00020000;//PB4 推挽输出   

RCC->APB2ENR|=1<<4; //使能PORTC时钟
RCC->APB2ENR|=1<<0; //使能AFIO时钟
GPIOC->CRH&=0X000FFFFF; //PC13,14,15设置成输出 2MHz 推挽输出
GPIOC->CRH|=0X22200000;
PWR->CR|=1<<8; //取消备份区写保护
RCC->BDCR&=0xFFFFFFFE; //外部低俗振荡器关闭 PC14,PC15成为普通IO
BKP->CR&=0xFFFFFFFE; //侵入检测TAMPER引脚作为通用IO口使用
PWR->CR&=0xFFFFFEFF; //备份区写保护

OLED_RST_Clr();
delay_ms(100);
OLED_RST_Set(); 

OLED_WR_Byte(0xAE,OLED_CMD); //关闭显示
OLED_WR_Byte(0xD5,OLED_CMD); //设置时钟分频因子,震荡频率
OLED_WR_Byte(80,OLED_CMD);   //[3:0],分频因子;[7:4],震荡频率
OLED_WR_Byte(0xA8,OLED_CMD); //设置驱动路数
OLED_WR_Byte(0X3F,OLED_CMD); //默认0X3F(1/64) 
OLED_WR_Byte(0xD3,OLED_CMD); //设置显示偏移
OLED_WR_Byte(0X00,OLED_CMD); //默认为0

OLED_WR_Byte(0x40,OLED_CMD); //设置显示开始行 [5:0],行数.

OLED_WR_Byte(0x8D,OLED_CMD); //电荷泵设置
OLED_WR_Byte(0x14,OLED_CMD); //bit2,开启/关闭
OLED_WR_Byte(0x20,OLED_CMD); //设置内存地址模式
OLED_WR_Byte(0x02,OLED_CMD); //[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10;
OLED_WR_Byte(0xA1,OLED_CMD); //段重定义设置,bit0:0,0->0;1,0->127;
OLED_WR_Byte(0xC0,OLED_CMD); //设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数
OLED_WR_Byte(0xDA,OLED_CMD); //设置COM硬件引脚配置
OLED_WR_Byte(0x12,OLED_CMD); //[5:4]配置

OLED_WR_Byte(0x81,OLED_CMD); //对比度设置
OLED_WR_Byte(0xEF,OLED_CMD); //1~255;默认0X7F (亮度设置,越大越亮)
OLED_WR_Byte(0xD9,OLED_CMD); //设置预充电周期
OLED_WR_Byte(0xf1,OLED_CMD); //[3:0],PHASE 1;[7:4],PHASE 2;
OLED_WR_Byte(0xDB,OLED_CMD); //设置VCOMH 电压倍率
OLED_WR_Byte(0x30,OLED_CMD); //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;

OLED_WR_Byte(0xA4,OLED_CMD); //全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)
OLED_WR_Byte(0xA6,OLED_CMD); //设置显示方式;bit0:1,反相显示;0,正常显示                                   
OLED_WR_Byte(0xAF,OLED_CMD); //开启显示  
OLED_Clear();

}

2017/4/21

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值