FSMC(STM32)



(一)FSMC:Flexible Static Memory Controller,可变(灵活)静态存储控制器

小容量产品是指闪存存储器容量在1 6K至32K字节之间的STM32F101xx、STM32F102xx和

STM32F103xx微控制器。

中容量产品是指闪存存储器容量在64K至128K字节之间的STM32F101xx、STM32F102xx和

STM32F103xx微控制器。

大容量产品是指闪存存储器容量在256K至512K字节之间的STM32F101xx和STM32F103xx微控

制器。

互联型产品是指STM32F105xx和STM32F107xx微控制器。

对于M3来说

然后将这1.0GB的外存分为4个大块

1,为什么每一块中每一片是64M?

答:我们知道地址线26跟,2的26次方等于64M,所以每个块是64M,

2,为什么每一块中是4片?

答:它这里有一个很巧妙的方法每一个块有4个片选,以方便我们使用那一片;

故:1.0GB =  (4*64)*4

以下例程我们的液晶是接在Bank1中的第4片;

先看下接口图(野火板子)

1,为什么是片4?

答:

我们的LCD_CS接在了FSMC_NE4的片选4端(说白了是:液晶的内存与FSMC要相互对应)

2,为什么是块1?

答:因为液晶里面的RAM相当于NOR FLASH,或者PSRAM,所以最好用块1

3,为什么低电平电量点亮屏幕呢?

答:看下图

对于38,39管脚的控制使用一个PNP三极管,当LIGHT低电平时 导通。

为什么接PB1?

答:PB1通过有PWM调制功能

4,对于读写控制可参考图中注解,但主要对于不同的液晶控制芯片读写控制可能有所差异。

如图9341

RS 我们接的是FSMC_A23,那么我们控制FSMC的地址线23就可以控制发送命令还是数据了

程序讲解:

1,加载ili9341驱动文件

2,打开

/* #include "stm32f10x_flash.h" */
#include "stm32f10x_fsmc.h"

3,端口配置

4,工作模式配置(参考ili9341手册)

void LCD_FSMC_Config(void)
{
    FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
    FSMC_NORSRAMTimingInitTypeDef  p; 

    p.FSMC_AddressSetupTime = 0x02;	 //地址建立时间
    p.FSMC_AddressHoldTime = 0x00;	 //地址保持时间
    p.FSMC_DataSetupTime = 0x05;		 //数据建立时间
    p.FSMC_BusTurnAroundDuration = 0x00;
    p.FSMC_CLKDivision = 0x00;
    p.FSMC_DataLatency = 0x00;
    p.FSMC_AccessMode = FSMC_AccessMode_B;	 // 一般使用模式B来控制LCD

    FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM4;
    FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
    //FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;
  FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;
    FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
    FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
    FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
    FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
    FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
    FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
    FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
    FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
    FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
    FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
    FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;  

    FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
    FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE);
}

FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM4;//此处我们用到了bank1的第四片

FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM4;//此处我们用到了bank1的第四片

5,液晶软件复位(低电平复位,切记高电平要保持一下)

void LCD_Rst(void)
{
		GPIO_ResetBits(GPIOG, GPIO_Pin_11);	 //低电平复位
    Lcd_Delay(0xAFFf<<2);
    GPIO_SetBits(GPIOG, GPIO_Pin_11);
    Lcd_Delay(0xAFFf<<2);
}

6,写命令、数据

void LCD_REG_Config(void)

这里介绍一下写命令与写数据函数

	LCD_ILI9341_CMD(0xCF);      //写命令
	LCD_ILI9341_Parameter(0x00);   //写数据

如下:

#define Bank1_LCD_C    ((u32)0x6C000000)	   //Disp Reg ADDR
#define Bank1_LCD_D    ((u32)0x6D000000)       //Disp Data ADDR       // A23 PE2

//选定LCD指定寄存器
#define LCD_WR_REG(index)    ((*(__IO u16 *) (Bank1_LCD_C)) = ((u16)index))
//往LCD GRAM写入数据
#define LCD_WR_Data(val)       ((*(__IO u16 *) (Bank1_LCD_D)) = ((u16)(val)))

#define LCD_ILI9341_CMD(index)       LCD_WR_REG(index)
#define LCD_ILI9341_Parameter(val)	 LCD_WR_Data(val)

解释如下:

当主控对指针量(地址)0x6D000000操作,FSMC_A23为高电平,此时为写数据;

操作顺序: CPU作用于FSMC外设,FSMC内存块作用于TFT的GRAM。

可理解CPU向0x6C000000,0x6D000000该地址写入数据,即使操作FSMC的块1的片选4,后导致FSMC外设地址线和数据线管脚的变化;

为什么2^23 还要*2 ?

答:

在外部设备是16位时,连接到内部地址总线 HADDR时 左移一位,0-1,,,,24-25;所以为了满足对应关系,我们要将指针量*2,才能找出正确的地址后与之对应;

若连接其他的地址线,那么计算方式一样。

7,扫描方式

	DEBUG_DELAY();
	LCD_ILI9341_CMD(0x36);
	LCD_ILI9341_Parameter(0xC8);    //竖屏  左上角(起点)到右下角(终点)扫描方式
	DEBUG_DELAY();

向“36” 寄存器 写对应指令就成

	/* column address control set */   X轴
	LCD_ILI9341_CMD(0X2A);
	LCD_ILI9341_Parameter(0x00);    //低八位  0
	LCD_ILI9341_Parameter(0x00);   //高八位
	LCD_ILI9341_Parameter(0x00);  
	LCD_ILI9341_Parameter(0xEF);       0XEF = 239

	/* page address control set */   Y轴
	DEBUG_DELAY();
	LCD_ILI9341_CMD(0X2B);
	LCD_ILI9341_Parameter(0x00);        0
	LCD_ILI9341_Parameter(0x00);
	LCD_ILI9341_Parameter(0x01);
	LCD_ILI9341_Parameter(0x3F);       0X13F = 319  

---------------------------------------------------------------------------

函数部分:

①清屏函数(源)

void LCD_Clear(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color)

如清掉整个屏幕

LCD_Clear(0, 0, 240, 320, BACKGROUND);

②设置坐标点(源)

void LCD_SetCursor(uint16_t x, uint16_t y)

③ 开窗(源)

界限设置,不然就不会反过来写(第一行写完,然后从第二行写),调整地址指针

void LCD_OpenWindow(uint16_t x, uint16_t y, uint16_t width, uint16_t height)

④画点(源)

一切一切的本源

void LCD_SetPoint(uint16_t x , uint16_t y , uint16_t color)
{
	LCD_SetCursor(x, y);
	LCD_ILI9341_CMD(0x2c);
	LCD_WR_Data(color);
}

⑤颜色(源)

uint16_t LCD_RD_data(void)
{
	uint16_t R=0, G=0, B=0 ;

	R = *(__IO uint16_t *)Bank1_LCD_D; 	  /*FIRST READ OUT DUMMY DATA*/
	R = *(__IO uint16_t *)Bank1_LCD_D;  	/*READ OUT RED DATA  */
	B = *(__IO uint16_t *)Bank1_LCD_D;  	/*READ OUT BLACK DATA*/
	G = *(__IO uint16_t *)Bank1_LCD_D;  	/*READ OUT GREEN DATA*/
      //将地址转换成指针,对指针进行操作

    return (((R>>11)<<11) | ((G>>10)<<5) | (B>>11));  //转换成16位宽度
}

⑥显示一个字符(源)

void LCD_DispChar(uint16_t x, uint16_t y, uint8_t ascii, uint16_t color)

如:LCD_DispChar(60, 60, ‘A‘, RED); //对应有效的地方写该颜色,这个函数也是独立的;

当然在用之前要有自己对应的的字库

⑦显示一个字符串

void LCD_DispStr(uint16_t x, uint16_t y, uint8_t *pstr, uint16_t color)

如:

LCD_DispStr(10, 10, (uint8_t *)"This is a lcd demo to display ascii", RED);

⑧显示数字

这个说白还是用到LCD_DispChar

void LCD_DisNum(uint16_t x, uint16_t y, uint32_t num, uint16_t color)

                                                            瘋子笔录

时间: 2024-11-06 09:35:33

FSMC(STM32)的相关文章

DMA(STM32)

1.DMA:data memory access //实际的内存存储 注:DMA干活的时候是不需要CPU干涉的 2. ①内存(定义的变量)---外设(寄存器): ②内存---内存 ③外设---外设(一个外设的寄存器到另一个外设的寄存器) 3. STM32有两个DMA控制器 如图: 4.举例说明:(内存到外设,串口1 TX DMA) 1 void USART1_DMA_Config(void) 2 { 3 DMA_InitTypeDef DMA_InitStructure; 4 5 /*Open

CAN通信(STM32)

1.CAN是控制器局域网络(Controller Area Network, CAN)的简称 (理论知识不做讲解了,太多了) 2.芯片选用:TJA1050 差分信号输入, 这里的显性电平CANH和CANL压差是2V左右,逻辑上表示“0” 两线之间没有压差CANH和CANL都是2.5V左右,表示逻辑“1” (二)实现代码 1. /* 配置CAN模块*/ CAN_Config(); void CAN_Config(void){①CAN_GPIO_Config();   //此处用PB8/PB9 CA

2019年9月19日星期四(STM32)

一.RTC(实时时钟) 1.背景 时间在计算机系统中是一个非常重要的参数,在很多应用场景下都需要使用时间.RTC就是一个专门记录时间的设备,本质上是一个1Hz定时器. 为了计时准确,计时系统掉电也要能够正常计时.为了到达这个目的,RTC需要独立的时钟源,独立的供电电源 stm32f407的RTC的时钟源是低速晶振(LSE---32.768KHz),使用纽扣电池单独供电 2.stm32f407的RTC RTC进行2次预分频,一次7位异步和15位的同步,最终得到1hz的时钟,为了降低功耗,异步预分频

简单背后的不简单&mdash;&mdash;初识arduino(stm32)

每一篇博文都是本人原创,禁止转载 知道arduino是在上大学的时候,但是在很多做单片机 开发的人眼中看来,arduino是给外行人玩的,因此自诩为专业嵌入式开发的很多人(当然也包括我)对这种东西当然是不屑的.因为机缘巧合,我有了一种想要学习arduino软件构架的想法,因为最早的arduino的是基于avr单片机,我手头没有相关的硬件,因此我打算使用目前广泛使用的stm32的单片机开始对arduino的背后代码的研究. 最早开发arduino对stm32支持的是LeafsLabs公司( htt

STM32学习之路-LCD(2)&lt;LCD初始化&gt;

这些天一直在研究LCD的初始化函数,因为不过是用IO口模拟时序还是用FSMC来驱动LCD,都必须要弄好LCD的初始化 其实LCD的初始化就是跟着LCD IC的datasheet来写寄存器,大部分都使用上面的默认值,网上有很多修改的例子,这里就不 放出来了.但是我想写下一些比较重要的东西. 这是从网上下载来的一个文件的前半部分: 当然,别的型号的IC也是有这些东西的,不过可能有些地址不同而已. R0,这个命令有两个功能,如果对它写,则最低位为OSC,用于开启和关闭振荡器.而如果对它读操作, 则返回

STM32学习经验(补充)

2016/3/23 1.      今天把普中开发板上的RS232芯片烧坏了,所以接下来要完成stlink的使用,来下载程序,同时也尝试调试程序,也算是被逼的去学一个很有用的工具,本来我都不想学stlink的. 2.      先学习一下stm32的定时器,过程中,加入stlink的下载和调试. 3.      定时器:stm32分高级定时器(TIM1和TIM8),通用定时器(TIM2-5),基本定时器(TIM6,7). 4.      通用定时器(TIM2-5):1)位于低速APB1总线上.2

STM32学习之路-LCD(4)&amp;lt;显示字符&amp;gt;

昨晚疯狂的打了一夜的LOL,感觉L多了,今天一天精神萎靡.还是继续把显示字符给看了,可是在犹豫要不要写这篇文章 事实上写的东西也就是copy别人家的代码,不想写那么多,就记录下自己困惑的地方吧.也许改天回来看的时候能让自己高速的明确 也也许能帮助到有些朋友.. 看了奋斗给的样例和偷偷去下了正点原子的样例,事实上都是差点儿相同的,仅仅要略微改下都能够通用的,原理就在那里,跑不了. 奋斗给的样例,都是人家的 void lcd_wr_zf(u16 StartX, u16 StartY, u16 X,

STM32之输入捕获以及小小应用(库)

五一之际,先祝大家五一快乐.其实快乐很简单,工作的人有假放,学习的人也有假放,像我,有假放才有更多的时间学自己想学的东西.51假期学51,可惜没有32假期呀.好了..言归正传,大家听过吸星大法吧..在这里.智商和情商比我高的人估计又知道我要说什么了..没错了..今天我们来了解"葵花宝典"第STM32篇之输入捕获,也就是上文所讲的"吸星大法", 那输入捕获可以用来干嘛呢??这个问题问的好,输入捕获可以用来测量脉冲宽度或者测量频率,假如要捕获一个脉冲的高电平脉宽,我们要

嵌入式开发之 STM32自行车码表(图文)

笔者将从以下几个方面逐步深入地讲解STM32F103C8开发板的使用,并在Windows下编写一个简单的自行车码表程序: 元器件 环境搭建 电路连接 一个简单的LED闪烁程序 自行车码表 准备工作之 元器件 准备工作之 电路连接 准备工作之 环境搭建 CubeMX配置 KeilST-LINK下载程序调试程序 下载并注册安装Keil Keil安装程序及注册机 用keil打开CubeMX生成的工程文件 build keilST-LINK下载和调试以blink为例 出错误了 解决方法一 解决方法二 连