友快網

導航選單

學習STM32程式設計——LCD顯示實驗

關鍵程式碼:

lcd。c

//寫暫存器函式//regval:暫存器值void LCD_WR_REG(vu16 regval){ regval=regval; //使用-O2最佳化的時候,必須插入的延時 LCD->LCD_REG=regval;//寫入要寫的暫存器序號 }//寫LCD資料//data:要寫入的值void LCD_WR_DATA(vu16 data){ data=data; //使用-O2最佳化的時候,必須插入的延時 LCD->LCD_RAM=data; }//讀LCD資料//返回值:讀到的值u16 LCD_RD_DATA(void){ vu16 ram; //防止被最佳化 ram=LCD->LCD_RAM; return ram; } //寫暫存器//LCD_Reg:暫存器地址//LCD_RegValue:要寫入的資料void LCD_WriteReg(u16 LCD_Reg,u16 LCD_RegValue){ LCD->LCD_REG = LCD_Reg; //寫入要寫的暫存器序號 LCD->LCD_RAM = LCD_RegValue;//寫入資料 } //讀暫存器//LCD_Reg:暫存器地址//返回值:讀到的資料u16 LCD_ReadReg(u16 LCD_Reg){ LCD_WR_REG(LCD_Reg); //寫入要讀的暫存器序號 delay_us(5); return LCD_RD_DATA(); //返回讀到的值} //開始寫GRAMvoid LCD_WriteRAM_Prepare(void){ LCD->LCD_REG=lcddev。wramcmd; } //LCD寫GRAM//RGB_Code:顏色值void LCD_WriteRAM(u16 RGB_Code){ LCD->LCD_RAM = RGB_Code;//寫十六位GRAM}//讀取個某點的顏色值 //x,y:座標//返回值:此點的顏色u16 LCD_ReadPoint(u16 x,u16 y){ u16 r=0,g=0,b=0; if(x>=lcddev。width||y>=lcddev。height)return 0; //超過了範圍,直接返回 LCD_SetCursor(x,y); if (lcddev。id == 0X5510) //5510 傳送讀GRAM指令 { LCD_WR_REG(0X2E00); } else //其他IC(9341/5310/1963/7789)傳送讀GRAM指令 { LCD_WR_REG(0X2E); } r=LCD_RD_DATA(); //dummy Read if (lcddev。id == 0X1963) //對1963來說,是真讀 { return r; //1963直接讀就可以 } r = LCD_RD_DATA(); //實際座標顏色 //9341/5310/5510/7789 要分2次讀出 b = LCD_RD_DATA(); g = r & 0XFF; //對於 9341/5310/5510/7789, 第一次讀取的是RG的值,R在前,G在後,各佔8位 g <<= 8; return (((r >> 11) << 11) | ((g >> 10) << 5) | (b >> 11)); // 9341/5310/5510/7789 需要公式轉換一下} //LCD開啟顯示void LCD_DisplayOn(void){ if (lcddev。id == 0X5510) //5510開啟顯示指令 { LCD_WR_REG(0X2900); //開啟顯示 } else //9341/5310/1963/7789 等傳送開啟顯示指令 { LCD_WR_REG(0X29); //開啟顯示 }}//LCD關閉顯示void LCD_DisplayOff(void){ if (lcddev。id == 0X5510) //5510關閉顯示指令 { LCD_WR_REG(0X2800); //關閉顯示 } else //9341/5310/1963/7789 等傳送關閉顯示指令 { LCD_WR_REG(0X28); //關閉顯示 }}//設定游標位置//Xpos:橫座標//Ypos:縱座標void LCD_SetCursor(u16 Xpos, u16 Ypos){ //9341/5310/7789等設定座標 { LCD_WR_REG(lcddev。setxcmd); LCD_WR_DATA(Xpos >> 8); LCD_WR_DATA(Xpos & 0XFF); LCD_WR_REG(lcddev。setycmd); LCD_WR_DATA(Ypos >> 8); LCD_WR_DATA(Ypos & 0XFF); }}//畫點//x,y:座標//POINT_COLOR:此點的顏色void LCD_DrawPoint(u16 x,u16 y){ LCD_SetCursor(x,y); //設定游標位置 LCD_WriteRAM_Prepare(); //開始寫入GRAM LCD->LCD_RAM=POINT_COLOR; }//SSD1963 背光設定//pwm:背光等級,0~100。越大越亮。void LCD_SSD_BackLightSet(u8 pwm){ LCD_WR_REG(0xBE); //配置PWM輸出 LCD_WR_DATA(0x05); //1設定PWM頻率 LCD_WR_DATA(pwm*2。55);//2設定PWM佔空比 LCD_WR_DATA(0x01); //3設定C LCD_WR_DATA(0xFF); //4設定D LCD_WR_DATA(0x00); //5設定E LCD_WR_DATA(0x00); //6設定F}//初始化lcd//該初始化函式可以初始化各種ILI93XX液晶,但是其他函式是基於ILI9320的!!!//在其他型號的驅動晶片上沒有測試! void LCD_Init(void){ vu32 i=0; GPIO_InitTypeDef GPIO_InitStructure; FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure; FSMC_NORSRAMTimingInitTypeDef readWriteTiming; FSMC_NORSRAMTimingInitTypeDef writeTiming; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOD|RCC_AHB1Periph_GPIOE|RCC_AHB1Periph_GPIOF|RCC_AHB1Periph_GPIOG, ENABLE);//使能PD,PE,PF,PG時鐘 RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC,ENABLE);//使能FSMC時鐘 GPIO_InitStructure。GPIO_Pin = GPIO_Pin_15;//PB15 推輓輸出,控制背光 GPIO_InitStructure。GPIO_Mode = GPIO_Mode_OUT;//普通輸出模式 GPIO_InitStructure。GPIO_OType = GPIO_OType_PP;//推輓輸出 GPIO_InitStructure。GPIO_Speed = GPIO_Speed_50MHz;//100MHz GPIO_InitStructure。GPIO_PuPd = GPIO_PuPd_UP;//上拉 GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化 //PB15 推輓輸出,控制背光 GPIO_InitStructure。GPIO_Pin = (3<<0)|(3<<4)|(7<<8)|(3<<14);//PD0,1,4,5,8,9,10,14,15 AF OUT GPIO_InitStructure。GPIO_Mode = GPIO_Mode_AF;//複用輸出 GPIO_InitStructure。GPIO_OType = GPIO_OType_PP;//推輓輸出 GPIO_InitStructure。GPIO_Speed = GPIO_Speed_100MHz;//100MHz GPIO_InitStructure。GPIO_PuPd = GPIO_PuPd_UP;//上拉 GPIO_Init(GPIOD, &GPIO_InitStructure);//初始化 GPIO_InitStructure。GPIO_Pin = (0X1FF<<7);//PE7~15,AF OUT GPIO_InitStructure。GPIO_Mode = GPIO_Mode_AF;//複用輸出 GPIO_InitStructure。GPIO_OType = GPIO_OType_PP;//推輓輸出 GPIO_InitStructure。GPIO_Speed = GPIO_Speed_100MHz;//100MHz GPIO_InitStructure。GPIO_PuPd = GPIO_PuPd_UP;//上拉 GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化 GPIO_InitStructure。GPIO_Pin = GPIO_Pin_12;//PF12,FSMC_A6 GPIO_InitStructure。GPIO_Mode = GPIO_Mode_AF;//複用輸出 GPIO_InitStructure。GPIO_OType = GPIO_OType_PP;//推輓輸出 GPIO_InitStructure。GPIO_Speed = GPIO_Speed_100MHz;//100MHz GPIO_InitStructure。GPIO_PuPd = GPIO_PuPd_UP;//上拉 GPIO_Init(GPIOF, &GPIO_InitStructure);//初始化 GPIO_InitStructure。GPIO_Pin = GPIO_Pin_12;//PF12,FSMC_A6 GPIO_InitStructure。GPIO_Mode = GPIO_Mode_AF;//複用輸出 GPIO_InitStructure。GPIO_OType = GPIO_OType_PP;//推輓輸出 GPIO_InitStructure。GPIO_Speed = GPIO_Speed_100MHz;//100MHz GPIO_InitStructure。GPIO_PuPd = GPIO_PuPd_UP;//上拉 GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化 GPIO_PinAFConfig(GPIOD,GPIO_PinSource0,GPIO_AF_FSMC);//PD0,AF12 GPIO_PinAFConfig(GPIOD,GPIO_PinSource1,GPIO_AF_FSMC);//PD1,AF12 GPIO_PinAFConfig(GPIOD,GPIO_PinSource4,GPIO_AF_FSMC); GPIO_PinAFConfig(GPIOD,GPIO_PinSource5,GPIO_AF_FSMC); GPIO_PinAFConfig(GPIOD,GPIO_PinSource8,GPIO_AF_FSMC); GPIO_PinAFConfig(GPIOD,GPIO_PinSource9,GPIO_AF_FSMC); GPIO_PinAFConfig(GPIOD,GPIO_PinSource10,GPIO_AF_FSMC); GPIO_PinAFConfig(GPIOD,GPIO_PinSource14,GPIO_AF_FSMC); GPIO_PinAFConfig(GPIOD,GPIO_PinSource15,GPIO_AF_FSMC);//PD15,AF12 GPIO_PinAFConfig(GPIOE,GPIO_PinSource7,GPIO_AF_FSMC);//PE7,AF12 GPIO_PinAFConfig(GPIOE,GPIO_PinSource8,GPIO_AF_FSMC); GPIO_PinAFConfig(GPIOE,GPIO_PinSource9,GPIO_AF_FSMC); GPIO_PinAFConfig(GPIOE,GPIO_PinSource10,GPIO_AF_FSMC); GPIO_PinAFConfig(GPIOE,GPIO_PinSource11,GPIO_AF_FSMC); GPIO_PinAFConfig(GPIOE,GPIO_PinSource12,GPIO_AF_FSMC); GPIO_PinAFConfig(GPIOE,GPIO_PinSource13,GPIO_AF_FSMC); GPIO_PinAFConfig(GPIOE,GPIO_PinSource14,GPIO_AF_FSMC); GPIO_PinAFConfig(GPIOE,GPIO_PinSource15,GPIO_AF_FSMC);//PE15,AF12 GPIO_PinAFConfig(GPIOF,GPIO_PinSource12,GPIO_AF_FSMC);//PF12,AF12 GPIO_PinAFConfig(GPIOG,GPIO_PinSource12,GPIO_AF_FSMC); readWriteTiming。FSMC_AddressSetupTime = 0XF; //地址建立時間(ADDSET)為16個HCLK 1/168M=6ns*16=96ns readWriteTiming。FSMC_AddressHoldTime = 0x00; //地址保持時間(ADDHLD)模式A未用到 readWriteTiming。FSMC_DataSetupTime = 60; //資料儲存時間為60個HCLK =6*60=360ns readWriteTiming。FSMC_BusTurnAroundDuration = 0x00; readWriteTiming。FSMC_CLKDivision = 0x00; readWriteTiming。FSMC_DataLatency = 0x00; readWriteTiming。FSMC_AccessMode = FSMC_AccessMode_A; //模式A writeTiming。FSMC_AddressSetupTime =9; //地址建立時間(ADDSET)為9個HCLK =54ns writeTiming。FSMC_AddressHoldTime = 0x00; //地址保持時間(A writeTiming。FSMC_DataSetupTime = 8; //資料儲存時間為6ns*9個HCLK=54ns writeTiming。FSMC_BusTurnAroundDuration = 0x00; writeTiming。FSMC_CLKDivision = 0x00; writeTiming。FSMC_DataLatency = 0x00; writeTiming。FSMC_AccessMode = FSMC_AccessMode_A; //模式A FSMC_NORSRAMInitStructure。FSMC_Bank = FSMC_Bank1_NORSRAM4;// 這裡我們使用NE4 ,也就對應BTCR[6],[7]。 FSMC_NORSRAMInitStructure。FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; // 不復用資料地址 FSMC_NORSRAMInitStructure。FSMC_MemoryType =FSMC_MemoryType_SRAM;// FSMC_MemoryType_SRAM; //SRAM FSMC_NORSRAMInitStructure。FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;//儲存器資料寬度為16bit FSMC_NORSRAMInitStructure。FSMC_BurstAccessMode =FSMC_BurstAccessMode_Disable;// FSMC_BurstAccessMode_Disable; FSMC_NORSRAMInitStructure。FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; FSMC_NORSRAMInitStructure。FSMC_AsynchronousWait=FSMC_AsynchronousWait_Disable; 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_Enable; // 讀寫使用不同的時序 FSMC_NORSRAMInitStructure。FSMC_WriteBurst = FSMC_WriteBurst_Disable; FSMC_NORSRAMInitStructure。FSMC_ReadWriteTimingStruct = &readWriteTiming; //讀寫時序 FSMC_NORSRAMInitStructure。FSMC_WriteTimingStruct = &writeTiming; //寫時序 FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); //初始化FSMC配置 FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE); // 使能BANK1 delay_ms(50); // delay 50 ms //嘗試9341 ID的讀取 LCD_WR_REG(0XD3); lcddev。id=LCD_RD_DATA(); //dummy read lcddev。id=LCD_RD_DATA(); //讀到0X00 lcddev。id=LCD_RD_DATA(); //讀取93 lcddev。id<<=8; lcddev。id|=LCD_RD_DATA(); //讀取41 if(lcddev。id==0X9341||lcddev。id == 0X7789 ||lcddev。id==0X5310||lcddev。id==0X5510||lcddev。id==0X1963)//如果是這幾個IC,則設定WR時序為最快 { //重新配置寫時序控制暫存器的時序 FSMC_Bank1E->BWTR[6]&=~(0XF<<0);//地址建立時間(ADDSET)清零 FSMC_Bank1E->BWTR[6]&=~(0XF<<8);//資料儲存時間清零 FSMC_Bank1E->BWTR[6]|=3<<0; //地址建立時間(ADDSET)為3個HCLK =18ns if(lcddev。id == 0X7789) { FSMC_Bank1E->BWTR[6]|=3<<8; //資料儲存時間(DATAST)為6ns*3個HCLK=18ns } else { FSMC_Bank1E->BWTR[6]|=2<<8; //資料儲存時間(DATAST)為6ns*3個HCLK=18ns } } printf(“ LCD ID:%x\r\n”,lcddev。id); //列印LCD ID if(lcddev。id==0X9341) //9341初始化 { LCD_WR_REG(0xCF); LCD_WR_DATA(0x00); LCD_WR_DATA(0xC1); LCD_WR_DATA(0X30); LCD_WR_REG(0xED); LCD_WR_DATA(0x64); LCD_WR_DATA(0x03); LCD_WR_DATA(0X12); LCD_WR_DATA(0X81); LCD_WR_REG(0xE8); LCD_WR_DATA(0x85); LCD_WR_DATA(0x10); LCD_WR_DATA(0x7A); LCD_WR_REG(0xCB); LCD_WR_DATA(0x39); LCD_WR_DATA(0x2C); LCD_WR_DATA(0x00); LCD_WR_DATA(0x34); LCD_WR_DATA(0x02); LCD_WR_REG(0xF7); LCD_WR_DATA(0x20); LCD_WR_REG(0xEA); LCD_WR_DATA(0x00); LCD_WR_DATA(0x00); LCD_WR_REG(0xC0); //Power control LCD_WR_DATA(0x1B); //VRH[5:0] LCD_WR_REG(0xC1); //Power control LCD_WR_DATA(0x01); //SAP[2:0];BT[3:0] LCD_WR_REG(0xC5); //VCM control LCD_WR_DATA(0x30); //3F LCD_WR_DATA(0x30); //3C LCD_WR_REG(0xC7); //VCM control2 LCD_WR_DATA(0XB7); LCD_WR_REG(0x36); // Memory Access Control LCD_WR_DATA(0x48); LCD_WR_REG(0x3A); LCD_WR_DATA(0x55); LCD_WR_REG(0xB1); LCD_WR_DATA(0x00); LCD_WR_DATA(0x1A); LCD_WR_REG(0xB6); // Display Function Control LCD_WR_DATA(0x0A); LCD_WR_DATA(0xA2); LCD_WR_REG(0xF2); // 3Gamma Function Disable LCD_WR_DATA(0x00); LCD_WR_REG(0x26); //Gamma curve selected LCD_WR_DATA(0x01); LCD_WR_REG(0xE0); //Set Gamma LCD_WR_DATA(0x0F); LCD_WR_DATA(0x2A); LCD_WR_DATA(0x28); LCD_WR_DATA(0x08); LCD_WR_DATA(0x0E); LCD_WR_DATA(0x08); LCD_WR_DATA(0x54); LCD_WR_DATA(0XA9); LCD_WR_DATA(0x43); LCD_WR_DATA(0x0A); LCD_WR_DATA(0x0F); LCD_WR_DATA(0x00); LCD_WR_DATA(0x00); LCD_WR_DATA(0x00); LCD_WR_DATA(0x00); LCD_WR_REG(0XE1); //Set Gamma LCD_WR_DATA(0x00); LCD_WR_DATA(0x15); LCD_WR_DATA(0x17); LCD_WR_DATA(0x07); LCD_WR_DATA(0x11); LCD_WR_DATA(0x06); LCD_WR_DATA(0x2B); LCD_WR_DATA(0x56); LCD_WR_DATA(0x3C); LCD_WR_DATA(0x05); LCD_WR_DATA(0x10); LCD_WR_DATA(0x0F); LCD_WR_DATA(0x3F); LCD_WR_DATA(0x3F); LCD_WR_DATA(0x0F); LCD_WR_REG(0x2B); LCD_WR_DATA(0x00); LCD_WR_DATA(0x00); LCD_WR_DATA(0x01); LCD_WR_DATA(0x3f); LCD_WR_REG(0x2A); LCD_WR_DATA(0x00); LCD_WR_DATA(0x00); LCD_WR_DATA(0x00); LCD_WR_DATA(0xef); LCD_WR_REG(0x11); //Exit Sleep delay_ms(120); LCD_WR_REG(0x29); //display on } LCD_Display_Dir(0); //預設為豎屏 LCD_LED=1; //點亮背光 LCD_Clear(WHITE);} //清屏函式//color:要清屏的填充色void LCD_Clear(u16 color){ u32 index = 0; u32 totalpoint = lcddev。width; totalpoint *= lcddev。height; //得到總點數 LCD_SetCursor(0x00, 0x0000); //設定游標位置 LCD_WriteRAM_Prepare(); //開始寫入GRAM for (index = 0; index < totalpoint; index++) { LCD->LCD_RAM=color; }}

main。c

int main(void){ u8 x=0; u8 lcd_id[12]; //存放LCD ID字串 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設定系統中斷優先順序分組2 delay_init(168); //初始化延時函式 uart_init(115200); //初始化串列埠波特率為115200 LED_Init(); //初始化LED LCD_Init(); //初始化LCD FSMC介面 POINT_COLOR=RED; //畫筆顏色:紅色 sprintf((char*)lcd_id,“LCD ID:%04X”,lcddev。id);//將LCD ID列印到lcd_id陣列。 while(1) { switch(x) { case 0:LCD_Clear(WHITE);break; case 1:LCD_Clear(BLACK);break; case 2:LCD_Clear(BLUE);break; case 3:LCD_Clear(RED);break; case 4:LCD_Clear(MAGENTA);break; case 5:LCD_Clear(GREEN);break; case 6:LCD_Clear(CYAN);break; case 7:LCD_Clear(YELLOW);break; case 8:LCD_Clear(BRRED);break; case 9:LCD_Clear(GRAY);break; case 10:LCD_Clear(LGRAY);break; case 11:LCD_Clear(BROWN);break; } POINT_COLOR=RED; LCD_ShowString(30,40,210,24,24,“Explorer STM32F4”); LCD_ShowString(30,70,200,16,16,“TFTLCD TEST”); LCD_ShowString(30,90,200,16,16,“ATOM@ALIENTEK”); LCD_ShowString(30,110,200,16,16,lcd_id); //顯示LCD ID LCD_ShowString(30,130,200,12,12,“2014/5/4”); x++; if(x==12)x=0; LED0=!LED0; delay_ms(1000); } }

上一篇:1988年,山東女子效仿武則天稱帝,建後宮、招男寵,後來怎麼樣了
下一篇:普京出訪白俄,或開闢第二戰線,敘利亞遭遇空襲,以色列背後捅刀