OpenEdv-开源电子网

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

怎么像51一样,定义Bdata区变量,可以对每一位操作。

[复制链接]

33

主题

92

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
280
金钱
280
注册时间
2013-6-18
在线时间
15 小时
发表于 2013-6-19 10:32:21 | 显示全部楼层 |阅读模式
本人刚学习STM32,看见SRAM中有个1M的位带区,想像51样定义char,int,..变量,对每一位进行位操作。
///////////////////////////////////
bdata unsigned char dat;
sbit dat_0=dat^0;.
.
sbit dat_7=dat^7;
/////////////////////////////////////////////////////////////
STM32的位带区有2个一个是SRAM_bitband,和外设_bitband.

网上一般看到的是对外设中位带的操作,例如:
//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+12) //0x4001080C 
#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //输出 
//PAout(3)=1;就是对PA^3输出1. 
//////////////////////////////////////////////////////////////////
但是我想在SRAM中定义位变量,难道就是吧地址定义在 0x22000000 --0x23ffffff么?

#define DEVICE_REG0 ((volatile unsigned long *) (0x20000000))

    #define DEVICE_REG0_BIT0 ((volatile unsigned long *) (0x22000000))

    #define DEVICE_REG0_BIT1 ((volatile unsigned long *) (0x22000004))

    ...

    *DEVICE_REG0 = 0xAB;        

   *DEVICE_REG0_BIT1 = 0x1; // 通过位带别名地址设置 bit1

求大神,还有没有别简单的方法了。






















一知半解!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

26

主题

194

帖子

5

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1175
金钱
1175
注册时间
2011-8-20
在线时间
21 小时
发表于 2014-5-24 15:07:24 | 显示全部楼层
你的意思是想操作一个变量的每一位吧,跟51单片机sbit一样,每一位取一个名字,然后单独操作。
你可以用结构体位域试试,例如定义一个类型


然后定义一个变量uint8_type dat;  你可以用dat.B=0x55将整个字节赋值0x55,也可以用dat.A.a=0  dat.A.d=1这样对这个字节的某位(几位)进行操作。
类似于51单片机的P0=0x55, sbit LED = P0^1, LED=1这样的操作。
A和B占用同一个空间,sizeof(uint8_type)为1字节。
关联到硬件上,就和你的(u32 *)(0x20000000)一样了
#define PORT (*(uint8_type* )(0x20000))
PORT.A.a = 1;
for( int i=0; i<(1.0/0); i++ ) { for( int j=0; j<365; j++) money ++; age ++; if( age > 30 ) ChangeJob( Boss ); } 脸上的痘痘提醒我?我还年轻?口袋的米米告诉我?我仍需努力
回复 支持 1 反对 0

使用道具 举报

30

主题

705

帖子

1

精华

新手上路

积分
21
金钱
21
注册时间
2013-3-14
在线时间
52 小时
发表于 2013-6-19 10:53:34 | 显示全部楼层
GPIO_ResetBits(GPIOD, GPIO_Pin_7);
GPIO_SetBits(GPIOD, GPIO_Pin_7);
如此调用即可。
原子哥是不是又要出黑科技了呀。^_^...
回复 支持 反对

使用道具 举报

30

主题

705

帖子

1

精华

新手上路

积分
21
金钱
21
注册时间
2013-3-14
在线时间
52 小时
发表于 2013-6-19 10:54:31 | 显示全部楼层
GPIO_SetBits(GPIOD,GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);
操作多个IO。
原子哥是不是又要出黑科技了呀。^_^...
回复 支持 反对

使用道具 举报

33

主题

92

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
280
金钱
280
注册时间
2013-6-18
在线时间
15 小时
 楼主| 发表于 2013-6-19 11:08:51 | 显示全部楼层
回复【3楼】fanghuiopenedv:
---------------------------------
你说的这个是对外设的位带操作,(也就是内部寄存器),我需要的是对SRAM中的位带操作(是存储单元),我想要的是定义变量比如
u8 dat;dat是变量,不是寄存器。上面我说的是网上看的,自己试了下,有点小问题。自己写的:
#define dat ((u32 *)(0x20000000))
#define dat_0  ((u32 *)(0x22000000))
#define dat_1  ((u32 *)(0x22000004))
#define dat_2  ((u32 *)(0x22000008))
#define dat_3  ((u32 *)(0x2200000c))
#define dat_4  ((u32 *)(0x22000010))
#define dat_5  ((u32 *)(0x22000014))
#define dat_6  ((u32 *)(0x22000018))
#define dat_7  ((u32 *)(0x2200001c))

int main()
{
*dat=0xaa;
// *dat_0=1;
// *dat_1=1;
// *dat_2=1;
// *dat_3=1;
// *dat_4=1;
// *dat_5=1;
// *dat_6=1;
// *dat_7=1;
while(1);
}
问题如下:
当*dat=0xaa;时内存单元里0x20000000的值是0xaa;这个没有错,但是(自己的想法)既然是位操作,每一位应该是一一对应的,但是我查看0x22000000,0x22000004......的值(dat_0--dat_7)却不是1,0,1,0,1,0,1,0,求解,反过来改变dat_0---dat_7的值,
0x20000000的值(dat)却是对的了,求解
一知半解!
回复 支持 反对

使用道具 举报

30

主题

705

帖子

1

精华

新手上路

积分
21
金钱
21
注册时间
2013-3-14
在线时间
52 小时
发表于 2013-6-19 11:21:08 | 显示全部楼层
不用宏定义用指针应该可以的吧。宏定义的话就不知道对不对了。
原子哥是不是又要出黑科技了呀。^_^...
回复 支持 反对

使用道具 举报

33

主题

92

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
280
金钱
280
注册时间
2013-6-18
在线时间
15 小时
 楼主| 发表于 2013-6-19 11:23:07 | 显示全部楼层
回复【4楼】liawei123:
---------------------------------
原来看内存是看不出来的,不过我用串口输出对应的dat_0-----dat_7的值是对的,>_<||| 。不过还是谢谢你们了。
一知半解!
回复 支持 反对

使用道具 举报

7

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
79
金钱
79
注册时间
2014-5-14
在线时间
0 小时
发表于 2014-5-24 13:32:15 | 显示全部楼层
回复【2楼】fanghuiopenedv:
---------------------------------
求助——GPIO _SetBits和GPIO_ResetBits函数在哪个头文件里,也就是要调用,需要包含那个文件 
同样的   LCD_RD_data()
回复 支持 反对

使用道具 举报

30

主题

705

帖子

1

精华

新手上路

积分
21
金钱
21
注册时间
2013-3-14
在线时间
52 小时
发表于 2014-5-24 13:59:55 | 显示全部楼层
回复【7楼】hyd:
---------------------------------
stm32f10x_gpio.c里面有定义的。
原子哥是不是又要出黑科技了呀。^_^...
回复 支持 反对

使用道具 举报

7

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
79
金钱
79
注册时间
2014-5-14
在线时间
0 小时
发表于 2014-5-24 18:28:30 | 显示全部楼层
回复【9楼】subo19920716:
---------------------------------
这是其中一些代码,编译运行时, GPIO_ResetBits(GPIOD,GPIO_Pin_4);GPIO_SetBits(GPIOD, GPIO_Pin_4);没有被定义,我想问的是 GPIO_ResetBits()和GPIO_SetBits()两个函数在函数库里有没有,可以直接调用;还是要自己写。谢谢!!!
u16 LCD_ReadPoint(u16 x,u16 y)
{        
        if(x>=240||y>=320)return 0;//超过了范围,直接返回                   
        LCD_SetCursor(x,y);
        LCD_WR_REG(0x22);       //选择GRAM地址 
        GPIO_SetBits(GPIOD, GPIO_Pin_11);
        GPIO_ResetBits(GPIOD, GPIO_Pin_7);                                  
        //读取数据(读GRAM时,需要读2次)
        GPIO_ResetBits(GPIOD,GPIO_Pin_4);                                            
GPIO_SetBits(GPIOD, GPIO_Pin_4);
        //dummy READ
        GPIO_ResetBits(GPIOD, GPIO_Pin_4);                                           
        GPIO_SetBits(GPIOD, GPIO_Pin_4); 
        return LCD_BGR2RGB(LCD_RD_data());
}
回复 支持 反对

使用道具 举报

16

主题

253

帖子

0

精华

高级会员

Rank: 4

积分
565
金钱
565
注册时间
2013-10-16
在线时间
52 小时
发表于 2014-6-18 17:06:21 | 显示全部楼层
回复【9楼】subo19920716:
---------------------------------
你好,我按照你这个操作怎么不行的,谢谢
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-7 04:47

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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