本期测评HC32F4A0的EXMC外部存储器控制器来驱动TFTLCD液晶屏,板载的液晶屏接口完全兼容正点原子的液晶屏,正好手上有一块咸鱼上50块买的仿正点原子的4.0寸液晶屏,下图是液晶屏的原理图。
HC32F4A0的EXMC控制器又细分为NFC、DMC和SMC,我们使用SMC来控制液晶,相当于GDM32F103的FSMC控制器。与GD、ST不同的是,SMC的地中空间起始地址不是由片选来定的,且地址空间是可自定义的。比如GD的使用NE0,那么起始地址是0x60000000,使用NE1,那么起始地址就为0x64000000,如下图所示。而HC32F4A0无论片选是什么,起始地址都为0x60000000。那么如果要确定LCD的起始地址,就必须确定地址线,如开发板用到的是ADD12,那么LCD的地址就是0x60000000+((1 << 13)-2)=0x60001FFE。这个定义倒是与GD和ST相同,外设存储宽度为16位,内部都要右移一位。但是在手册中并没有找到相关的说明,可以参考GD或ST的说明,如下图。
ST的说明。
以下是LCD液晶屏SMC配置代码:
/**************************************************************
* [url=home.php?mod=space&uid=32621]@name[/url] bsp_NT35510_Init
* [url=home.php?mod=space&uid=159083]@brief[/url] * @param None
* @retval
* [url=home.php?mod=space&uid=1315547]@author[/url] Zachary
* [url=home.php?mod=space&uid=34591]@data[/url] 2022-11-09
**************************************************************/
void bsp_NT35510_Init( void )
{
bsp_NT35510_Gpio_Init();
bsp_NT35510_EXMC_Init();
delay_ms( 100 );
//发送秘钥
LCD_WriteReg( 0xF000, 0x0055 );
LCD_WriteReg( 0xF001, 0x00AA );
LCD_WriteReg( 0xF002, 0x0052 );
LCD_WriteReg( 0xF003, 0x0008 );
LCD_WriteReg( 0xF004, 0x0001 );
LCD_WR_REG( 0xC500 ); //读取ID高8位
lcddev.id = LCD_RD_DATA(); //读回0X55
lcddev.id <<= 8;
LCD_WR_REG( 0xC501 ); //读取ID低8位
lcddev.id |= LCD_RD_DATA(); //读回0X10
delay_ms( 5 );
if( lcddev.id == 0x8000 )
lcddev.id = 0x5510; //NT35510读回的ID是8000H,为方便区分,我们强制设置为5510
if( lcddev.id == 0x5510 )
{
LCD_WriteReg( 0xF000, 0x55 );
LCD_WriteReg( 0xF001, 0xAA );
LCD_WriteReg( 0xF002, 0x52 );
LCD_WriteReg( 0xF003, 0x08 );
LCD_WriteReg( 0xF004, 0x01 );
//AVDD Set AVDD 5.2V
LCD_WriteReg( 0xB000, 0x0D );
LCD_WriteReg( 0xB001, 0x0D );
LCD_WriteReg( 0xB002, 0x0D );
//AVDD ratio
LCD_WriteReg( 0xB600, 0x34 );
LCD_WriteReg( 0xB601, 0x34 );
LCD_WriteReg( 0xB602, 0x34 );
//AVEE -5.2V
LCD_WriteReg( 0xB100, 0x0D );
LCD_WriteReg( 0xB101, 0x0D );
LCD_WriteReg( 0xB102, 0x0D );
//AVEE ratio
LCD_WriteReg( 0xB700, 0x34 );
LCD_WriteReg( 0xB701, 0x34 );
LCD_WriteReg( 0xB702, 0x34 );
//VCL -2.5V
LCD_WriteReg( 0xB200, 0x00 );
LCD_WriteReg( 0xB201, 0x00 );
LCD_WriteReg( 0xB202, 0x00 );
//VCL ratio
LCD_WriteReg( 0xB800, 0x24 );
LCD_WriteReg( 0xB801, 0x24 );
LCD_WriteReg( 0xB802, 0x24 );
//VGH 15V (Free pump)
LCD_WriteReg( 0xBF00, 0x01 );
LCD_WriteReg( 0xB300, 0x0F );
LCD_WriteReg( 0xB301, 0x0F );
LCD_WriteReg( 0xB302, 0x0F );
//VGH ratio
LCD_WriteReg( 0xB900, 0x34 );
LCD_WriteReg( 0xB901, 0x34 );
LCD_WriteReg( 0xB902, 0x34 );
//VGL_REG -10V
LCD_WriteReg( 0xB500, 0x08 );
LCD_WriteReg( 0xB501, 0x08 );
LCD_WriteReg( 0xB502, 0x08 );
LCD_WriteReg( 0xC200, 0x03 );
//VGLX ratio
LCD_WriteReg( 0xBA00, 0x24 );
LCD_WriteReg( 0xBA01, 0x24 );
LCD_WriteReg( 0xBA02, 0x24 );
//VGMP/VGSP 4.5V/0V
LCD_WriteReg( 0xBC00, 0x00 );
LCD_WriteReg( 0xBC01, 0x78 );
LCD_WriteReg( 0xBC02, 0x00 );
//VGMN/VGSN -4.5V/0V
LCD_WriteReg( 0xBD00, 0x00 );
LCD_WriteReg( 0xBD01, 0x78 );
LCD_WriteReg( 0xBD02, 0x00 );
//VCOM
LCD_WriteReg( 0xBE00, 0x00 );
LCD_WriteReg( 0xBE01, 0x64 );
//Gamma Setting
LCD_WriteReg( 0xD100, 0x00 );
LCD_WriteReg( 0xD101, 0x33 );
LCD_WriteReg( 0xD102, 0x00 );
LCD_WriteReg( 0xD103, 0x34 );
LCD_WriteReg( 0xD104, 0x00 );
LCD_WriteReg( 0xD105, 0x3A );
LCD_WriteReg( 0xD106, 0x00 );
LCD_WriteReg( 0xD107, 0x4A );
LCD_WriteReg( 0xD108, 0x00 );
LCD_WriteReg( 0xD109, 0x5C );
LCD_WriteReg( 0xD10A, 0x00 );
LCD_WriteReg( 0xD10B, 0x81 );
LCD_WriteReg( 0xD10C, 0x00 );
LCD_WriteReg( 0xD10D, 0xA6 );
LCD_WriteReg( 0xD10E, 0x00 );
LCD_WriteReg( 0xD10F, 0xE5 );
LCD_WriteReg( 0xD110, 0x01 );
LCD_WriteReg( 0xD111, 0x13 );
LCD_WriteReg( 0xD112, 0x01 );
LCD_WriteReg( 0xD113, 0x54 );
LCD_WriteReg( 0xD114, 0x01 );
LCD_WriteReg( 0xD115, 0x82 );
LCD_WriteReg( 0xD116, 0x01 );
LCD_WriteReg( 0xD117, 0xCA );
LCD_WriteReg( 0xD118, 0x02 );
LCD_WriteReg( 0xD119, 0x00 );
LCD_WriteReg( 0xD11A, 0x02 );
LCD_WriteReg( 0xD11B, 0x01 );
LCD_WriteReg( 0xD11C, 0x02 );
LCD_WriteReg( 0xD11D, 0x34 );
LCD_WriteReg( 0xD11E, 0x02 );
LCD_WriteReg( 0xD11F, 0x67 );
LCD_WriteReg( 0xD120, 0x02 );
LCD_WriteReg( 0xD121, 0x84 );
LCD_WriteReg( 0xD122, 0x02 );
LCD_WriteReg( 0xD123, 0xA4 );
LCD_WriteReg( 0xD124, 0x02 );
LCD_WriteReg( 0xD125, 0xB7 );
LCD_WriteReg( 0xD126, 0x02 );
LCD_WriteReg( 0xD127, 0xCF );
LCD_WriteReg( 0xD128, 0x02 );
LCD_WriteReg( 0xD129, 0xDE );
LCD_WriteReg( 0xD12A, 0x02 );
LCD_WriteReg( 0xD12B, 0xF2 );
LCD_WriteReg( 0xD12C, 0x02 );
LCD_WriteReg( 0xD12D, 0xFE );
LCD_WriteReg( 0xD12E, 0x03 );
LCD_WriteReg( 0xD12F, 0x10 );
LCD_WriteReg( 0xD130, 0x03 );
LCD_WriteReg( 0xD131, 0x33 );
LCD_WriteReg( 0xD132, 0x03 );
LCD_WriteReg( 0xD133, 0x6D );
LCD_WriteReg( 0xD200, 0x00 );
LCD_WriteReg( 0xD201, 0x33 );
LCD_WriteReg( 0xD202, 0x00 );
LCD_WriteReg( 0xD203, 0x34 );
LCD_WriteReg( 0xD204, 0x00 );
LCD_WriteReg( 0xD205, 0x3A );
LCD_WriteReg( 0xD206, 0x00 );
LCD_WriteReg( 0xD207, 0x4A );
LCD_WriteReg( 0xD208, 0x00 );
LCD_WriteReg( 0xD209, 0x5C );
LCD_WriteReg( 0xD20A, 0x00 );
LCD_WriteReg( 0xD20B, 0x81 );
LCD_WriteReg( 0xD20C, 0x00 );
LCD_WriteReg( 0xD20D, 0xA6 );
LCD_WriteReg( 0xD20E, 0x00 );
LCD_WriteReg( 0xD20F, 0xE5 );
LCD_WriteReg( 0xD210, 0x01 );
LCD_WriteReg( 0xD211, 0x13 );
LCD_WriteReg( 0xD212, 0x01 );
LCD_WriteReg( 0xD213, 0x54 );
LCD_WriteReg( 0xD214, 0x01 );
LCD_WriteReg( 0xD215, 0x82 );
LCD_WriteReg( 0xD216, 0x01 );
LCD_WriteReg( 0xD217, 0xCA );
LCD_WriteReg( 0xD218, 0x02 );
LCD_WriteReg( 0xD219, 0x00 );
LCD_WriteReg( 0xD21A, 0x02 );
LCD_WriteReg( 0xD21B, 0x01 );
LCD_WriteReg( 0xD21C, 0x02 );
LCD_WriteReg( 0xD21D, 0x34 );
LCD_WriteReg( 0xD21E, 0x02 );
LCD_WriteReg( 0xD21F, 0x67 );
LCD_WriteReg( 0xD220, 0x02 );
LCD_WriteReg( 0xD221, 0x84 );
LCD_WriteReg( 0xD222, 0x02 );
LCD_WriteReg( 0xD223, 0xA4 );
LCD_WriteReg( 0xD224, 0x02 );
LCD_WriteReg( 0xD225, 0xB7 );
LCD_WriteReg( 0xD226, 0x02 );
LCD_WriteReg( 0xD227, 0xCF );
LCD_WriteReg( 0xD228, 0x02 );
LCD_WriteReg( 0xD229, 0xDE );
LCD_WriteReg( 0xD22A, 0x02 );
LCD_WriteReg( 0xD22B, 0xF2 );
LCD_WriteReg( 0xD22C, 0x02 );
LCD_WriteReg( 0xD22D, 0xFE );
LCD_WriteReg( 0xD22E, 0x03 );
LCD_WriteReg( 0xD22F, 0x10 );
LCD_WriteReg( 0xD230, 0x03 );
LCD_WriteReg( 0xD231, 0x33 );
LCD_WriteReg( 0xD232, 0x03 );
LCD_WriteReg( 0xD233, 0x6D );
LCD_WriteReg( 0xD300, 0x00 );
LCD_WriteReg( 0xD301, 0x33 );
LCD_WriteReg( 0xD302, 0x00 );
LCD_WriteReg( 0xD303, 0x34 );
LCD_WriteReg( 0xD304, 0x00 );
LCD_WriteReg( 0xD305, 0x3A );
LCD_WriteReg( 0xD306, 0x00 );
LCD_WriteReg( 0xD307, 0x4A );
LCD_WriteReg( 0xD308, 0x00 );
LCD_WriteReg( 0xD309, 0x5C );
LCD_WriteReg( 0xD30A, 0x00 );
LCD_WriteReg( 0xD30B, 0x81 );
LCD_WriteReg( 0xD30C, 0x00 );
LCD_WriteReg( 0xD30D, 0xA6 );
LCD_WriteReg( 0xD30E, 0x00 );
LCD_WriteReg( 0xD30F, 0xE5 );
LCD_WriteReg( 0xD310, 0x01 );
LCD_WriteReg( 0xD311, 0x13 );
LCD_WriteReg( 0xD312, 0x01 );
LCD_WriteReg( 0xD313, 0x54 );
LCD_WriteReg( 0xD314, 0x01 );
LCD_WriteReg( 0xD315, 0x82 );
LCD_WriteReg( 0xD316, 0x01 );
LCD_WriteReg( 0xD317, 0xCA );
LCD_WriteReg( 0xD318, 0x02 );
LCD_WriteReg( 0xD319, 0x00 );
LCD_WriteReg( 0xD31A, 0x02 );
LCD_WriteReg( 0xD31B, 0x01 );
LCD_WriteReg( 0xD31C, 0x02 );
LCD_WriteReg( 0xD31D, 0x34 );
LCD_WriteReg( 0xD31E, 0x02 );
LCD_WriteReg( 0xD31F, 0x67 );
LCD_WriteReg( 0xD320, 0x02 );
LCD_WriteReg( 0xD321, 0x84 );
LCD_WriteReg( 0xD322, 0x02 );
LCD_WriteReg( 0xD323, 0xA4 );
LCD_WriteReg( 0xD324, 0x02 );
LCD_WriteReg( 0xD325, 0xB7 );
LCD_WriteReg( 0xD326, 0x02 );
LCD_WriteReg( 0xD327, 0xCF );
LCD_WriteReg( 0xD328, 0x02 );
LCD_WriteReg( 0xD329, 0xDE );
LCD_WriteReg( 0xD32A, 0x02 );
LCD_WriteReg( 0xD32B, 0xF2 );
LCD_WriteReg( 0xD32C, 0x02 );
LCD_WriteReg( 0xD32D, 0xFE );
LCD_WriteReg( 0xD32E, 0x03 );
LCD_WriteReg( 0xD32F, 0x10 );
LCD_WriteReg( 0xD330, 0x03 );
LCD_WriteReg( 0xD331, 0x33 );
LCD_WriteReg( 0xD332, 0x03 );
LCD_WriteReg( 0xD333, 0x6D );
LCD_WriteReg( 0xD400, 0x00 );
LCD_WriteReg( 0xD401, 0x33 );
LCD_WriteReg( 0xD402, 0x00 );
LCD_WriteReg( 0xD403, 0x34 );
LCD_WriteReg( 0xD404, 0x00 );
LCD_WriteReg( 0xD405, 0x3A );
LCD_WriteReg( 0xD406, 0x00 );
LCD_WriteReg( 0xD407, 0x4A );
LCD_WriteReg( 0xD408, 0x00 );
LCD_WriteReg( 0xD409, 0x5C );
LCD_WriteReg( 0xD40A, 0x00 );
LCD_WriteReg( 0xD40B, 0x81 );
LCD_WriteReg( 0xD40C, 0x00 );
LCD_WriteReg( 0xD40D, 0xA6 );
LCD_WriteReg( 0xD40E, 0x00 );
LCD_WriteReg( 0xD40F, 0xE5 );
LCD_WriteReg( 0xD410, 0x01 );
LCD_WriteReg( 0xD411, 0x13 );
LCD_WriteReg( 0xD412, 0x01 );
LCD_WriteReg( 0xD413, 0x54 );
LCD_WriteReg( 0xD414, 0x01 );
LCD_WriteReg( 0xD415, 0x82 );
LCD_WriteReg( 0xD416, 0x01 );
LCD_WriteReg( 0xD417, 0xCA );
LCD_WriteReg( 0xD418, 0x02 );
LCD_WriteReg( 0xD419, 0x00 );
LCD_WriteReg( 0xD41A, 0x02 );
LCD_WriteReg( 0xD41B, 0x01 );
LCD_WriteReg( 0xD41C, 0x02 );
LCD_WriteReg( 0xD41D, 0x34 );
LCD_WriteReg( 0xD41E, 0x02 );
LCD_WriteReg( 0xD41F, 0x67 );
LCD_WriteReg( 0xD420, 0x02 );
LCD_WriteReg( 0xD421, 0x84 );
LCD_WriteReg( 0xD422, 0x02 );
LCD_WriteReg( 0xD423, 0xA4 );
LCD_WriteReg( 0xD424, 0x02 );
LCD_WriteReg( 0xD425, 0xB7 );
LCD_WriteReg( 0xD426, 0x02 );
LCD_WriteReg( 0xD427, 0xCF );
LCD_WriteReg( 0xD428, 0x02 );
LCD_WriteReg( 0xD429, 0xDE );
LCD_WriteReg( 0xD42A, 0x02 );
LCD_WriteReg( 0xD42B, 0xF2 );
LCD_WriteReg( 0xD42C, 0x02 );
LCD_WriteReg( 0xD42D, 0xFE );
LCD_WriteReg( 0xD42E, 0x03 );
LCD_WriteReg( 0xD42F, 0x10 );
LCD_WriteReg( 0xD430, 0x03 );
LCD_WriteReg( 0xD431, 0x33 );
LCD_WriteReg( 0xD432, 0x03 );
LCD_WriteReg( 0xD433, 0x6D );
LCD_WriteReg( 0xD500, 0x00 );
LCD_WriteReg( 0xD501, 0x33 );
LCD_WriteReg( 0xD502, 0x00 );
LCD_WriteReg( 0xD503, 0x34 );
LCD_WriteReg( 0xD504, 0x00 );
LCD_WriteReg( 0xD505, 0x3A );
LCD_WriteReg( 0xD506, 0x00 );
LCD_WriteReg( 0xD507, 0x4A );
LCD_WriteReg( 0xD508, 0x00 );
LCD_WriteReg( 0xD509, 0x5C );
LCD_WriteReg( 0xD50A, 0x00 );
LCD_WriteReg( 0xD50B, 0x81 );
LCD_WriteReg( 0xD50C, 0x00 );
LCD_WriteReg( 0xD50D, 0xA6 );
LCD_WriteReg( 0xD50E, 0x00 );
LCD_WriteReg( 0xD50F, 0xE5 );
LCD_WriteReg( 0xD510, 0x01 );
LCD_WriteReg( 0xD511, 0x13 );
LCD_WriteReg( 0xD512, 0x01 );
LCD_WriteReg( 0xD513, 0x54 );
LCD_WriteReg( 0xD514, 0x01 );
LCD_WriteReg( 0xD515, 0x82 );
LCD_WriteReg( 0xD516, 0x01 );
LCD_WriteReg( 0xD517, 0xCA );
LCD_WriteReg( 0xD518, 0x02 );
LCD_WriteReg( 0xD519, 0x00 );
LCD_WriteReg( 0xD51A, 0x02 );
LCD_WriteReg( 0xD51B, 0x01 );
LCD_WriteReg( 0xD51C, 0x02 );
LCD_WriteReg( 0xD51D, 0x34 );
LCD_WriteReg( 0xD51E, 0x02 );
LCD_WriteReg( 0xD51F, 0x67 );
LCD_WriteReg( 0xD520, 0x02 );
LCD_WriteReg( 0xD521, 0x84 );
LCD_WriteReg( 0xD522, 0x02 );
LCD_WriteReg( 0xD523, 0xA4 );
LCD_WriteReg( 0xD524, 0x02 );
LCD_WriteReg( 0xD525, 0xB7 );
LCD_WriteReg( 0xD526, 0x02 );
LCD_WriteReg( 0xD527, 0xCF );
LCD_WriteReg( 0xD528, 0x02 );
LCD_WriteReg( 0xD529, 0xDE );
LCD_WriteReg( 0xD52A, 0x02 );
LCD_WriteReg( 0xD52B, 0xF2 );
LCD_WriteReg( 0xD52C, 0x02 );
LCD_WriteReg( 0xD52D, 0xFE );
LCD_WriteReg( 0xD52E, 0x03 );
LCD_WriteReg( 0xD52F, 0x10 );
LCD_WriteReg( 0xD530, 0x03 );
LCD_WriteReg( 0xD531, 0x33 );
LCD_WriteReg( 0xD532, 0x03 );
LCD_WriteReg( 0xD533, 0x6D );
LCD_WriteReg( 0xD600, 0x00 );
LCD_WriteReg( 0xD601, 0x33 );
LCD_WriteReg( 0xD602, 0x00 );
LCD_WriteReg( 0xD603, 0x34 );
LCD_WriteReg( 0xD604, 0x00 );
LCD_WriteReg( 0xD605, 0x3A );
LCD_WriteReg( 0xD606, 0x00 );
LCD_WriteReg( 0xD607, 0x4A );
LCD_WriteReg( 0xD608, 0x00 );
LCD_WriteReg( 0xD609, 0x5C );
LCD_WriteReg( 0xD60A, 0x00 );
LCD_WriteReg( 0xD60B, 0x81 );
LCD_WriteReg( 0xD60C, 0x00 );
LCD_WriteReg( 0xD60D, 0xA6 );
LCD_WriteReg( 0xD60E, 0x00 );
LCD_WriteReg( 0xD60F, 0xE5 );
LCD_WriteReg( 0xD610, 0x01 );
LCD_WriteReg( 0xD611, 0x13 );
LCD_WriteReg( 0xD612, 0x01 );
LCD_WriteReg( 0xD613, 0x54 );
LCD_WriteReg( 0xD614, 0x01 );
LCD_WriteReg( 0xD615, 0x82 );
LCD_WriteReg( 0xD616, 0x01 );
LCD_WriteReg( 0xD617, 0xCA );
LCD_WriteReg( 0xD618, 0x02 );
LCD_WriteReg( 0xD619, 0x00 );
LCD_WriteReg( 0xD61A, 0x02 );
LCD_WriteReg( 0xD61B, 0x01 );
LCD_WriteReg( 0xD61C, 0x02 );
LCD_WriteReg( 0xD61D, 0x34 );
LCD_WriteReg( 0xD61E, 0x02 );
LCD_WriteReg( 0xD61F, 0x67 );
LCD_WriteReg( 0xD620, 0x02 );
LCD_WriteReg( 0xD621, 0x84 );
LCD_WriteReg( 0xD622, 0x02 );
LCD_WriteReg( 0xD623, 0xA4 );
LCD_WriteReg( 0xD624, 0x02 );
LCD_WriteReg( 0xD625, 0xB7 );
LCD_WriteReg( 0xD626, 0x02 );
LCD_WriteReg( 0xD627, 0xCF );
LCD_WriteReg( 0xD628, 0x02 );
LCD_WriteReg( 0xD629, 0xDE );
LCD_WriteReg( 0xD62A, 0x02 );
LCD_WriteReg( 0xD62B, 0xF2 );
LCD_WriteReg( 0xD62C, 0x02 );
LCD_WriteReg( 0xD62D, 0xFE );
LCD_WriteReg( 0xD62E, 0x03 );
LCD_WriteReg( 0xD62F, 0x10 );
LCD_WriteReg( 0xD630, 0x03 );
LCD_WriteReg( 0xD631, 0x33 );
LCD_WriteReg( 0xD632, 0x03 );
LCD_WriteReg( 0xD633, 0x6D );
//LV2 Page 0 enable
LCD_WriteReg( 0xF000, 0x55 );
LCD_WriteReg( 0xF001, 0xAA );
LCD_WriteReg( 0xF002, 0x52 );
LCD_WriteReg( 0xF003, 0x08 );
LCD_WriteReg( 0xF004, 0x00 );
//Display control
LCD_WriteReg( 0xB100, 0xCC );
LCD_WriteReg( 0xB101, 0x00 );
//Source hold time
LCD_WriteReg( 0xB600, 0x05 );
//Gate EQ control
LCD_WriteReg( 0xB700, 0x70 );
LCD_WriteReg( 0xB701, 0x70 );
//Source EQ control (Mode 2)
LCD_WriteReg( 0xB800, 0x01 );
LCD_WriteReg( 0xB801, 0x03 );
LCD_WriteReg( 0xB802, 0x03 );
LCD_WriteReg( 0xB803, 0x03 );
//Inversion mode (2-dot)
LCD_WriteReg( 0xBC00, 0x05 );
LCD_WriteReg( 0xBC01, 0x00 );
LCD_WriteReg( 0xBC02, 0x00 );
//Timing control 4H w/ 4-delay
LCD_WriteReg( 0xC900, 0x11 );
LCD_WriteReg( 0xC901, 0x02 );
LCD_WriteReg( 0xC902, 0x50 );
LCD_WriteReg( 0xC903, 0x50 );
LCD_WriteReg( 0xC904, 0x50 );
LCD_WriteReg( 0x3500, 0x00 );
LCD_WriteReg( 0x3A00, 0x55 ); //16-bit/pixel
LCD_WR_REG( 0x2100 );
LCD_WR_REG( 0x1100 );
delay_us( 120 );
LCD_WR_REG( 0x2900 );
}
LCD_Display_Dir( 1 ); //0竖屏
LCD_Clear( GBLUE );
LCD_Draw_Circle( 200, 200, 100, RED );
LCD_ShowString( 300, 300, lcddev.width, lcddev.height, 24, ( uint8_t * )"hello world", RED, GBLUE );
}
/**************************************************************
* @Name bsp_NT35510_Gpio_Init
* @brief
* @param None
* @retval
* @author Zachary
* @Data 2022-11-09
**************************************************************/
static void bsp_NT35510_Gpio_Init( void )
{
stc_gpio_init_t stcGpioInit;
LL_PERIPH_WE( LL_PERIPH_GPIO | LL_PERIPH_FCG | LL_PERIPH_PWC_CLK_RMU | \
LL_PERIPH_EFM | LL_PERIPH_SRAM );
/* Init LCD backlight IO */
GPIO_StructInit( &stcGpioInit );
stcGpioInit.u16PinDrv = PIN_HIGH_DRV;
stcGpioInit.u16PinDir = PIN_DIR_OUT;
stcGpioInit.u16PullUp = PIN_PU_ON;
GPIO_Init( LCD_BKL_PORT, LCD_BKL_PIN, &stcGpioInit );
GPIO_SetPins( LCD_BKL_PORT, LCD_BKL_PIN );
/* Config xLCD_RST */
TCA9539_WritePin( TCA9539_IO_PORT0, TCA9539_IO_PIN7, TCA9539_PIN_SET );
TCA9539_ConfigPin( TCA9539_IO_PORT0, TCA9539_IO_PIN7, TCA9539_DIR_OUT );
/************************* Set pin drive capacity *************************/
GPIO_StructInit( &stcGpioInit );
stcGpioInit.u16PinDrv = PIN_HIGH_DRV;
/* SMC_CS SMC_WE SMC_OE */
GPIO_Init( LCD_CS_PORT, LCD_CS_PIN, &stcGpioInit );
GPIO_Init( LCD_WE_PORT, LCD_WE_PIN, &stcGpioInit );
GPIO_Init( LCD_OE_PORT, LCD_OE_PIN, &stcGpioInit );
/* SMC_ADD[0:18]*/
GPIO_Init( LCD_ADD12_PORT, LCD_ADD12_PIN, &stcGpioInit );
/* SMC_DATA[0:15] */
GPIO_Init( LCD_DATA0_PORT, LCD_DATA0_PIN, &stcGpioInit );
GPIO_Init( LCD_DATA1_PORT, LCD_DATA1_PIN, &stcGpioInit );
GPIO_Init( LCD_DATA2_PORT, LCD_DATA2_PIN, &stcGpioInit );
GPIO_Init( LCD_DATA3_PORT, LCD_DATA3_PIN, &stcGpioInit );
GPIO_Init( LCD_DATA4_PORT, LCD_DATA4_PIN, &stcGpioInit );
GPIO_Init( LCD_DATA5_PORT, LCD_DATA5_PIN, &stcGpioInit );
GPIO_Init( LCD_DATA6_PORT, LCD_DATA6_PIN, &stcGpioInit );
GPIO_Init( LCD_DATA7_PORT, LCD_DATA7_PIN, &stcGpioInit );
GPIO_Init( LCD_DATA8_PORT, LCD_DATA8_PIN, &stcGpioInit );
GPIO_Init( LCD_DATA9_PORT, LCD_DATA9_PIN, &stcGpioInit );
GPIO_Init( LCD_DATA10_PORT, LCD_DATA10_PIN, &stcGpioInit );
GPIO_Init( LCD_DATA11_PORT, LCD_DATA11_PIN, &stcGpioInit );
GPIO_Init( LCD_DATA12_PORT, LCD_DATA12_PIN, &stcGpioInit );
GPIO_Init( LCD_DATA13_PORT, LCD_DATA13_PIN, &stcGpioInit );
GPIO_Init( LCD_DATA14_PORT, LCD_DATA14_PIN, &stcGpioInit );
GPIO_Init( LCD_DATA15_PORT, LCD_DATA15_PIN, &stcGpioInit );
/************************** Set EXMC pin function *************************/
/* SMC_DATA[0:15] */
GPIO_SetFunc( LCD_DATA0_PORT, LCD_DATA0_PIN, GPIO_FUNC_12 );
GPIO_SetFunc( LCD_DATA1_PORT, LCD_DATA1_PIN, GPIO_FUNC_12 );
GPIO_SetFunc( LCD_DATA2_PORT, LCD_DATA2_PIN, GPIO_FUNC_12 );
GPIO_SetFunc( LCD_DATA3_PORT, LCD_DATA3_PIN, GPIO_FUNC_12 );
GPIO_SetFunc( LCD_DATA4_PORT, LCD_DATA4_PIN, GPIO_FUNC_12 );
GPIO_SetFunc( LCD_DATA5_PORT, LCD_DATA5_PIN, GPIO_FUNC_12 );
GPIO_SetFunc( LCD_DATA6_PORT, LCD_DATA6_PIN, GPIO_FUNC_12 );
GPIO_SetFunc( LCD_DATA7_PORT, LCD_DATA7_PIN, GPIO_FUNC_12 );
GPIO_SetFunc( LCD_DATA8_PORT, LCD_DATA8_PIN, GPIO_FUNC_12 );
GPIO_SetFunc( LCD_DATA9_PORT, LCD_DATA9_PIN, GPIO_FUNC_12 );
GPIO_SetFunc( LCD_DATA10_PORT, LCD_DATA10_PIN, GPIO_FUNC_12 );
GPIO_SetFunc( LCD_DATA11_PORT, LCD_DATA11_PIN, GPIO_FUNC_12 );
GPIO_SetFunc( LCD_DATA12_PORT, LCD_DATA12_PIN, GPIO_FUNC_12 );
GPIO_SetFunc( LCD_DATA13_PORT, LCD_DATA13_PIN, GPIO_FUNC_12 );
GPIO_SetFunc( LCD_DATA14_PORT, LCD_DATA14_PIN, GPIO_FUNC_12 );
GPIO_SetFunc( LCD_DATA15_PORT, LCD_DATA15_PIN, GPIO_FUNC_12 );
/* SMC_CS */
GPIO_SetFunc( LCD_CS_PORT, LCD_CS_PIN, GPIO_FUNC_12 );
/* SMC_WE */
GPIO_SetFunc( LCD_WE_PORT, LCD_WE_PIN, GPIO_FUNC_12 );
/* SMC_OE */
GPIO_SetFunc( LCD_OE_PORT, LCD_OE_PIN, GPIO_FUNC_12 );
/* SMC_ADD[0:18]*/
GPIO_SetFunc( LCD_ADD12_PORT, LCD_ADD12_PIN, GPIO_FUNC_12 );
LL_PERIPH_WP( LL_PERIPH_GPIO | LL_PERIPH_FCG | LL_PERIPH_PWC_CLK_RMU | \
LL_PERIPH_EFM | LL_PERIPH_SRAM );
LCD_RSTCmd( 0 );
delay_ms( 50 );
LCD_RSTCmd( 1 );
delay_ms( 50 );
}
/**************************************************************
* @Name bsp_NT35510_EXMC_Init
* @brief
* @param None
* @retval
* @author Zachary
* @Data 2022-11-09
**************************************************************/
static int32_t bsp_NT35510_EXMC_Init( void )
{
__IO uint32_t u32To = 0UL;
int32_t i32Ret = LL_OK;
stc_exmc_smc_init_t stcSmcInit;
stc_exmc_smc_chip_config_t stcChipConfig;
stc_exmc_smc_timing_config_t stcTimingConfig;
en_flag_status_t enChipStatus = RESET;
en_flag_status_t enTimingStatus = RESET;
LL_PERIPH_WE( LL_PERIPH_FCG );
FCG_Fcg3PeriphClockCmd( FCG3_PERIPH_SMC, ENABLE );
EXMC_SMC_Cmd( ENABLE );
EXMC_SMC_ExitLowPower();
while ( EXMC_SMC_READY != EXMC_SMC_GetStatus() )
{
;
}
/* Configure SMC width && CS &chip & timing. */
EXMC_SMC_StructInit( &stcSmcInit );
stcSmcInit.stcChipConfig.u32AddrMatch = 0x60UL;//?
stcSmcInit.stcChipConfig.u32AddrMask = EXMC_SMC_ADDR_MASK_16MB;
stcSmcInit.stcChipConfig.u32MemoryWidth = EXMC_SMC_MEMORY_WIDTH_16BIT;
stcSmcInit.stcChipConfig.u32BAA = EXMC_SMC_BAA_PORT_DISABLE;
stcSmcInit.stcChipConfig.u32ADV = EXMC_SMC_ADV_PORT_DISABLE;
stcSmcInit.stcChipConfig.u32BLS = EXMC_SMC_BLS_SYNC_CS;
stcSmcInit.stcChipConfig.u32ReadBurstLen = EXMC_SMC_READ_BURST_4BEAT;
stcSmcInit.stcChipConfig.u32WriteBurstLen = EXMC_SMC_WRITE_BURST_4BEAT;
stcSmcInit.stcChipConfig.u32ReadMode = EXMC_SMC_READ_SYNC;
stcSmcInit.stcChipConfig.u32WriteMode = EXMC_SMC_WRITE_SYNC;
stcSmcInit.stcTimingConfig.u8RC = 6U;
stcSmcInit.stcTimingConfig.u8WC = 4U;
stcSmcInit.stcTimingConfig.u8CEOE = 1U;
stcSmcInit.stcTimingConfig.u8WP = 2U;
stcSmcInit.stcTimingConfig.u8PC = 0U;//4
stcSmcInit.stcTimingConfig.u8TR = 0U;//1
EXMC_SMC_Init( EXMC_SMC_CHIP3, &stcSmcInit );
/* Set command: updateregs */
EXMC_SMC_SetCommand( EXMC_SMC_CHIP3, EXMC_SMC_CMD_UPDATEREGS, 0UL, 0UL );
/* Check timing status */
u32To = 0UL;
while ( ( enChipStatus != SET ) || ( enTimingStatus != SET ) )
{
( void )EXMC_SMC_GetTimingConfig( EXMC_SMC_CHIP3, &stcTimingConfig );
if ( 0 == memcmp( &stcTimingConfig, &stcSmcInit.stcTimingConfig, sizeof( stcTimingConfig ) ) )
{
enTimingStatus = SET;
}
EXMC_SMC_GetChipConfig( EXMC_SMC_CHIP3, &stcChipConfig );
if ( 0 == memcmp( &stcChipConfig, &stcSmcInit.stcChipConfig, sizeof( stcChipConfig ) ) )
{
enChipStatus = SET;
}
if ( u32To > SMC_MAX_TIMEOUT )
{
i32Ret = LL_ERR;
break;
}
u32To++;
}
LL_PERIPH_WP( LL_PERIPH_FCG );
return i32Ret;
}
以下是液晶屏寄存器读写代码:
typedef struct
{
__IO uint16_t LCD_REG;
__IO uint16_t LCD_RAM;
} NT35510_TypeDef;
/* --- Define ------------------------------------------------------------*/
#define LCD_BASE ( ( uint32_t )( 0x60000000 | 0x00001FFE ) )
#define LCD ( ( NT35510_TypeDef * ) LCD_BASE )
/**************************************************************
* @Name LCD_WR_REG
* @brief 写寄存器函数
* @param regval: [输入/出] 寄存器值
* @retval
* @author Zachary
* @Data 2022-11-09
**************************************************************/
void LCD_WR_REG( __IO uint16_t regval )
{
regval = regval; //使用-O2优化的时候,必须插入的延时
LCD->LCD_REG = regval;//写入要写的寄存器序号
}
/**************************************************************
* @Name LCD_WR_DATA
* @brief 写LCD数据
* @param data: [输入/出] 要写入的值
* @retval
* @author Zachary
* @Data 2022-11-09
**************************************************************/
void LCD_WR_DATA( __IO uint16_t data )
{
data = data; //使用-O2优化的时候,必须插入的延时
LCD->LCD_RAM = data;
}
/**************************************************************
* @Name LCD_RD_DATA
* @brief 读LCD数据
* @param None
* @retval 读到的值
* @author Zachary
* @Data 2022-11-09
**************************************************************/
uint16_t LCD_RD_DATA( void )
{
__IO uint16_t ram; //防止被优化
ram = LCD->LCD_RAM;
return ram;
}
/**************************************************************
* @Name LCD_WriteReg
* @brief 写寄存器
* @param LCD_Reg: [输入/出] 寄存器地址
** LCD_RegValue: [输入/出] 要写入的数据
* @retval
* @author Zachary
* @Data 2022-11-09
**************************************************************/
void LCD_WriteReg( uint16_t LCD_Reg, uint16_t LCD_RegValue )
{
LCD->LCD_REG = LCD_Reg; //写入要写的寄存器序号
LCD->LCD_RAM = LCD_RegValue;//写入数据
}
/**************************************************************
* @Name LCD_ReadReg
* @brief 读寄存器
* @param LCD_Reg: [输入/出] 寄存器地址
* @retval 读到的数据
* @author Zachary
* @Data 2022-11-09
**************************************************************/
uint16_t LCD_ReadReg( uint16_t LCD_Reg )
{
LCD_WR_REG( LCD_Reg ); //写入要读的寄存器序号
// delay_us(5);
return LCD_RD_DATA(); //返回读到的值
}
以下是部分液晶操作函数,主要是画点、清屏、画圆等函数:
/**************************************************************
* @Name LCD_Clear
* @brief 清屏函数
* @param color: [输入/出] 要清屏的填充色
* @retval
* @author Zachary
* @Data 2022-11-09
**************************************************************/
void LCD_Clear( uint16_t color )
{
uint32_t index = 0;
uint32_t totalpoint = lcddev.width;
totalpoint *= lcddev.height; //得到总点数
LCD_SetCursor( 0x00, 0x0000 ); //设置光标位置
LCD->LCD_REG = lcddev.wramcmd; //开始写入GRAM
for ( index = 0; index < totalpoint; index++ )
{
LCD->LCD_RAM = color;
}
}
/**************************************************************
* @Name LCD_Draw_Circle
* @brief 在指定位置画一个指定大小的圆
* @param x0: [输入/出]
** y0: [输入/出] 中心点
** r: [输入/出] 半径
** color: [输入/出]
* @retval
* @author Zachary
* @Data 2022-11-09
**************************************************************/
void LCD_Draw_Circle( uint16_t x0, uint16_t y0, uint8_t r, uint16_t color )
{
int a, b;
int di;
a = 0;
b = r;
di = 3 - ( r << 1 ); //判断下个点位置的标志
while ( a <= b )
{
LCD_DrawPoint( x0 + a, y0 - b, color ); //5
LCD_DrawPoint( x0 + b, y0 - a, color ); //0
LCD_DrawPoint( x0 + b, y0 + a, color ); //4
LCD_DrawPoint( x0 + a, y0 + b, color ); //6
LCD_DrawPoint( x0 - a, y0 + b, color ); //1
LCD_DrawPoint( x0 - b, y0 + a, color );
LCD_DrawPoint( x0 - a, y0 - b, color ); //2
LCD_DrawPoint( x0 - b, y0 - a, color ); //7
a++;
//使用Bresenham算法画圆
if ( di < 0 )di += 4 * a + 6;
else
{
di += 10 + 4 * ( a - b );
b--;
}
}
}
/**************************************************************
* @Name LCD_ShowChar
* @brief 在指定位置显示一个字符
* @param x: [输入/出]
** y: [输入/出] 起始坐标
** num: [输入/出] 要显示的字符
** size: [输入/出] 字体大小
** mode: [输入/出] 叠加方式
* @retval
* @author Zachary
* @Data 2022-11-09
**************************************************************/
void LCD_ShowChar( uint16_t x, uint16_t y, uint8_t num, uint8_t size, uint8_t mode, uint16_t frontcolor, uint16_t backcolor )
{
uint8_t temp, t1, t;
uint16_t y0 = y;
uint8_t csize = ( size / 8 + ( ( size % 8 ) ? 1 : 0 ) ) * ( size / 2 ); //得到字体一个字符对应点阵集所占的字节数
num = num - ' '; //得到偏移后的值(ASCII字库是从空格开始取模,所以-' '就是对应字符的字库)
for( t = 0; t < csize; t++ )
{
if( size == 12 )
temp = asc2_1206[num][t]; //调用1206字体
else if( size == 16 )
temp = asc2_1608[num][t]; //调用1608字体
else if( size == 24 )
temp = asc2_2412[num][t]; //调用2412字体
else
return; //没有的字库
for( t1 = 0; t1 < 8; t1++ )
{
if( temp & 0x80 )
LCD_Fast_DrawPoint( x, y, frontcolor );
else if( mode == 0 )
LCD_Fast_DrawPoint( x, y, backcolor );
temp <<= 1;
y++;
if( y >= lcddev.height )
return; //超区域了
if( ( y - y0 ) == size )
{
y = y0;
x++;
if( x >= lcddev.width )
return; //超区域了
break;
}
}
}
}
/**************************************************************
* @Name LCD_ShowString
* @brief 显示字符串
* @param x: [输入/出]
** y: [输入/出] 起点坐标
** width: [输入/出]
** height: [输入/出] 区域大小
** size: [输入/出] 字体大小
** p: [输入/出] 字符串起始地址
** frontcolor: [输入/出]
** backcolor: [输入/出]
* @retval
* @author Zachary
* @Data 2022-11-09
**************************************************************/
void LCD_ShowString( uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t size, uint8_t *p, uint16_t frontcolor, uint16_t backcolor )
{
uint8_t x0 = x;
width += x;
height += y;
while ( ( *p <= '~' ) && ( *p >= ' ' ) ) //判断是不是非法字符!
{
if ( x >= width )
{
x = x0;
y += size;
}
if ( y >= height )
break; //退出
LCD_ShowChar( x, y, *p, size, 0, frontcolor, backcolor );
x += size / 2;
p++;
}
}
以下是刷屏测试和字符显示代码:
/**************************************************************
* @Name main
* @brief
* @param None
* @retval
* @author Zachary
* @Data 2022-02-13
**************************************************************/
int32_t main( void )
{
SysInit();
while( 1 )
{
LED10_TOGGLE();
LED11_TOGGLE();
TCA9539_WritePin( TCA9539_IO_PORT1, TCA9539_IO_PIN7, TCA9539_PIN_SET );
delay_ms( 500 );
TCA9539_WritePin( TCA9539_IO_PORT1, TCA9539_IO_PIN7, TCA9539_PIN_RESET );
delay_ms( 500 );
}
}
/**************************************************************
* @Name SysInit
* @brief
* @param None
* @retval
* @author Zachary
* @Data 2023-02-13
**************************************************************/
static void SysInit( void )
{
bsp_SetSysClk();
CLK_GetClockFreq( &sysclk ); /* ---检查时钟是否正确--- */
delay_init( 240 ); /* ---系统滴答定时器初始化--- */
bsp_Gpio_Init(); /* ---初始化Gpio--- */
bsp_TCA9539_Init();
TCA9539_ConfigPin( TCA9539_IO_PORT1, TCA9539_IO_PIN7, TCA9539_DIR_OUT );
bsp_NT35510_Init();
LCD_Test();
}
/**************************************************************
* @Name LCD_Test
* @brief
* @param None
* @retval
* @author Zachary
* @Data 2023-03-04
**************************************************************/
static void LCD_Test( void )
{
LCD_Clear( RED );
delay_ms( 500 );
LCD_Clear( GREEN );
delay_ms( 500 );
LCD_Clear( BLACK );
delay_ms( 500 );
LCD_Clear( BLUE );
delay_ms( 500 );
LCD_Clear( YELLOW );
delay_ms( 500 );
LCD_Clear( MAGENTA );
delay_ms( 500 );
LCD_Draw_Circle( 200, 200, 100, BLACK );
LCD_ShowString( 300, 300, lcddev.width, lcddev.height, 24, ( uint8_t * )"hello world", BLACK, MAGENTA );
}
以下是测试视频:
以下是代码附件:
正好手上有一块咸鱼上50块买的仿正点原子的4.0寸液晶屏,我花了198买了原子的屏。