搜索
bottom↓
回复: 3

求助 stm32f3 discovery板子 位带操作问题

[复制链接]

出0入10汤圆

发表于 2013-5-13 19:10:59 | 显示全部楼层 |阅读模式
玩stm32f3 discovery 板子时,想使用位带的操作方法,借鉴原子哥的程序和网上关于  《stm32F407位带操作,实现51类似的GPIO控制功能的代码 》的程序,
可是无论如何都实现不了位带的操作,各位高手大虾们帮忙啊,有没有人实现过stm32f3的位带操作程序,求分享。

使用的程序如下。
#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))
//F4XXIO 口地址映射
#define GPIOA_ODR_Addr (GPIOA_BASE+20)
#define GPIOB_ODR_Addr (GPIOB_BASE+20)
#define GPIOC_ODR_Addr (GPIOC_BASE+20)
#define GPIOD_ODR_Addr (GPIOD_BASE+20)
#define GPIOE_ODR_Addr (GPIOE_BASE+20)
#define GPIOF_ODR_Addr (GPIOF_BASE+20)
#define GPIOG_ODR_Addr (GPIOG_BASE+20)
#define GPIOH_ODR_Addr (GPIOH_BASE+20)
#define GPIOI_ODR_Addr (GPIOI_BASE+20) //
#define GPIOA_IDR_Addr (GPIOA_BASE+16)
#define GPIOB_IDR_Addr (GPIOB_BASE+16)
#define GPIOC_IDR_Addr (GPIOC_BASE+16)
#define GPIOD_IDR_Addr (GPIOD_BASE+16)
#define GPIOE_IDR_Addr (GPIOE_BASE+16)
#define GPIOF_IDR_Addr (GPIOF_BASE+16)
#define GPIOG_IDR_Addr (GPIOG_BASE+16)
#define GPIOH_IDR_Addr (GPIOF_BASE+16)
#define GPIOI_IDR_Addr (GPIOG_BASE+16)

#define GPIOAout(n)  BIT_ADDR(GPIOA_ODR_Addr,n) //GPIOA 某一位输出
#define GPIOAin(n)  BIT_ADDR(GPIOA_IDR_Addr,n) //GPIOA 某一位输入
#define GPIOBout(n)  BIT_ADDR(GPIOB_ODR_Addr,n) //GPIOB 某一位输出
#define GPIOBin(n)  BIT_ADDR(GPIOB_IDR_Addr,n) //GPIOB 某一位输入
#define GPIOCout(n)  BIT_ADDR(GPIOC_ODR_Addr,n) //GPIOC 某一位输出
#define GPIOCin(n)  BIT_ADDR(GPIOC_IDR_Addr,n) //GPIOC 某一位输入
#define GPIODout(n)  BIT_ADDR(GPIOD_ODR_Addr,n) //GPIOD 某一位输出
#define GPIODin(n)  BIT_ADDR(GPIOD_IDR_Addr,n) //GPIOD 某一位输入
#define GPIOEout(n)  BIT_ADDR(GPIOE_ODR_Addr,n) //GPIOE 某一位输出
#define G PIOEin(n)  BIT_ADDR(GPIOE_IDR_Addr,n) //GPIOE 某一位输入
#define GPIOFout(n)  BIT_ADDR(GPIOF_ODR_Addr,n) //GPIOF 某一位输出
#define GPIOFin(n)  BIT_ADDR(GPIOF_IDR_Addr,n) //GPIOF 某一位输入
#define GPIOGout(n)  BIT_ADDR(GPIOG_ODR_Addr,n) //GPIOG 某一位输出
#define GPIOGin(n)  BIT_ADDR(GPIOG_IDR_Addr,n) //GPIOG 某一位输入
#define GPIOHout(n)  BIT_ADDR(GPIOH_ODR_Addr,n) //GPIOH 某一位输出
#define GPIOHin(n)  BIT_ADDR(GPIOH_IDR_Addr,n) //GPIOH 某一位输入

/*************************************************************************/
#define LED1 GPIODout(12) // 定义 LED1 为 GPIOD_Pin_12
#define KEY1 GPIOCin(0) // 定义 KEY1 为 GPIOC_Pin_0
void GPIO_Configuration(void); // 函数声明
void Delay1(ulong x); / 函数声明
/******************************************************************************
*
* 函数名 : main
* 功能 : 主函数
* 输入 : None
* 输出 : None
* 返回 : None
***************************************************************************/
int main(void)
{
GPIO_Configuration();
while(1)
{
LED1=1; //LED 灯亮
Delay1(0XFFF);

LED1=0; //LED 灯灭
Delay1(0XFFF);
}
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2013-9-30 10:03:52 | 显示全部楼层
http://www.amobbs.com/forum.php? ... =%E4%BD%8D%E5%B8%A6 这个帖子说明白了····留个爪子···

出0入10汤圆

 楼主| 发表于 2013-9-30 10:55:29 | 显示全部楼层
kalo425 发表于 2013-9-30 10:03
http://www.amobbs.com/forum.php?mod=viewthread&tid=3785474&highlight=%E4%BD%8D%E5%B8%A6 这个帖子说明 ...

谢谢  我先试试 谢谢你了

出0入475汤圆

发表于 2017-7-16 10:56:08 | 显示全部楼层
本帖最后由 1a2b3c 于 2017-7-16 10:57 编辑

最近用到STM32F303,在修改IO的时候,觉得用库操作太麻烦了,要自己一个一个修改,用宏定义也不解决,自然就会想到用位带操作。查M4的手册知道M4也是支持位带操作,F3系列也是属于M4内核,而且在405也是用位带操作,觉得F303也是一样可以做位带操作。直接先修改一个IO,调试却发现在,IO电平始终没有变化。查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)
#define GPIOB_ODR_Addr    (GPIOB_BASE+20)
#define GPIOC_ODR_Addr    (GPIOC_BASE+20)
第一次地址映射操作是内核决定的,F3跟F4都是相同的,这里不会有错。查ODR寄存器的偏移地址:
_IO uint16_t ODR;          /*!< GPIO port output data register,                           Address offset: 0x14 */

ODR的地址偏移了0x14,也就是20,也是对的。F4都可以用位带操作,F3却用不了,就觉得很奇怪。放了一段时间,不死心,继续查找问题。调试,看汇编代码,在位带操作IO那里打断点





可以看到,操作寄存器的地址是0X42010290,查M3的GPIO地址,
#define GPIOC_BASE            (AHB2PERIPH_BASE + 0x0800)
#define AHB2PERIPH_BASE       (PERIPH_BASE + 0x08000000)
#define PERIPH_BASE           ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region */

也就是GPIOC的地址是0x48000800。这明显就对不上,位带操作的地址都不是对应GPIO的ODR,当然操作不了GPIO的电平,这下死心了。

死也要再死个明白,继续查M4的手册关于Memory System章节,可以看到位带操作地址有两个,Bit Band Region是直接位带操作(具体的可以百度),Bit Band Alias是间接位带操作,要做地址映射才能操作,所以才会BITBAND这个宏定义。只有寄存器的地址在Bit Badn Alias(0x42000000,0x43FFFFFF)地址区域内的才进行位带操作。F303的GPIO是属于AHB2,地址已经不在位置操作区域,所以地址映射后对应不是GPIO的寄存器,自然不能进行位带操作(ST这点也做得太坑了,为什么要把GPIO的归到AHB2)。M4的GPIO都在AHB1总线上,地址在位带操作地址区域自然可以用位带操作GPI,M1也是一样。


最近用F3也发现有问题的,找了一圈看到这个,以上是转来的,那么就是说F3不能实现这个功能了?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-22 05:32

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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