一段关于C语言结构体的程序

[复制链接]
4394|10
 楼主| liu_xf 发表于 2009-5-20 18:34 | 显示全部楼层 |阅读模式
typedef struct
{
  vu16 LCD_REG;
  vu16 LCD_RAM;
} LCD_TypeDef;
 
/* Note: LCD /CS is CE4 - Bank 4 of NOR/SRAM Bank 1~4 */
#define LCD_BASE        ((u32)(0x60000000 | 0x0C000000))
#define LCD             ((LCD_TypeDef *) LCD_BASE)

-----------
以上定义是不是给结构体定义一个基地址为0x6c000000,成员LCD_REG 的地址为0x6c000000,成员LCD_RAM 的地址为0x6c000001,

那如果我这样定义绝对地址,是不是和上面的一样
#define LCD_REG   ((u32)0x6c000000)
#define LCD_RAM   ((u32)0x6c000001)

----
在STM32单片机中用FSMC刷LCD用到这样的语句有点看不明白
耕在此行 发表于 2009-5-20 19:41 | 显示全部楼层

搞不懂

耕在此行 发表于 2009-5-20 19:42 | 显示全部楼层

指针也有结构类型的啊

呵呵 长见识了
zq1987731 发表于 2009-5-20 19:56 | 显示全部楼层

C语言里

    结构体本就是有个首地址,各个成员按顺序依次排列存储的,LZ完全可以自己定个结构体存些不同地数据然后在仿真窗口里看存储器内的摆放形式...

    #define LCD_REG   ((u32)0x6c000000)
    #define LCD_RAM   ((u32)0x6c000001)
    ...为什么用u32去强制转换呢?
    你的外部FSMC如果用到8位宽度,写控制或数据应该是下面这样:
    *((volatile UINT8 * )0x6C000001) = DATA;
    *((volatile UINT8 * )0x6C000000) = DATA;
    16位宽度的话应该是这样:
    *((volatile UINT16 * )0x6C000002) = DATA;
    *((volatile UINT16 * )0x6C000000) = DATA;
    指针【指向什么类型的数据】需要弄明白..同时别和“指针本身的内容(即地址内容)”搞混了~~
    
 楼主| liu_xf 发表于 2009-5-20 21:06 | 显示全部楼层

说明一下。。

FSMC的A0接至LCD的数据与命令选择端

A0为0时表示写命令
A0为1时表示写数据

 *((volatile UINT8 * )0x6C000001) = DATA;
 *((volatile UINT8 * )0x6C000000) = CMD;

我知道按楼上这样写法是可以的

但我有看到别人写的程序是这样的
typedef struct
{
  vu16 LCD_REG;
  vu16 LCD_RAM;
} LCD_TypeDef;

#define LCD             ((LCD_TypeDef *) 0x6c000000)

LCD->LCD_REG = CMD;
LCD->LCD_REG = DATA;

不知这两种表示方法是否一样。。。

zq1987731 发表于 2009-5-20 21:28 | 显示全部楼层

可以这么理解

    ((LCD_TypeDef *) 0x6c000000)是将0x6c000000地址开始的2个半字(现在看来数据总线是8位了)转换为LCD_TypeDef类型。
    那么宏定义用LCD取代后“LCD”代表的是结构体指针,“LCD->(LCD_REG或LCD_RAM”代表的是结构体成员,这时候由于LCD_REG成员是结构体中第一个成员,地址自然是0x6c000000,那么LCD_RAM成员的地址就是0x6c000001,两种方法当然起到一样的效果了...
未来是梦 发表于 2009-5-20 23:00 | 显示全部楼层

re

STM32例程里太多这样的东西了,一种风格吧。
把属性相同的REG组织在一个结构里,地址连续的就很好组织,可读性很好;

LCD_REG  的地址 0x6c000000   字长16bit。两个字节
LCD_RAM  的地址 0x6c000002   字长16bit。两个字节


 楼主| liu_xf 发表于 2009-5-20 23:11 | 显示全部楼层

摘一个例子

/*------------------------ General Purpose and Alternate Function IO ---------*/
typedef struct
{
  vu32 CRL;      //偏移0x00
  vu32 CRH;      //偏移0x04
  vu32 IDR;      //偏移0x08
  vu32 ODR;      //偏移0x0c
  vu32 BSRR;     //偏移0x10
  vu32 BRR;
  vu32 LCKR;
} GPIO_TypeDef;


#define GPIOA               ((GPIO_TypeDef *) 0x40018000)

   
GPIOA->BSRR = 0x1;  //PA0 置1

等同于

*((uv32 * )0x40018010) = 0x1;  //PA0 置1
 楼主| liu_xf 发表于 2009-5-20 23:14 | 显示全部楼层

按7楼的说法,那4楼的错了

应该是
   8位宽度
   *((volatile UINT8 * )0x6C000001) = DATA;
    *((volatile UINT8 * )0x6C000000) = DATA;
    16位宽度的话应该是这样:
    *((volatile UINT16 * )0x6C000002) = DATA;  //16位是两个字节,所以地址加2
    *((volatile UINT16 * )0x6C000000) = DATA;  
zq1987731 发表于 2009-5-21 07:59 | 显示全部楼层

回LS,这点倒是疏忽了

从自己代码中COPY来的,写着16位宽度却忘了+2...- -
alala2643 发表于 2015-9-18 11:29 | 显示全部楼层
:)谢谢上面各位大神,终于有点感觉了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

68

主题

372

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部