做畢設的時候遇到了難題,某寶買的一個小小的TFT LCD送的例程無法實現非填充模式,例如我想在顯示屏上顯示傳感器獲取到的數值,第一遍是正常的,但是後面顯示的數值會在原來的基礎上疊加,導致屏幕一團團的。
某寶的顯示屏如下:
未修改顯示函數效果如下:
查了好多帖子,最後在openedv論壇的某個大佬分享的源碼和原子本來的例程中才找到了解決這個問題的辦法,下面就是需要修改成非填充模式的操作。
函數原型爲淘寶店家給的函數,就不全部列出來了,就僅僅把需要修改的地方寫出來。
- 需要修改第一個函數爲LCD_ShowChar( )
函數如下:
//******************************************************************
//函數名: LCD_ShowChar
//功能: 顯示單個英文字符
//輸入參數:(x,y):字符顯示位置起始座標
// fc:前置畫筆顏色
// bc:背景顏色
// num:數值(0-94)
// size:字體大小
// mode:模式 0,非疊加模式;1,疊加模式
//返回值: 無
//修改記錄:無
//******************************************************************
void LCD_ShowChar(u16 x,u16 y,u16 fc, u16 bc, u8 num,u8 size,u8 mode)
{
u8 temp,t1,t;
u8 csize=(size/8+((size%8)?1:0))*(size/2); //得到字體一個字符對應點陣集所佔的字節數
num=num-' ';//得到偏移後的值
LCD_SetWindows(x,y,x+size/2-1,y+size-1);//設置單個文字顯示窗口
for(t=0;t<csize;t++)
{
if(size==12)temp=asc2_1206[num][t];//調用1206字體
else temp=asc2_1608[num][t]; //調用1608字體
for(t1=0;t1<csize/2;t1++)
{
if(temp&0x01)
{
LCD_DrawPoint(x+t1,y+t);
LCD_WR_DATA_16Bit(POINT_COLOR);
}
else
{
if(mode==0)
{
LCD_DrawPoint(x+t1,y+t);
LCD_WR_DATA_16Bit(BACK_COLOR);
}
}
temp>>=1;
}
}
LCD_SetWindows(0,0,lcddev.width-1,lcddev.height-1);//恢復窗口爲全屏
}
疊加模式不多說,非疊加模式就是當mode=0時,調用LCD_DrawPoint()進行畫點,然後再在8位總線下寫入一個16位數據,該數據位背景顏色BLACK_COLOR,後temp右移遍歷。
- (調用該函數情況下)修改的第二個函數爲LCD_ShowNum( )
函數如下:
//******************************************************************
//函數名: LCD_ShowNum
//功能: 顯示單個數字變量值
//輸入參數:x,y :起點座標
// len :指定顯示數字的位數
// size:字體大小(12,16)
// color:顏色
// num:數值(0~4294967295)
//返回值: 無
//修改記錄:無
//******************************************************************
void LCD_ShowNum(u16 x,u16 y,u32 num,u8 len,u8 size)
{
u8 t,temp;
u8 enshow=0;
for(t=0;t<len;t++)
{
temp=(num/mypow(10,len-t-1))%10;
if(enshow==0&&t<(len-1))
{
if(temp==0)
{
LCD_ShowChar(x+(size/2)*t,y,POINT_COLOR,BACK_COLOR,' ',size,0);
continue;
}else enshow=1;
}
LCD_ShowChar(x+(size/2)*t,y,POINT_COLOR,BACK_COLOR,temp+'0',size,0);
}
}
其實這個函數最好還是在u8 size後面添加一個參數u8 mode,就可以在調用函數的時候方便修改模式,這裏我偷懶爲了使用該函數實現非填充模式就直接在函數調用LCD_ShowChar()函數的時候直接寫參數0,固定成了非填充模式。
- 主函數部分:
/****************************************************************************************************
//=======================================液晶屏數據線接線==========================================//
//CS 接PB12 //片選信號
//CLK 接PB13 //SPI時鐘信號
//SDI(DIN) 接PB15 //SPI總線數據信號
//=======================================液晶屏控制線接線==========================================//
//RS(D/C) 接PB1 //寄存器/數據選擇信號(RS=0數據總線發送的是指令;RS=1數據總線發送的是像素數據)
//RST 接系統復位NRST //液晶屏復位信號,低電平復位
/////////////////////////////////////////////////////////////////////////////////////////////////
//==================================如何精簡到只需要3個IO=======================================//
//1.CS信號可以精簡,不作SPI複用片選可將CS接地常低,節省1個IO
//2.LED背光控制信號可以接高電平3.3V背光常亮,節省1個IO
//3.RST復位信號可以接到單片機的復位端,利用系統上電覆位,節省1個IO
//==================================如何切換橫豎屏顯示=======================================//
//打開lcd.h頭文件,修改宏#define USE_HORIZONTAL 值爲0使用豎屏模式.1,使用橫屏模式
//===========================如何切換模擬SPI總線驅動和硬件SPI總線驅動=========================//
//打開lcd.h頭文件,修改宏#define USE_HARDWARE_SPI 值爲0使用模擬SPI總線.1,使用硬件SPI總線
**************************************************************************************************/
#include "delay.h"
#include "sys.h"
#include "lcd.h"
#include "gui.h"
#include "usart.h"
#include "led.h"
#include "usmart.h"
//LED 狀態設置函數
void led_set(u8 sta)
{
LED0=sta;
}
//函數參數調用測試函數
void test_fun(void(*ledset)(u8),u8 sta)
{
ledset(sta);
}
__align(4) u8 dtbuf[50];
int main(void)
{
int x;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設置NVIC中斷分組2:2位搶佔優先級,2位響應優先級
uart_init(9600); //串口初始化爲9600
delay_init(); //延時函數初始化
LED_Init();
SystemInit(); //初始化RCC 設置系統主頻爲72MHZ
LCD_Init(); //液晶屏初始化
usmart_dev.init(72); //初始化USMART
LCD_Clear(BLACK);
POINT_COLOR=RED;
while(1)
{
for(x=0;x<60;x++)
{
//LCD_ShowNum(52,52,x,2,16);
sprintf((char *)dtbuf,"%d",x);
//LCD_ShowString(10+38,10,16,dtbuf,0);
Gui_StrCenter(0,50,BLUE,YELLOW,dtbuf,16,0);//居中顯示
delay_ms(1000);
}
if(x==60)
{
x=0;
}
}
}
主函數就是在屏幕上顯示一個累加計時的功能,沒什麼特別的。具體的效果忘了拍圖保存,下一篇帖子做MPU6050的時候有一張類似的效果圖,可以參考那個。
需要源碼的話看我簡介取吧,項目代碼都放那裏,就不直接掛網盤了。