2710|8

1万

帖子

16

TA的资源

版主

楼主
 

【雅特力开发板 AT32F421 测评】3、对外设位操作的疑问,难道不好用 [复制链接]

  本帖最后由 ddllxxrr 于 2021-4-11 16:38 编辑

我觉得位操作十分简单,然而就是这个简单的操作,害了我一整天。我不得不宣布,对外设的位操作失败。

 

我看了下例程提供的位操作是对RAM的,我觉得没有什么实用价值,谁会没有事跑到RAM去操作一个BIT。

 

我要有价值的那就是象51单片机那样的位操作。我本来十分有把握的建了H文件内容如下:

 

#ifndef __BITBAND__
#define __BITBAND__

//#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))

//#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))

//#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))

//#define GPIOA_ODR_Addr    (GPIOA_BASE+0x14) //0x4001080C
//#define GPIOA_IDR_Addr    (GPIOA_Base+0x10) 

//#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //输出 ODR保存要输出的数据;IDR保存读入的数据
//#define PAin(n)  BIT_ADDR(GPIOA_IDR_Addr,n)  //in

//位带操作,实现51类似的GPIO控制功能
//IO口操作宏定义
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) 
#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+20) //0x40020014
#define GPIOB_ODR_Addr    (GPIOB_BASE+20) //0x40020414 
#define GPIOC_ODR_Addr    (GPIOC_BASE+20) //0x40020814 
#define GPIOD_ODR_Addr    (GPIOD_BASE+20) //0x40020C14 
#define GPIOE_ODR_Addr    (GPIOE_BASE+20) //0x40021014 
#define GPIOF_ODR_Addr    (GPIOF_BASE+20) //0x40021414    
#define GPIOG_ODR_Addr    (GPIOG_BASE+20) //0x40021814   
#define GPIOH_ODR_Addr    (GPIOH_BASE+20) //0x40021C14    
#define GPIOI_ODR_Addr    (GPIOI_BASE+20) //0x40022014     
#define GPIOA_IDR_Addr    (GPIOA_BASE+16) //0x40020010 
#define GPIOB_IDR_Addr    (GPIOB_BASE+16) //0x40020410 
#define GPIOC_IDR_Addr    (GPIOC_BASE+16) //0x40020810 
#define GPIOD_IDR_Addr    (GPIOD_BASE+16) //0x40020C10 
#define GPIOE_IDR_Addr    (GPIOE_BASE+16) //0x40021010 
#define GPIOF_IDR_Addr    (GPIOF_BASE+16) //0x40021410 
#define GPIOG_IDR_Addr    (GPIOG_BASE+16) //0x40021810 
#define GPIOH_IDR_Addr    (GPIOH_BASE+16) //0x40021C10 
#define GPIOI_IDR_Addr    (GPIOI_BASE+16) //0x40022010 
 
//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)  //输入
 
#define PHout(n)   BIT_ADDR(GPIOH_ODR_Addr,n)  //输出 
#define PHin(n)    BIT_ADDR(GPIOH_IDR_Addr,n)  //输入
 
#define PIout(n)   BIT_ADDR(GPIOI_ODR_Addr,n)  //输出 
#define PIin(n)    BIT_ADDR(GPIOI_IDR_Addr,n)  //输入


#endif

然而,这就是开始了,一点也不好用,从上午到下午。程序如下:

int main(void)
{
  AT32_Board_Init();
  GPIO_init();
  for(;;)
  {
    PAout(8) = 1;
		//GPIO_SetBits(GPIOA,GPIO_Pins_8);
		PAout(10) = 1;
		AT32_LEDn_Toggle(LED2);
    Delay_ms(200);
    AT32_LEDn_Toggle(LED3);
    Delay_ms(200);
    AT32_LEDn_Toggle(LED4);
    Delay_ms(200);
		PAout(8) = 0;
		//GPIO_ResetBits(GPIOA,GPIO_Pins_8);
		PAout(10) = 0;
		AT32_LEDn_Toggle(LED2);
    Delay_ms(200);
    AT32_LEDn_Toggle(LED3);
    Delay_ms(200);
    AT32_LEDn_Toggle(LED4);
    Delay_ms(200);
  
  }
}

只要我用位操作就不好用,只要我不用位操作就好用。

管脚初始化完的。我后来找了下资料大致原因如下:

 

找到A的定义:

#elif defined (AT32F421xx)
 #define GPIOA_BASE           (AHB2PERIPH_BASE + 0x0000)
 #define GPIOB_BASE           (AHB2PERIPH_BASE + 0x0400)
 #define GPIOC_BASE           (AHB2PERIPH_BASE + 0x0800)
 #define GPIOF_BASE           (AHB2PERIPH_BASE + 0x1400)
#endif

 

找到AHB2PERIPH_BASE的定义:

/** Peripheral memory map */
#define APB1PERIPH_BASE       (PERIPH_BASE)
#define APB2PERIPH_BASE       (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE        (PERIPH_BASE + 0x20000)
#define AHB2PERIPH_BASE       (PERIPH_BASE + 0x08000000)

 

管脚正好是 AHB2PERIPH_BASE 但为什后边是0x08000000,而根据M4核定义,

应是0x4200 0000开始,而如果按上边公式,我的范围应在,0x5000 0000开始,所以不好用。。。。。。

我开始不淡定了,我把0x0800 0000 减0x0600 0000想让地址落下0x2200 0000但是不好用。

 

不想了,我就是不明白,好好的外设A地址为什么定义到了0x4800 0000开始,而技术手册,明明写着外设从0x400 0000开始。

 

 

而地址映射确实在0x4800 0000(否则库函数根本不好用),那么我要问啦,位映射地址:0x4200 0000怎么没有画出来:

 

 

 

不知大家的位操作好用不啦?

最新回复

哎,用M4内核做M0的事,我们还是把这款当做F030的高频升级版开发比较核实。   详情 回复 发表于 2021-4-15 14:21
点赞 关注
个人签名http://shop34182318.taobao.com/
https://shop436095304.taobao.com/?spm=a230r.7195193.1997079397.37.69fe60dfT705yr
 
 

回复
举报

6802

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

雅特力的F421 的地址是按着STM32F030排的 因此和STM32F030一样,gpio 不支持bit-band

点评

我晕  详情 回复 发表于 2021-4-11 20:05

赞赏

1

查看全部赞赏

 
 
 

回复

6802

帖子

0

TA的资源

五彩晶圆(高级)

板凳
 

STM32F030的GPIO是属于AHB2,地址不在位置操作区域,地址映射后对应不是GPIO的寄存器,不能对位操作,F421模仿的是F030,,,

点评

谢谢回答    详情 回复 发表于 2021-4-11 20:05
 
 
 

回复

1万

帖子

16

TA的资源

版主

4
 
Jacktang 发表于 2021-4-11 18:23 雅特力的F421 的地址是按着STM32F030排的 因此和STM32F030一样,gpio 不支持bit-band

我晕

个人签名http://shop34182318.taobao.com/
https://shop436095304.taobao.com/?spm=a230r.7195193.1997079397.37.69fe60dfT705yr
 
 
 

回复

1万

帖子

16

TA的资源

版主

5
 
Jacktang 发表于 2021-4-11 18:31 STM32F030的GPIO是属于AHB2,地址不在位置操作区域,地址映射后对应不是GPIO的寄存器,不能对位操作,F421 ...

谢谢回答

 

个人签名http://shop34182318.taobao.com/
https://shop436095304.taobao.com/?spm=a230r.7195193.1997079397.37.69fe60dfT705yr
 
 
 

回复

1942

帖子

3

TA的资源

版主

6
 

居然还有这个操作。。。想不到!

 
 
 

回复

7608

帖子

2

TA的资源

五彩晶圆(高级)

7
 

有些mcu没配置这个cortex的选项,好像近几年的新片子都没配这个。

个人签名

默认摸鱼,再摸鱼。2022、9、28

 
 
 

回复

5260

帖子

239

TA的资源

管理员

8
 

找雅特力官方问了下: GPIO bitband因GPIO外设基地址调整,其映射范围超出位带区而无法使用。

加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
 
 
 

回复

71

帖子

2

TA的资源

一粒金砂(中级)

9
 

哎,用M4内核做M0的事,我们还是把这款当做F030的高频升级版开发比较核实。

 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表