stm32点亮一个灯的6种方式:

 本代码在正点原子ministm32 实现,闪亮PD2:

总体来说分两种:

1 通过控制三个寄存器实现,ODR,BRR,BSRR

位带地址写0/1实现

操作方式寄存器封装函数
寄存器ODRGPIO_WriteBit
BRRGPIO_ResetBits
BSRRGPIO_SetBits
位带地址如(*((u32*)0x42228188))=0

 void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_PIN(GPIO_Pin));
  GPIOx->BSRR = GPIO_Pin;
}
 

void GPIO_ResetBits(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin)

{
    GPIOx->BRR |= GPIO_Pin;    
}
 

 void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_PIN(GPIO_Pin));
  GPIOx->BSRR = GPIO_Pin;
}
 

void GPIO_ResetBits(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin){
    GPIOx->BRR |= GPIO_Pin;
    
}
 

  char x=5;
    while(1)
    {
    switch (x) {
           case 1:     
            GPIOD-> ODR =0x0; 
            delay_ms(0xFF);
            GPIOD ->ODR =0xffff; 
            delay_ms(0x10FF);
            break;
        
        case 2:
            GPIOD->BRR |= 0x0004;   //  PD2 ¶ÔÓ¦µÄÊǵÚ3λ£¡²»ÊǵÚ2λ   43210
            delay_ms(0xFF);
            GPIOD->BSRR |=0x0004;
            delay_ms(0xFF);
           break;


        case 3:
             GPIOD->BSRR =0x00040000;
            delay_ms(0xFF);
            GPIOD->BSRR |=0x0004;
            delay_ms(0xFF);
            break;
        case 4:
           GPIO_WriteBit(GPIOD, GPIO_Pin_2,0);    
            delay_ms(0xFF);
           GPIO_WriteBit(GPIOD, GPIO_Pin_2, 1);
            delay_ms(0xFF);
            break;


        case 5:
           GPIO_ResetBits(GPIOD, 4);   
            delay_ms(0xFF);
           GPIO_SetBits(GPIOD, 4); 
            delay_ms(0xFF);
            break;


         case 6:
            (*((u32*)0x42228188))=0;   //0x42228180+2*4
            delay_ms(0xFF);
            (*((u32*)0x42228188))=1;
            delay_ms(0x10FF);
            break;                        
        default:
             
    }    

位绑定地址计算公式为:

结合“豆包” ,prompt:  stm32 gpioA PA0的位绑定地址 计算:

AliasAddr = 0x42000000 + ((A - 0x40000000) * 32 + n * 4),其中A为要绑定的寄存器地址,n表示寄存器中的位序号(0~7)。()

PA0的位绑定地址 ,也称位带地址(C ODR的偏移地址

= 0x42000000 + (0x1080C × 32) = 0x42000000 + 0x210180 = 0x42210180

PD2的位绑定地址 ,也称位带地址(C ODR的偏移地址

   = 0x42000000 + (0x1140C × 32)  + 2 × 4 =0x42228188

注:× 32等于16进制的 x20 ,很方便手算。

        

教材的算法:

// 把“位带地址+位序号”转换成别名地址的宏
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x02000000+((addr & 0x00FFFFFF)<<5)+(bitnum<<2)) 
/*
 *addr & 0xF0000000,取地址的高4位,看看是2还是4,用于区分SRAM和外设地址,
 *如果是2,+0x02000000则=0X2200 0000,即是SRAM,如果是4,+0x02000000则=0X4200 0000,即是外设
 *
 *addr & 0x000FFFFFF,屏蔽掉高两位,相当于-0X2000 0000或者-0X4000 0000,结果表示偏移位带区多少个字节
 *<<5  等于*8*4,因为位带区一个地址表示一个字节,一个字节有8个bit,一个bit可以膨胀成一个字,即4个字节
 *<<2 等于*4,因为一个位可以膨胀成一个字,即4个字节
 *
 *分解成两条公式应该就是这样:
 *SRAM位带别名地址
 *AliasAddr= 0x2200 0000+((A-0x2000 0000)*8+n)*4 =0x22000000+ (A-0x20000000)*8*4 +n*4
 *外设位带别名地址(野火原始把这里弄错了!)
 *AliasAddr= 0x4200 0000+((A-0x2000 0000)*8+n)*4 =0x2200 0000+ (A-0x2000 0000)*8*4 +n*4

=  0x4200 0000 +(0x4001 140C - 0x2000 0000)*32*2+2*4 //带入PD2端口数据

=  0x4200 0000 + 0x2001 140C *32*2+8 // *32左移一个16进制的0

=  0x4200 0000+0x2001 140C0*2+8

=  0x 4200 0000

+  0x 0022 8180

+                     8

= 0x 4222   8188
 */

#define GPIOD_ODR_Addr    (GPIOD_BASE+12) //0x4001 140C   

  • 22
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值