实验十TFT液晶显示实验一、实验目的1.了解240x400TFTLCD的工作原理。2.了解TFTLCD控制芯片OTM4001A的控制方式。3.学习并使用数学库IQmathLib.h。4.学习TM4C129xSeriesCortex-M4的EPI总线操作方式。5.学习EPI相关库函数的使用。二、实验原理1.TFT彩屏工作原理TFT(ThinFilmTransistor)LCD即薄膜场效应晶体管LCD,是有源矩阵类型液晶显示器(AM-LCD)中的一种。和TN技术不同的是,TFT的显示采用“背透式”照射方式——假想的光源路径不是像TN液晶那样从上至下,而是从下向上。这样的作法是在液晶的背部设置特殊光管,光源照射时通过下偏光板向上透出。由于上下夹层的电极改成FET电极和共通电极,在FET电极导通时,液晶分子的表现也会发生改变,可以通过遮光和透光来达到显示的目的,响应时间大大提高到80ms左右。因其具有比TNLCD更高的对比度和更丰富的色彩,荧屏更新频率也更快,故TFT俗称“真彩”。LCD是由二层玻璃基板夹住液晶组成的,形成一个平行板电容器,通过嵌入在下玻璃基板上的TFT对这个电容器和内置的存储电容充电,维持每幅图像所需要的电压直到下一幅画面更新。液晶的彩色都是透明的必须给LCD衬以白色的背光板上才能将五颜六色表达出来,而要使白色的背光板有反射就需要在四周加上白色灯光。因此在TFTLCD的底部都组合了灯具,如CCFL或LED。2.OTM4001A控制芯片简介OTM4001A是一款262144色,用于中小型TFTLCD显示屏的片上系统(SoC)驱动芯片,通过指定用于图形数据的RAM能支持达240xRGBx432分辨率。OTM4001A内部的时序控制器能为不同的需求提供不同接口方式,OTM4001A提供了系统接口,包括8/9/16/18位并口和SPI串口方式(本实验采用16位并口方式);OTM4001A也提供了6/16/18位RGB接口,用于动态显示图片。OTM4001A的主要特性还有窗口地址功能能限制数据重写区域,并减少数据传输;内部6位D/A转换器输出的64γ颜色校准;内部233280字节的RAM;背光引脚输出控制的内置自适应背光控制功能(CABC);逻辑供电电压范围2.5~3.6V,IO接口支持操作电压1.65~3.6V,模拟供电电压范围2.5~3.6V;内置的内部晶振与硬件复位。本实验中,采用80系统总线的16位并口方式,对TFTLCD的常规写操作时序特征和时序图分别如下表10-1和图10-1所示:为使液晶正常工作,我们需要在初始化之前先复位液晶,复位液晶的时序特征和时序图分别如下表10-2和图10-2所示:3.TivaWareCseries的数学库IQmathLib.hTiva™IQmath.h是一个高度优化和高精度的数学函数库,帮助C/C++程序员在Tiva器件上无缝地将浮点运算转化为定点计算。计算速度将显著快于浮点运算。IQmath库采用32位定点带符号数作为基本数据类型。这些定点数的格式从IQ1到IQ30,这里IQ数据格式代表了数的小数位数。C语言中要调用IQmath函数,需要先包含头文件“IQmath/IQmathLib.h”。然后,才能使用_iq和_iqN的数据类型以及库中的函数,以下代码是对IQmath库函数的简单调用:#includeIQmath/IQmathLib.hintmain(void){_iq24X,Y,Z;X=_IQ24(1.0);Y=_IQ24(7.0);Z=_IQ24div(X,Y);}IQmath库函数的具体使用请参阅TivaWare™IQmathLibraryUSER’SGUIDE。4.实验用到的主要库函数简介voidEPIModeSet(uint32_tui32Base,uint32_tui32Mode)函数用于选择EPI的工作方式。ui32Base为EPI模块的基地址;ui32Mode为EPI的工作模式,本实验选择为EPI_MODE_HB16,配置成16位总线模式。voidEPIConfigHB16Set(uint32_tui32Base,uint32_tui32Config,uint32_tui32MaxWait)函数用于16位总线工作模式的详细设置。ui32Base为EPI模块的基地址;ui32Config为16位总线工作方式的配置参数;ui32MaxWait为等待的最大外部时钟数。voidEPIAddressMapSet(uint32_tui32Base,uint32_tui32Map)函数用于配置外部设备的地址映射。ui32Base为EPI模块的基地址;ui32Map是地址映射参数,由一些宏定义的参数通过逻辑与组成。对于存储设备,EPI将外设视为一块连续的存储空间;对于无地址设备,EPI将外设视为一个地址。5.简化的EPI模块配置步骤三、实验代码。Sine_wave.c:#includestdbool.h#includestdint.h#includestring.h#includeinc/hw_memmap.h#includeinc/hw_types.h#includeinc/hw_epi.h#includeinc/hw_ints.h#includedriverlib/epi.h#includedriverlib/gpio.h#includedriverlib/sysctl.h#includedriverlib/rom.h#includedriverlib/rom_map.h#includedriverlib/pin_map.h#includedriverlib/systick.h#includedriverlib/interrupt.h#includedriverlib/ssi.h#includedriverlib/fpu.h#includeutils/uartstdio.h#includeTFTinit/TFT_400x240_OTM4001A_16bit.h#includeEPIinit/EPIinit.h#includeIQmath/IQmathLib.h#ifndefM_PI#defineM_PI3.14159265358979323846F#endifuint32_tg_ui32SysClock;staticvolatileunsignedlongg_ulTickCount;#defineSERIES_LENGTH240typedefstruct_Series{uint32_txAxis;int32_tdata;}tSeries;statictSeriesg_cSeries[240];uint16_tui32Loop=0,ulItemCount=0,FinishCalculateFlag=0,ulLastTickCount=0;floatfElapsedTime;_iq24fRadians,fSine;#defineTICKS_PER_SECOND40#defineFSECONDS_PER_TICK(1.0F/(float)TICKS_PER_SECOND)voidSysTickIntHandler(void){TickCount++;if(g_ulTickCount=480)g_ulTickCount=0;}voidConfigureUART(void){SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);GPIOPinConfigure(GPIO_PA0_U0RX);GPIOPinConfigure(GPIO_PA1_U0TX);GPIOPinTypeUART(GPIO_PORTA_BASE,GPIO_PIN_0|GPIO_PIN_1);UARTStdioConfig(0,115200,g_ui32SysClock);}voidDrawTriWave(intTlenth)//绘制三角波,参数为周期的长度,应该为60的倍数{intcount;while(ulLastTickCount==g_ulTickCount){}ulLastTickCount=g_ulTickCount;if(ulItemCount==SERIES_LENGTH)//SERIES_LENGTH为240{FinishCalculateFlag=1;}else{g_cSeries[ulItemCount].xAxis=++ulItemCount;}count=g_ulTickCount;while(count=Tlenth)count-=Tlenth;if(countTlenth/2)g_cSeries[ulItemCount-1].data=count;elseif(countTlenth)g_cSeries[ulItemCount-1].data=(-1)*(count)+Tlenth;if(!FinishCalculateFlag){TFTLCD_DrawPoint(g_cSeries[ulItemCount-1].xAxis,g_cSeries[ulItemCount-1].data+60,BLUE);}else{for(ui32Loop=2;ui32LoopSERIES_LENGTH;ui32Loop++){TFTLCD_DrawPoint(g_cSeries[ui32Loop-1].xAxis,g_cSeries[ui32Loop-1].data+60,0);g_cSeries[ui32Loop-1].data=g_cSeries[ui32Loop].data;TFTLCD_DrawPoint(g_cSeries[ui32Loop-1].xAxis,g_cSeries[ui32Loop-1].data+60,BLUE);}}}voidTFTLCD_DrawCircle(intx,inty,intr){intnum=800;floati;_iq24angle,xi,yi,fr,sin_angle,cos_angle;fr=_IQ24(r);for(i=0;inum;i++){angle=_IQ24((i/((float)(num/2)))*(float)M_PI);sin_angle=_IQ24sin(angle);cos_angle=_IQ24cos(angle);xi=_IQ24mpy(cos_angle,fr);yi=_IQ24mpy(sin_angle,fr);TFTLCD_DrawPoint(x+_IQ24int(xi),y+_IQ24int(yi),WHITE);}}voidmain(){FPUEnable();FPULazyStackingEnable();g_ui32SysClock=SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ|SYSCTL_OSC_MAIN|SYSCTL_USE_PLL|SYSCTL_CFG_VCO_480),120000000);SysTickPeriodSet(g_ui32SysClock/TICKS_PER_SECOND);IntMasterEnable();SysTickIntEnable();SysTickEnable();ConfigureUART();EPIGPIOinit();UARTprintf(TFTLCDtest\n);UARTprintf(EPIType:host-bus16-bitinterface\n);TFT_400x240_OTM4001Ainit(g_ui32SysClock);//OpenBackLight.GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,GPIO_PIN_0);GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_0,GPIO_PIN_0);TFTLCD_Sho