位带操作

文章目录
  1. 1. sys.h
  2. 2. sys.c
  3. 3. 使用方法
  4. 4. 使用例
  5. 5. 附录

大位带这一块

sys.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

#ifndef __SYS_H
#define __SYS_H

#include "stm32f10x.h"

//把“位带地址+位序号”转换成别名地址的宏
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr & 0xFFFFF)<<5)+(bitnum<<2))

//把该地址转换成一个指针
#define MEM_ADDR(addr) *((volatile unsigned long *) (addr))

//位带的实现---GPIOA/B/C IDR/ODR
#define PAin(bitnum) MEM_ADDR(BITBAND(GPIOA_BASE + 0x08, bitnum))//GPIOA的IDR的第bitnum位的地址
#define PAout(bitnum) MEM_ADDR(BITBAND(GPIOA_BASE + 0x0C, bitnum))//GPIOA的ODR的第bitnum位的地址
#define PBin(bitnum) MEM_ADDR(BITBAND(GPIOB_BASE + 0x08, bitnum))//GPIOB的IDR的第bitnum位的地址
#define PBout(bitnum) MEM_ADDR(BITBAND(GPIOB_BASE + 0x0C, bitnum))//GPIOB的ODR的第bitnum位的地址
#define PCin(bitnum) MEM_ADDR(BITBAND(GPIOC_BASE + 0x08, bitnum))//GPIOB的IDR的第bitnum位的地址
#define PCout(bitnum) MEM_ADDR(BITBAND(GPIOC_BASE + 0x0C, bitnum))//GPIOB的ODR的第bitnum位的地址

#endif

sys.c

1
#include "sys.h"

使用方法

先导入头文件sys.h;

PAin(X)即为端口X的电平信息,高电平PAin(X) = 1;低电平PAin(X) = 0;其他PBin(X),PCin(X)同理。

PAout(X)可设置端口X的电平,高电平PAin(X) = 1;低电平PAin(X) = 0;其他PBin(X),PCin(X)同理。

使用时可将PXin(X)当作GPIO_ReadInputDataBit(GPIOX, GPIO_Pin_X);使用;

PXout(X)当作GPIO_SetBits(GPIOX, GPIO_Pin_X);与GPIO_ResetBits(GPIOX, GPIO_Pin_X);使用;

使用例

简单的LED灯控制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include "stm32f10x.h"                  // Device header
#include "sys.h"

void LED_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

PAout(1) = 1;
PAout(2) = 1;
}

void LED1_ON(void)
{
PAout(1) = 0;
}

void LED1_OFF(void)
{
PAout(1) = 1;
}

void LED1_Turn(void)
{
if (PAin(1) == 0)
{
PAout(1) = 1;
}
else
{
PAout(1) = 0;
}
}

void LED2_ON(void)
{
PAout(2) = 0;
}

void LED2_OFF(void)
{
PAout(2) = 1;
}

void LED2_Turn(void)
{
if (PAin(2) == 0)
{
PAout(2) = 1;
}
else
{
PAout(2) = 0;
}
}

附录

还有许多方式实现读取端口信息
例如

1
#define PIN_STATA	GPIO_ReadInputDataBit(GPIOX, GPIO_Pin_X)//标准库读取

或者与位带结合

1
2
3
#define KEY0_STATE()		PBin(0)
#define KEY1_STATE() PBin(1)

等等…