OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 8627|回复: 13

STM32F0 位带操作(附带f0 f1 f4通用引脚初始化方案)

[复制链接]

51

主题

2166

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10653
金钱
10653
注册时间
2017-4-14
在线时间
2780 小时
发表于 2019-3-31 20:52:30 | 显示全部楼层 |阅读模式
本帖最后由 nashui_sx 于 2021-2-27 13:46 编辑

STM32F030F4不支持位带操作,最近总是来回切换stm32f1 f0,同样写的库 引脚初始化改来改去挺烦的,就想弄个方案解决,给大家分享下

1.普通大家用的模拟位带操作
typedef struct _16_Bits_Struct
{
     u16 bit0  : 1;
     u16 bit1  : 1;
     u16 bit2  : 1;
     u16 bit3  : 1;
     u16 bit4  : 1;
     u16 bit5  : 1;
     u16 bit6  : 1;
     u16 bit7  : 1;
     u16 bit8  : 1;
     u16 bit9  : 1;
     u16 bit10 : 1;
     u16 bit11 : 1;
     u16 bit12 : 1;
     u16 bit13 : 1;
     u16 bit14 : 1;
     u16 bit15 : 1;
} Bits_16_TypeDef;

//使用
#define LED_PORT              GPIOA
#define LED_PIN        GPIO_Pin_4
#define LED0           (((Bits_16_TypeDef *)(&(LED_PORT->ODR)))->bit4)//输出
#define KEY1           (((Bits_16_TypeDef *)(&(KEY_PORT->IDR)))->bit3)//输入[/mw_shl_code]

这样就是往常常用的模拟位带操作的方法,但是给正点原子的#define PAout(n) 还是有点不一样,头文件宏定义还是要改,就想着能不能改进下,下面两行代码,兼容原子的代码
#define LED0 (((Bits_16_TypeDef *)(&(LED_PORT->ODR)))->bit4)//输出
#define KEY1 (((Bits_16_TypeDef *)(&(KEY_PORT->IDR)))->bit3)//输入

2.改进位带操作
分析 #define LED0 PAout(4) 和#define LED0 (((Bits_16_TypeDef *)(&(GPIOA->ODR)))->bit4)的差异
也就是4和->bit4的差异,这俩看着有规律可是怎么都替换不了
后来想起来二进制转10进制的方法  //用n替换"0x##n"中的"n"的方法,就尝试了下,确实可以
以#define PAout(n)   (((Bits_16_TypeDef *)(&(GPIOA->ODR)))->bit##n)  为例
PAout(n)中的n 在  (((Bits_16_TypeDef *)(&(GPIOA->ODR)))->bit##n)中 会替换##n
这样PAout(1)就等价于执行(((Bits_16_TypeDef *)(&(GPIOA->ODR)))->bit1),就兼容原子的代码了


下面代码放到f0的sys.h  就能和f1 f4的外带操作一样了
//方案2
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct _16_Bits_Struct
{
     u16 bit0  : 1;
     u16 bit1  : 1;
     u16 bit2  : 1;
     u16 bit3  : 1;
     u16 bit4  : 1;
     u16 bit5  : 1;
     u16 bit6  : 1;
     u16 bit7  : 1;
     u16 bit8  : 1;
     u16 bit9  : 1;
     u16 bit10 : 1;
     u16 bit11 : 1;
     u16 bit12 : 1;
     u16 bit13 : 1;
     u16 bit14 : 1;
     u16 bit15 : 1;
} Bits_16_TypeDef;
//用n替换"0x##n"中的"n"
#define PAout(n)   (((Bits_16_TypeDef *)(&(GPIOA->ODR)))->bit##n)  //输出
#define PAin(n)    (((Bits_16_TypeDef *)(&(GPIOA->IDR)))->bit##n)  //输入
#define PBout(n)   (((Bits_16_TypeDef *)(&(GPIOB->ODR)))->bit##n)  //输出
#define PBin(n)    (((Bits_16_TypeDef *)(&(GPIOB->IDR)))->bit##n)  //输入
#define PCout(n)   (((Bits_16_TypeDef *)(&(GPIOC->ODR)))->bit##n)  //输出
#define PCin(n)    (((Bits_16_TypeDef *)(&(GPIOC->IDR)))->bit##n)  //输入
#define PDout(n)   (((Bits_16_TypeDef *)(&(GPIOD->ODR)))->bit##n)  //输出
#define PDin(n)    (((Bits_16_TypeDef *)(&(GPIOD->IDR)))->bit##n)  //输入
#define PEout(n)   (((Bits_16_TypeDef *)(&(GPIOE->ODR)))->bit##n)  //输出
#define PEin(n)    (((Bits_16_TypeDef *)(&(GPIOE->IDR)))->bit##n)  //输入
#define PFout(n)   (((Bits_16_TypeDef *)(&(GPIOF->ODR)))->bit##n)  //输出
#define PFin(n)    (((Bits_16_TypeDef *)(&(GPIOF->IDR)))->bit##n)  //输入
#define PGout(n)   (((Bits_16_TypeDef *)(&(GPIOG->ODR)))->bit##n)  //输出
#define PGin(n)    (((Bits_16_TypeDef *)(&(GPIOG->IDR)))->bit##n)  //输入

至此,以后f1 f0的代码就能直接通用了



以下是附带的,引脚初始化通用代码,与位带操作相结合完美解决f0 f1 f4外设代码移植的通用性
具体是在f0 f1 f4 sys.h sys.c 分别添加一下代码(附带优点,自动识别要初始化的时钟总线)

里面用到的一个函数power  指数次方,用于计算时钟总线
u32 Power(u32 x,u32 y){u32 mul = 1,i;for(i = 0;i<y;i++)mul = mul * x;return mul;}


f0的
//sys.h
typedef enum
{
        GPIO_FK_IN=0,    //浮空输入
        GPIO_AD_IN=1,    //AD输入

        GPIO_KL_OUT=2,   //开漏输出 可以读IO输入电平变化,实现C51的IO双向功能,就不需要切换输入输出了,但需要外部上拉电阻
        GPIO_KL_AF_OUT=3,//开漏复用
        GPIO_TW_OUT=4,   //推挽输出
        GPIO_TW_AF_OUT=5,//推挽复用

        GPIO_P_NO=6,     //不上下拉
        GPIO_P_UP=7,     //上拉
        GPIO_P_DOWN=8,   //下拉

        GPIO_2MHz=9,
        GPIO_10MHz=10,
        GPIO_25MHz=10,//用GPIO_10MHz替代
        GPIO_50MHz=12,
        GPIO_100MHz=12//用GPIO_50MHz替代
}GPIO_My_TypeDef;
void My_GPIO_Init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin,GPIO_My_TypeDef mode,GPIO_My_TypeDef up_down,GPIO_My_TypeDef speed);

//sys.c
//stm32 通用外设初始化方案,方便不同芯片移植
void My_GPIO_Init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin,GPIO_My_TypeDef mode,GPIO_My_TypeDef up_down,GPIO_My_TypeDef speed)
{
        GPIO_InitTypeDef  GPIO_InitStructure;

        RCC_AHBPeriphClockCmd(Power(2,((uint32_t)GPIOx-(uint32_t)GPIOA)/0x0400)*(uint32_t)RCC_AHBPeriph_GPIOA, ENABLE);
        
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin;        

        if(mode==GPIO_FK_IN)                           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
        if(mode==GPIO_KL_OUT||mode==GPIO_TW_OUT)       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;                 
        if(mode==GPIO_KL_AF_OUT||mode==GPIO_TW_AF_OUT) GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;                 
        if(mode==GPIO_AD_IN)                           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
        if(mode==GPIO_TW_OUT||mode==GPIO_TW_AF_OUT)    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                 
        if(mode==GPIO_KL_OUT||mode==GPIO_KL_AF_OUT)    GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;

        if(up_down==GPIO_P_NO)                         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
        if(up_down==GPIO_P_UP)                         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;               
        if(up_down==GPIO_P_DOWN)                       GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;

         if(speed==GPIO_2MHz)                           GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
         if(speed==GPIO_10MHz)                          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
         if(speed==GPIO_25MHz)                          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;//用GPIO_10MHz替代
        if(speed==GPIO_50MHz)                          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        if(speed==GPIO_100MHz)                         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//用GPIO_50MHz替代         

        GPIO_Init(GPIOx, &GPIO_InitStructure);
}
f1
//sys.h
typedef enum
{
        GPIO_FK_IN=0,
        GPIO_AD_IN=1,

        GPIO_KL_OUT=2,
        GPIO_KL_AF_OUT=3,
        GPIO_TW_OUT=4,
        GPIO_TW_AF_OUT=5,

        GPIO_P_NO=6,
        GPIO_P_UP=7,
        GPIO_P_DOWN=8,

        GPIO_2MHz=9,
        GPIO_10MHz=10,
        GPIO_25MHz=10,//用GPIO_10MHz替代
        GPIO_50MHz=12,
        GPIO_100MHz=12//用GPIO_50MHz替代
}GPIO_My_TypeDef;
void My_GPIO_Init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin,GPIO_My_TypeDef mode,GPIO_My_TypeDef up_down,GPIO_My_TypeDef speed);


//sys.c
//stm32 通用外设初始化方案,方便不同芯片移植
void My_GPIO_Init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin,GPIO_My_TypeDef mode,GPIO_My_TypeDef up_down,GPIO_My_TypeDef speed)
{
        GPIO_InitTypeDef  GPIO_InitStructure;

        RCC_APB2PeriphClockCmd(Power(2,((uint32_t)GPIOx-(uint32_t)GPIOA)/0x0400+2), ENABLE);

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin;        

        if(mode==GPIO_AD_IN)                         GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AIN;
        if(mode==GPIO_FK_IN && up_down==GPIO_P_NO)   GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN_FLOATING;
        if(mode==GPIO_FK_IN && up_down==GPIO_P_DOWN) GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPD;  
        if(mode==GPIO_FK_IN && up_down==GPIO_P_UP)   GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;  
        if(mode==GPIO_KL_OUT)                        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_OD;
        if(mode==GPIO_TW_OUT)                        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
        if(mode==GPIO_KL_AF_OUT)                     GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_OD;
        if(mode==GPIO_TW_AF_OUT)                     GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;

         if(speed==GPIO_2MHz)                         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
        if(speed==GPIO_10MHz)                        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
        if(speed==GPIO_25MHz)                        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;//用GPIO_10MHz替代
        if(speed==GPIO_50MHz)                        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
        if(speed==GPIO_100MHz)                       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//用GPIO_50MHz替代         

        GPIO_Init(GPIOx, &GPIO_InitStructure);               
}




f4的
//sys.h
typedef enum
{
        GPIO_FK_IN=0,    //浮空输入
        GPIO_AD_IN=1,    //AD输入

        GPIO_KL_OUT=2,   //开漏输出 可以读IO输入电平变化,实现C51的IO双向功能,就不需要切换输入输出了,但需要外部上拉电阻
        GPIO_KL_AF_OUT=3,//开漏复用
        GPIO_TW_OUT=4,   //推挽输出
        GPIO_TW_AF_OUT=5,//推挽复用

        GPIO_P_NO=6,     //不上下拉
        GPIO_P_UP=7,     //上拉
        GPIO_P_DOWN=8,   //下拉

        GPIO_2MHz=9,
        GPIO_10MHz=9,    //用GPIO_2MHz替代
        GPIO_25MHz=11,
        GPIO_50MHz=12,
        GPIO_100MHz=13
}GPIO_My_TypeDef;
void My_GPIO_Init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin,GPIO_My_TypeDef mode,GPIO_My_TypeDef up_down,GPIO_My_TypeDef speed);


//sys.c
//stm32 通用外设初始化方案,方便不同芯片移植
void My_GPIO_Init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin,GPIO_My_TypeDef mode,GPIO_My_TypeDef up_down,GPIO_My_TypeDef speed)
{
        GPIO_InitTypeDef  GPIO_InitStructure;

        RCC_AHB1PeriphClockCmd(Power(2,((uint32_t)GPIOx-(uint32_t)GPIOA)/0x0400), ENABLE);
        
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin;        

        if(mode==GPIO_FK_IN)                           GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN;
        if(mode==GPIO_KL_OUT||mode==GPIO_TW_OUT)       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;                 
        if(mode==GPIO_KL_AF_OUT||mode==GPIO_TW_AF_OUT) GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;                 
        if(mode==GPIO_AD_IN)                           GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AN;
        if(mode==GPIO_TW_OUT||mode==GPIO_TW_AF_OUT)    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                 
        if(mode==GPIO_KL_OUT||mode==GPIO_KL_AF_OUT)    GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;

        if(up_down==GPIO_P_NO)                         GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
        if(up_down==GPIO_P_UP)                         GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;               
        if(up_down==GPIO_P_DOWN)                       GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_DOWN;

         if(speed==GPIO_2MHz  )                         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
         if(speed==GPIO_10MHz  )                        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;//用GPIO_2MHz替代
        if(speed==GPIO_25MHz )                         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
        if(speed==GPIO_50MHz )                         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;               
        if(speed==GPIO_100MHz)                         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;         

        GPIO_Init(GPIOx, &GPIO_InitStructure);           
}

使用方法:(自动识别要初始化的时钟总线
#define LED_PORT              GPIOA
#define LED_PIN        GPIO_Pin_4//能或组合引脚
led初始化My_GPIO_Init(LED_PORT,LED_PIN,GPIO_TW_OUT,GPIO_P_DOWN,GPIO_10MHz);//推挽输出 下拉 10m

#define KEY_PORT              GPIOA
#define KEY_PIN        GPIO_Pin_3//能或组合引脚
key初始化My_GPIO_Init(KEY_PORT,KEY_PIN,GPIO_FK_IN,GPIO_P_UP,GPIO_50MHz);//浮空输入 上拉 50m
这样以后外设的代码就能兼容f0 f1 f4了,直接复制过去,完美直接用

欢迎大家提提意见












正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

315

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1669
金钱
1669
注册时间
2018-1-29
在线时间
160 小时
发表于 2019-4-1 08:50:04 | 显示全部楼层
回复 支持 反对

使用道具 举报

0

主题

295

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
335
金钱
335
注册时间
2019-3-26
在线时间
9 小时
发表于 2019-4-1 11:19:38 | 显示全部楼层
谢谢大神分享!
回复 支持 反对

使用道具 举报

0

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
53
金钱
53
注册时间
2019-7-15
在线时间
18 小时
发表于 2019-8-1 17:30:31 | 显示全部楼层
666666666
回复 支持 反对

使用道具 举报

3

主题

39

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
311
金钱
311
注册时间
2013-4-5
在线时间
82 小时
发表于 2019-9-9 21:02:33 | 显示全部楼层
感谢分享。谢谢
回复 支持 反对

使用道具 举报

0

主题

32

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
268
金钱
268
注册时间
2018-12-2
在线时间
76 小时
发表于 2019-10-24 15:00:10 | 显示全部楼层
自动识别要初始化的时钟总线的原理是什么,没看明白
回复 支持 反对

使用道具 举报

51

主题

2166

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10653
金钱
10653
注册时间
2017-4-14
在线时间
2780 小时
 楼主| 发表于 2019-10-24 15:30:20 | 显示全部楼层
yenhok 发表于 2019-10-24 15:00
自动识别要初始化的时钟总线的原理是什么,没看明白

GPIOA  RCC_APB2Periph_GPIOA都是个地址就是个数  有对应关系 算一下就好了  
回复 支持 反对

使用道具 举报

0

主题

8

帖子

0

精华

初级会员

Rank: 2

积分
62
金钱
62
注册时间
2020-5-10
在线时间
14 小时
发表于 2020-11-13 13:02:42 | 显示全部楼层

你这个问题在V6编译器就报错了,因为编译器比较严格,感谢大佬的思路,现在附上我的完美解决方案,定义一个MYBIT宏去连接字符串,告诉编译器,老子就要这么干就行啦:
回复 支持 反对

使用道具 举报

0

主题

8

帖子

0

精华

初级会员

Rank: 2

积分
62
金钱
62
注册时间
2020-5-10
在线时间
14 小时
发表于 2020-11-13 13:03:28 | 显示全部楼层
//山寨版位带操作
//没有叉叉提醒
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct _16_Bits_Struct
{
     u16 bit0  : 1;
     u16 bit1  : 1;
     u16 bit2  : 1;
     u16 bit3  : 1;
     u16 bit4  : 1;
     u16 bit5  : 1;
     u16 bit6  : 1;
     u16 bit7  : 1;
     u16 bit8  : 1;
     u16 bit9  : 1;
     u16 bit10 : 1;
     u16 bit11 : 1;
     u16 bit12 : 1;
     u16 bit13 : 1;
     u16 bit14 : 1;
     u16 bit15 : 1;
} Bits_16_TypeDef;
//用n替换"0x##n##L"中的"n"
#define MYBIT(n) bit##n

#define PAout(n)   (((Bits_16_TypeDef *)(&(GPIOA->ODR)))->MYBIT(n))  //输出
#define PAin(n)    (((Bits_16_TypeDef *)(&(GPIOA->IDR)))->MYBIT(n))  //输入
#define PBout(n)   (((Bits_16_TypeDef *)(&(GPIOB->ODR)))->MYBIT(n))  //输出
#define PBin(n)    (((Bits_16_TypeDef *)(&(GPIOB->IDR)))->MYBIT(n))  //输入
#define PCout(n)   (((Bits_16_TypeDef *)(&(GPIOC->ODR)))->MYBIT(n))  //输出
#define PCin(n)    (((Bits_16_TypeDef *)(&(GPIOC->IDR)))->MYBIT(n))  //输入
#define PDout(n)   (((Bits_16_TypeDef *)(&(GPIOD->ODR)))->MYBIT(n))  //输出
#define PDin(n)    (((Bits_16_TypeDef *)(&(GPIOD->IDR)))->MYBIT(n))  //输入
#define PEout(n)   (((Bits_16_TypeDef *)(&(GPIOE->ODR)))->MYBIT(n))  //输出
#define PEin(n)    (((Bits_16_TypeDef *)(&(GPIOE->IDR)))->MYBIT(n))  //输入
#define PFout(n)   (((Bits_16_TypeDef *)(&(GPIOF->ODR)))->MYBIT(n))  //输出
#define PFin(n)    (((Bits_16_TypeDef *)(&(GPIOF->IDR)))->MYBIT(n))  //输入
#define PGout(n)   (((Bits_16_TypeDef *)(&(GPIOG->ODR)))->MYBIT(n))  //输出
#define PGin(n)    (((Bits_16_TypeDef *)(&(GPIOG->IDR)))->MYBIT(n))  //输入
回复 支持 反对

使用道具 举报

51

主题

2166

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10653
金钱
10653
注册时间
2017-4-14
在线时间
2780 小时
 楼主| 发表于 2020-11-14 09:00:34 | 显示全部楼层
chenyizhong 发表于 2020-11-13 13:03
//山寨版位带操作
//没有叉叉提醒
////////////////////////////////////////////////////////////////// ...

嗯呀,之前mdk版本低现在高版本的也不会有叉叉提醒了
回复 支持 反对

使用道具 举报

0

主题

8

帖子

0

精华

初级会员

Rank: 2

积分
62
金钱
62
注册时间
2020-5-10
在线时间
14 小时
发表于 2020-11-18 10:15:02 | 显示全部楼层
nashui_sx 发表于 2020-11-14 09:00
嗯呀,之前mdk版本低现在高版本的也不会有叉叉提醒了

我用的h7哦,你那个写法就行不通了哦,h7上用我这个就行了
回复 支持 反对

使用道具 举报

3

主题

39

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
311
金钱
311
注册时间
2013-4-5
在线时间
82 小时
发表于 2021-1-3 14:58:07 | 显示全部楼层
都是高手啊
回复 支持 反对

使用道具 举报

3

主题

39

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
311
金钱
311
注册时间
2013-4-5
在线时间
82 小时
发表于 2021-2-27 13:39:37 | 显示全部楼层
楼主 #define PAout(n)   (((Bits_16_TypeDef *)(&(GPIOA->ODR)))->bit##n##)  //输出
把 n后的两个#去掉就没x了吧
这样
#define PAout(n)   (((Bits_16_TypeDef *)(&(GPIOA->ODR)))->bit##n)
回复 支持 反对

使用道具 举报

51

主题

2166

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10653
金钱
10653
注册时间
2017-4-14
在线时间
2780 小时
 楼主| 发表于 2021-2-27 13:46:54 | 显示全部楼层
dujq 发表于 2021-2-27 13:39
楼主 #define PAout(n)   (((Bits_16_TypeDef *)(&(GPIOA->ODR)))->bit##n##)  //输出
把 n后的两个#去掉 ...

嗯呀  之前有人说了忘记改了,已经改了  不过用最新的mdk也不会有警告
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-29 00:13

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表