(一)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)

                                                            瘋子笔录

FSMC(STM32)的更多相关文章

  1. DMA(STM32)

     1.DMA:data memory access //实际的内存存储 注:DMA干活的时候是不须要CPU干涉的 2. ①内存(定义的变量)---外设(寄存器). ②内存---内存 ③外设---外 ...

  2. CAN通信(STM32)

    1.CAN是控制器局域网络(Controller Area Network, CAN)的简称 (理论知识不做讲解了,太多了) 2.芯片选用:TJA1050 差分信号输入, 这里的显性电平CANH和CA ...

  3. eBox(stm32) 之中断结构

    eBox的中断结构参考了mbed,和我们平时所用的中断结构有些差异,不容易理解,最近仔细看了底层代码,终于搞清楚了,总结一下         一  首先要要搞清楚的几个概念:类的静态成员,实例成员   ...

  4. stm32开发笔记一:使用固件库在RealView-MDK中新建工程(上)

    很久没有碰单片机了,两年了吧,因为项目需要,最近入手一块红牛的开发板,核心为STM32F103ZE.虽然以前做过大概半年的stm32的开发,现在天天在.net平台下写代码,已经忘记的差不多,恰逢周末, ...

  5. 嵌入式单片机STM32应用技术(课本)

    目录SAIU R20 1 6 第1页第1 章. 初识STM32..................................................................... ...

  6. (转)stm32启动文件详解

    在<<STM32不完全手册里面>>,用的是STM32F103RBT6,所有的例程都采用了一个叫STM32F10x.s的启动文件,里面定义了STM32的堆栈大小以及各种中断的名字 ...

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

    昨晚疯狂的打了一夜的LOL,感觉L多了,今天一天精神萎靡.还是继续把显示字符给看了,可是在犹豫要不要写这篇文章 事实上写的东西也就是copy别人家的代码,不想写那么多,就记录下自己困惑的地方吧.也许改 ...

  8. (stm32学习总结)—对寄存器的理解 _

    芯片里面有什么 我们看到的 STM32 芯片是已经封装好的成品,主要由内核和片上外设组成.若与电脑类比,内核与外设就如同电脑上的 CPU 与主板.内存.显卡.硬盘的关系.STM32F103 采用的是 ...

  9. (stm32学习总结)—LCD—液晶显示

    显示器简介 显示器属于计算机的 I/O 设备,即输入输出设备.它是一种将特定电子信息输出到屏幕上再反射到人眼的显示工具.常见的有 CRT 显示器.液晶显示器.LED 点阵显示器及OLED 显示器 本章 ...

随机推荐

  1. 最长上升子序列 OpenJ_Bailian - 2757 dp模板

    第一种是用以前状态更新当前状态(人人为我) 第二种是用当前状态更新以后状态(我为人人) 都是n^2代码: 对于人人为我的更新方法,可以用数据结构储存“人人”对其进行线性\二分优化. ; int a[m ...

  2. It is not based on WSGI, and it is typically run with only one thread per process.

    Tornado Web Server — Tornado 5.1.1 documentation http://www.tornadoweb.org/en/stable/

  3. SAPI

    https://en.wikipedia.org/wiki/Server_Application_Programming_Interface In computing, Server Applicat ...

  4. 前端开发组件化设计vue,react,angular原则漫谈

    前端开发组件化设计vue,react,angular原则漫谈 https://www.toutiao.com/a6346443500179505410/?tt_from=weixin&utm_ ...

  5. LoadRunner-迭代和并发设置

    迭代:指运行一次脚本时某段代码块(action)循环执行的次数,串行执行 并发:指同时运行脚本的次数,并行执行(多个用户同时跑) 以下是用例和对应的相关设置 Iterations是在Vuser Gen ...

  6. 洛谷P3527 MET-Meteors [POI2011] 整体二分

    正解:整体二分 解题报告: 传送门! 还有个双倍经验!(明明是一样的题目为什么你们一个紫一个黑啊喂! 这题首先要想到可以二分嘛,然后看到多组询问肯定就整体二分鸭 那就是基本套路啊,发现是区间修改单点查 ...

  7. [javascript]编码&i字符串格式化&nput历史记录&清空模态框

    js中编码问题 https://www.haorooms.com/post/js_escape_encodeURIComponent 我在前端js添加时候创建dom时候,有汉字,发现是乱码就研究了下 ...

  8. [py]字符串/列表

    去除str首尾空格(切片) ## str长度 循环,判断 ### [:i] [i:] 记录位置点 ## 方法1 def trim2(s): s2 = "" start = 0 en ...

  9. 更改docker服务网段分配地址

    docker安装完毕后,会自动生成一个网卡名为docker0的网桥,如果其默认分配的网段地址和已有地址段冲突,可按如下步骤修改. 查看默认地址段如下 docker0: flags=4099<UP ...

  10. webdriver模拟鼠标悬浮

    未经作者允许,禁止转载! 有时候会遇到这样的情况,鼠标停留在某一区域,不需要点击,悬浮在这一区域的上方就会显示该区域的下拉框,如下图 下面将鼠标停留在“日历”和“星座”这两个部分之间来回悬浮,下面是代 ...