[MCU] HC32F4A0-TFTLCD

Zachary_yo   2023-3-5 00:04 楼主

本期测评HC32F4A0的EXMC外部存储器控制器来驱动TFTLCD液晶屏,板载的液晶屏接口完全兼容正点原子的液晶屏,正好手上有一块咸鱼上50块买的仿正点原子的4.0寸液晶屏,下图是液晶屏的原理图。

1677937553884.png  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的说明,如下图。

image.png

ST的说明。

image.png

 以下是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 );
}

以下是测试视频:

76bdfa4868df565d3a910ce4460a3fde

 

以下是代码附件:

HC32F4A0_TFTLCD.7z (1.09 MB)
(下载次数: 11, 2023-3-5 00:03 上传)

   

回复评论 (1)

正好手上有一块咸鱼上50块买的仿正点原子的4.0寸液晶屏,我花了198买了原子的屏。

点赞 (1) 2023-3-6 08:52
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复