Eight, STM32 bit band operation

1. Bit band area and bit band alias area

(1) Introduction of bit band

1. Bit-band operation I
have used bit-band operation when learning 51 single-chip microcomputer. For example, using sbit to define the IO port of the single-chip microcomputer, but there is no such keyword in STM32. It is realized by accessing the bit-band alias area, that is, through Each bit is expanded into a 32-bit word, and when these words are accessed, the purpose of accessing bits is achieved. For example, the BSRR register has 32 bits, so it can be mapped to 32 addresses. When we visit these 32 addresses, we can access 32 bits.
2. STM32 bit band and bit band alias area The area that
supports bit band operation is the lowest 1MB range of the SRAM area (APB1/2, AHB peripheral) and the lowest 1MB range of the on-chip peripheral area.

1MB bit is expanded to 32MB bit band alias area

(2) Address conversion between bit band area and bit band alias area

The address conversion formula of peripheral bit band area and peripheral bit band alias area: AliasAddr = 0x42000000+ (A-0x40000000)*8*4+n*4

The address conversion formula between SRAM bit band area and SRAM bit band alias area: AliasAddr = 0x22000000+ (A-0x20000000)*8*4 +n*4

A: indicates the address of the register where the bit we want to operate, n: bit number

Understanding the main points: a bit in the bit band alias area will be expanded into four bytes

According to the characteristics of the above two formulas, they are unified into one formula: ((A & 0xF0000000)+0x02000000+((A &0x000FFFFF)<<5)+(n<<2))

A: The address of the register where the bit to be operated is located; n: the bit number, that is, which bit is in the register.

(3) Advantages of bit band operation

(1) It is very simple to control the input and output of GPIO port.

(2) It is very convenient to operate the serial interface chip (DS1302, 74HC595, etc.)

(3) The code is concise and easy to read.

 

Two, GPIO bit band operation

//addr是地址,bitnum是该地址的第几位
#define BITBAND(addr,bitnum) ((addr&0xF0000000)+0x2000000+((addr&0xFFFFF)<<5)+(bitnum<<2))
//volatile提示该变量是随时可变的,每次使用都要读取
#define MEM_ADDR(addr)*((volatile unsigned long *)(addr))
#define BIT_ADDR(addr,bitnum) MEM_ADDR(BITBAND(addr,bitnum))
//IO口地址映射
//输出寄存器
#define GPIOA_ODR_Addr (GPIOA_BASE+12)//0x4001280C
#define GPIOB_ODR_Addr (GPIOB_BASE+12)//0x40010C0C
#define GPIOC_ODR_Addr (GPIOC_BASE+12)//0x4001100C
#define GPIOD_ODR_Addr (GPIOD_BASE+12)//0x4001140C
#define GPTOE_ODR_Addr (GPIOE_BASE+12)//0x4001180C
#define GPIOF_ODR_Addr (GPIOF_BASE+12)//0x40011A0C
#define GPIOG_ODR_Addr (GPIOG_BASE+12)//0x40011E0C
//输入寄存器
#define GPIOA_IDR_Addr (GPIOA_BASE+8)//0x40010808
#define GPIOB_IDR_Addr (GPIOB_BASE+8)//0x40010C08
#define GPIOC_IDR_Addr (GPIOC_BASE+8)//0x40011008
#define GPIOD_IDR_Addr (GPIOD_BASE+8)//0x40011408
#define GPIOE_IDR_Addr (GPIOE_BASE+8)//0x40011808
#define GPTOF_IDR_Addr (GPIOF_BASE+8)//0x40011A08
#define GPTOG_IDR_Addr (GPIOG_BASE+8)//0x40011E08

//IO口操作,只对单一的IO口!
//确保n的值小于16!
#define PAout(n)	BIT_ADDR(GPIOA_ODR_Addr,n)//输出
#define PAin(n) 	BIT_ADDR (GPIOA_IDR_Addr,n)//输入

#define PBout(n) 	BIT_ADDR(GPIOB_ODR_Addr,n)//输出
#define PBin(n) 	BIT_ADDR(GPIOB_IDR_Addr,n)//输入

#define PCout(n) 	BIT_ADDR(GPIOC_ODR_Addr,n)//输出
#define PCin(n) 	BIT_ADDR(GPIOC_IDR_Addr,n)//输入

#define PDout(n) 	BIT_ADDR(GPIOD_ODR_Addr,n)//输出
#define PDin(n) 	BIT_ADDR(GPIOD_IDR_Addr,n)//输入

#define PEout(n) 	BIT_ADDR(GPIOE_ODR_Addr,n)//输出
#define PEin(n) 	BIT_ADDR(GPIOE_IDR_Addr,n)//输入

#define PFout(n)	BIT_ADDR(GPIOF_ODR_Addr,n)//输出
#define PFin(n)		BIT_ADDR(GPIOF_IDR_Addr,n)//输入

#define PGout(n)	BIT_ADDR(GPIOG_oDR_Addr,n)//输出
#define PGin(n) 	BIT_ADDR(GPIOG_IDR_Addr,n)//输入

 

Third, the LED flashes

In the file to light up the LED lights , use the library function to light up an LED_not silly gown -CSDN blog , create new system.h and system.c files, and add them to the project, type in the system.h file The following code:

#ifndef _system_H
#define _system_H

#include "stm32f10x.h"

//addr是地址,bitnum是该地址的第几位
#define BITBAND(addr,bitnum) ((addr&0xF0000000)+0x2000000+((addr&0xFFFFF)<<5)+(bitnum<<2))
//volatile提示该变量是随时可变的,每次使用都要读取
#define MEM_ADDR(addr)*((volatile unsigned long *)(addr))
#define BIT_ADDR(addr,bitnum) MEM_ADDR(BITBAND(addr,bitnum))
//IO口地址映射
//输出寄存器
#define GPIOA_ODR_Addr (GPIOA_BASE+12)//0x4001280C
#define GPIOB_ODR_Addr (GPIOB_BASE+12)//0x40010C0C
#define GPIOC_ODR_Addr (GPIOC_BASE+12)//0x4001100C
#define GPIOD_ODR_Addr (GPIOD_BASE+12)//0x4001140C
#define GPTOE_ODR_Addr (GPIOE_BASE+12)//0x4001180C
#define GPIOF_ODR_Addr (GPIOF_BASE+12)//0x40011A0C
#define GPIOG_ODR_Addr (GPIOG_BASE+12)//0x40011E0C
//输入寄存器
#define GPIOA_IDR_Addr (GPIOA_BASE+8)//0x40010808
#define GPIOB_IDR_Addr (GPIOB_BASE+8)//0x40010C08
#define GPIOC_IDR_Addr (GPIOC_BASE+8)//0x40011008
#define GPIOD_IDR_Addr (GPIOD_BASE+8)//0x40011408
#define GPIOE_IDR_Addr (GPIOE_BASE+8)//0x40011808
#define GPTOF_IDR_Addr (GPIOF_BASE+8)//0x40011A08
#define GPTOG_IDR_Addr (GPIOG_BASE+8)//0x40011E08

//IO口操作,只对单一的IO口!
//确保n的值小于16!
#define PAout(n)	BIT_ADDR(GPIOA_ODR_Addr,n)//输出
#define PAin(n) 	BIT_ADDR (GPIOA_IDR_Addr,n)//输入

#define PBout(n) 	BIT_ADDR(GPIOB_ODR_Addr,n)//输出
#define PBin(n) 	BIT_ADDR(GPIOB_IDR_Addr,n)//输入

#define PCout(n) 	BIT_ADDR(GPIOC_ODR_Addr,n)//输出
#define PCin(n) 	BIT_ADDR(GPIOC_IDR_Addr,n)//输入

#define PDout(n) 	BIT_ADDR(GPIOD_ODR_Addr,n)//输出
#define PDin(n) 	BIT_ADDR(GPIOD_IDR_Addr,n)//输入

#define PEout(n) 	BIT_ADDR(GPIOE_ODR_Addr,n)//输出
#define PEin(n) 	BIT_ADDR(GPIOE_IDR_Addr,n)//输入

#define PFout(n)	BIT_ADDR(GPIOF_ODR_Addr,n)//输出
#define PFin(n)		BIT_ADDR(GPIOF_IDR_Addr,n)//输入

#define PGout(n)	BIT_ADDR(GPIOG_oDR_Addr,n)//输出
#define PGin(n) 	BIT_ADDR(GPIOG_IDR_Addr,n)//输入

#endif

Type the following code in system.c:

#include "system.h"

Type the following code in main.c:

#include "system.h"
#include "led.h"

//延时函数
void delay(u32 i)
{
	u16 j=0;
	while(i--)
	{
		//1ms
		j=12000;
		while(j--);
	}
}

int main()
{
	LED_Init();	
	while(1)
	{
		PCout(0)=0;
		delay(1000);
		PCout(0)=1;
		delay(1000);
	}
}

Download it to the Puzhong STM32F103ZET6 development board, you can observe the LED lights flickering. If it is not a common development board, just replace the PCout(0) in the main function while(1) with the corresponding pin of the LED on your own board.

 

Guess you like

Origin blog.csdn.net/qq_40836442/article/details/110198507