最近在学习stm32的FSMC,打算整一个LCD的驱动,然后封装的比正点原子更高层一些,方便后期直接调用
然后在学习的时候碰到了一个小问题,研究了一会之后觉得挺有意思的,所以记下来
//使用NOR/SRAM的 Bank1.sector4,地址位HADDR[27,26]=11 A6作为数据命令区分线 //注意设置时STM32内部会右移一位对其! 111 1110=0X7E #define LCD_BASE ((u32)(0x6C000000 | 0x0000007E)) #define LCD ((LCD_TypeDef *) LCD_BASE)
这是正点原子给的例程当中lcd.h文件的几行代码
他这里对于LCD_Base的地址是怎么来的解释的比较粗糙,其实是这样的
下图是中文手册的1194面有关FSMC的内容
可以看到FSMC存储区域是分成了四个部分,即Bank1-Bank4
通过计算也不难发现,这四个Bank所占用的内存大小是一样的
而在正点原子的例程当中,他使用的是Bank1,也就是起始地址是0x60000000
然后注释说HADDR[27:26] = 11
根据手册可以得出他使用的是存储区域1的第4区
由于Bank内部的四个存储区域的大小是一样的(因为本质上四个区域是相同的),所以这四个存储区域平均分了Bank1的地址,存储区1开始与0x60,存储区2开始于存储区0x64,存储区3开始于0x68,存储区4开始于0x6C
这就能解释通这个Bank1.sector4的起始地址是怎么得到的了
然后就是解释后面的0x7E
我们知道正点原子设置地址线并不是真的为了写地址,而是一个RS信号正好连在了地址线上面,通过这个RS信号来控制写入命令和数据
所以我们只需要关注RS信号对应的那个引脚,也就是A6引脚(Address 6),而我们的A0-A5这6个引脚是没有用的。
0x7E经过转换进制之后是01111110,但是stm32内部会将数据右移一位,也就是所有1往右移动1位,高位补0,即A6:A0 = 0111111,此时A6是0。
如果我们增加0x02,那么就会得到0x80,也就是10000000,这时候右移一位就是01000000,也就是A6是1,这就实现了RS信号的0和1的控制(这是对于8位地址而言的,当是16位地址的时候,我们增加0x01,就会得到01111111,此时不会进行右移对齐,A6是1)
关于8位地址和16位地址的右移问题,可以参照手册1195面
16位地址的时候,会进行一次右移,因为内部变化两个字节,外面就变化一个字节,所以只需要增加0x01就能达到和8位地址时增加0x02一样的效果了
标签:右移,存储,LCD,FSMC,地址,A6,正点,TFT From: https://www.cnblogs.com/Edwardssss/p/17028923.html