• 位带操作—GPIO输出和输入


    GPIOC->ODR |=(0<<2);  // 总线操作,即操作整个寄存器.

    在51单片机中

    P0=0xFE;   //总线操作.

    sbit LED1=P0^0;  //位操作,即操作寄存器中的某一位.

    LED1 =0;    

    在STM32中并没有sbit这样的关键字.但是我们可以用位带操作实现位操作.

    位带操作

          在 STM32 中,有两个地方实现了位带,一个是 SRAM 区(存放代码)的最低 1MB 空间,令一个是外设区最低 1MB 空间。这两个 1MB 的空间除了可以像正常的 RAM 一样操作外,他们还有自己的位带别名区,位带别名区把这 1MB 的空间的一个位膨胀成一个 32 位的字(4个字节),当访问位带别名区的这些字时,就可以达到访问位带区某个比特位的目的.

    11

     

    位带操作的公式

    外设位带区与外设位带别名区的地址转换:    AlisaAddr=0x42000000+(A-0x40000000)*8*4+n*4

    SRAM位带区与SRAM位带别名区地址转换:  AlisaAddr=0x22000000+(A-0x20000000)*8*4+n*4

    其中:A:表示操作的那个位寄存器所在的寄存器地址

           n:位号(第几位)

    对上面式子的解释:

         AlisaAddr=位带别名区基地址+(寄存器地址-寄存器基地址)[偏移多少个字节]*8[一个字节8位]*4[每个位膨胀4个字节] [这是第0位]+n*4[第n个位膨胀的字节说]

    理解要点:位带区的一个位在位带别名区膨胀位4个字节

    位带操作的总公式

                     AlisaAddr =((addr&0xF0000000)+0x02000000+((addr&0x00FFFFFF)<<5)+(bitnum<<2))

       其中:addr:要操作的寄存器地址.(寄存器映射表中,每个外设地址+偏移地址)

             bitnum:位号,即寄存器的第几位

      

    对上面式子的解释:   addr&0xF0000000:为了取出4和2,用来区分是外设还是SRAM.然后+0x20000000就等于外设/SRAM位带别名区的起始地址

                              add&0x00FFFFFF0x00FFFFFF:屏蔽掉高2位,外设位带区的高地址位0x4010 0000,SRAM的位带区高地址为0x2010 0000, (0x4010 0000 –0x40000000) 和(0x2010 0000-0x200000)在求偏移地址相减的时候只要第四位有效,所以就把剩下的高两位屏蔽掉,剩下的6位与F相与即可.

     

    点亮LED的源码

    我们在上次的代码中继续添加:

    main为:

    #include "stm32f10x.h"   // 相当于51单片机中的  #include <reg51.h>
    #include "bsp_led.h"
    #include "bsp_key.h"
    
    #define SOFT_DELAY    Delay(0x0FFFFF);
    //void Delay(__IO u32 nCount);
    
    #define GPIOC_ODR_Addr (GPIOC_BASE+0x0C)
    #define  PCout(bitnum) *(unsigned int *)((GPIOC_ODR_Addr&0xF0000000)+0x02000000+((GPIOC_ODR_Addr &0x00FFFFFF)<<5)+(bitnum<<2))
    
    #define GPIOC_IDR_Addr (GPIOC_BASE+0x08)
    #define  PCIn(bitnum) *(unsigned int *)((GPIOC_IDR_Addr&0xF0000000)+0x02000000+((GPIOC_IDR_Addr &0x00FFFFFF)<<5)+(bitnum<<2))
    void Delay( uint32_t count){
     for( ;count!=0;count--);
    
    }
    
    
    int main(void)
    {
    	// 来到这里的时候,系统的时钟已经被配置成72M。
    	LED_GPIO_Config();
    	LED_OFF;
    	KEY_LED_Config();
    	while(1){
    		if(PCIn(13)==KEY_ON){
    			while(PCIn(13)==KEY_ON)
    				;
    
    				LED_TOGGLE;
    
    
    		}
    
    
    
    }
    
    }
    

     

     

     

     

     

     

  • 相关阅读:
    R语言中log1p()函数
    linux中awk命令实现科学计数法和普通数值的相互转换
    linux中awk命令实现保留指定小数位数
    redhat8中使用nmtui命令图形界面配置网络IP
    redhat8基于vmware软件图形界面配置IP
    R语言中read.table函数中check.names = F参数的作用
    R语言中实现相同行名自动重命名
    redhat9中配置静态IP(nmtui命令)
    redhat8如何配置静态IP
    redhat8中配置yum仓库
  • 原文地址:https://www.cnblogs.com/wenshinlee/p/8855604.html
Copyright © 2020-2023  润新知