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,port配置
?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來控制LCDFSMC_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); //低八位 0LCD_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); 0LCD_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)?
?
? 瘋子筆錄
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
版權聲明:本文博客原創文章。博客,未經同意,不得轉載。
轉載于:https://www.cnblogs.com/gcczhongduan/p/4741900.html
總結
以上是生活随笔為你收集整理的FSMC(STM32)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 某web笔试
- 下一篇: 要有被打断仍能够继续学习的能力