历史上的今天
返回首页

历史上的今天

今天是:2024年10月27日(星期日)

正在发生

2021年10月27日 | stm32专题二十一:FSMC液晶显示和扫描方向

2021-10-27 来源:eefocus

液晶屏连接原理图:

其中值得注意的是,LCD_RESET复位引脚和LCD_BL背光,可以选择普通的GPIO来进行控制。而左侧的FSMC数据线,就直接按照编号连接到液晶屏。右侧LCD_CS片选、RD、WE都是FSMC固定占用的,而命令 / 数据线使用的是地址线A16。


如果程序跑飞了导致下载器无法下载,先按住复位键,再点下载,然后松开复位键就能下载成功。


接下来是代码说明:

初始化GPIO和FMSC,这里一个值得注意点地方就是,我们模拟8080时序使用的是FSMC模式B,这其中有一些时序参数。在操作SRAM时,这些参数可以通过SRAM提供的数据手册来得到。而在驱动液晶屏时,因为提供的参数并没有严格对应,需要使用实验测试参数。多测试几组参数,来获得一个相对稳定且速度较快的参数值。


void ILI9341_GPIO_Config(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

 

// 打开 GPIO的时钟

RCC_APB2PeriphClockCmd(ILI9341_CS_CLK | ILI9341_DC_CLK | ILI9341_WR_CLK | ILI9341_RD_CLK | ILI9341_BK_CLK | 

ILI9341_RST_CLK | ILI9341_D0_CLK | ILI9341_D1_CLK | ILI9341_D2_CLK | ILI9341_D3_CLK | ILI9341_D4_CLK | 

ILI9341_D5_CLK | ILI9341_D6_CLK | ILI9341_D7_CLK |ILI9341_D8_CLK | ILI9341_D9_CLK | ILI9341_D10_CLK | 

ILI9341_D11_CLK | ILI9341_D12_CLK | ILI9341_D13_CLK | ILI9341_D14_CLK| ILI9341_D15_CLK, ENABLE);

// 初始化背光和复位引脚(通用推挽模式)

/* 控制引脚 */

GPIO_InitStructure.GPIO_Pin = ILI9341_RST_PIN;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(ILI9341_RST_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = ILI9341_BK_PIN;

GPIO_Init(ILI9341_BK_PORT, &GPIO_InitStructure);

// 初始化其他引脚(复用推挽模式)

/* 控制引脚 */

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Pin = ILI9341_CS_PIN;

GPIO_Init(ILI9341_CS_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = ILI9341_RD_PIN;

GPIO_Init(ILI9341_RD_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = ILI9341_RD_PIN;

GPIO_Init(ILI9341_RD_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = ILI9341_WR_PIN;

GPIO_Init(ILI9341_WR_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = ILI9341_DC_PIN;

GPIO_Init(ILI9341_DC_PORT, &GPIO_InitStructure);

/* 数据引脚 */

GPIO_InitStructure.GPIO_Pin = ILI9341_D0_PIN;

GPIO_Init(ILI9341_D0_PORT, &GPIO_InitStructure);

 

GPIO_InitStructure.GPIO_Pin = ILI9341_D1_PIN;

GPIO_Init(ILI9341_D1_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = ILI9341_D2_PIN;

GPIO_Init(ILI9341_D2_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = ILI9341_D3_PIN;

GPIO_Init(ILI9341_D3_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = ILI9341_D4_PIN;

GPIO_Init(ILI9341_D4_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = ILI9341_D5_PIN;

GPIO_Init(ILI9341_D5_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = ILI9341_D6_PIN;

GPIO_Init(ILI9341_D6_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = ILI9341_D7_PIN;

GPIO_Init(ILI9341_D7_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = ILI9341_D8_PIN;

GPIO_Init(ILI9341_D8_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = ILI9341_D9_PIN;

GPIO_Init(ILI9341_D9_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = ILI9341_D10_PIN;

GPIO_Init(ILI9341_D10_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = ILI9341_D11_PIN;

GPIO_Init(ILI9341_D11_PORT, &GPIO_InitStructure);

 

GPIO_InitStructure.GPIO_Pin = ILI9341_D12_PIN;

GPIO_Init(ILI9341_D12_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = ILI9341_D13_PIN;

GPIO_Init(ILI9341_D13_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = ILI9341_D14_PIN;

GPIO_Init(ILI9341_D14_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = ILI9341_D15_PIN;

GPIO_Init(ILI9341_D15_PORT, &GPIO_InitStructure);

}

 

 

void ILI9341_FSMC_Config(void)

{

FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;

FSMC_NORSRAMTimingInitTypeDef  readWriteTiming;

 

/*使能FSMC外设时钟*/

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC,ENABLE);

 

/* 这里地址建立时间和数据保持时间,在ILI9341数据手册中没有明确的给出来,

我们实际上是通过实验的方式,来直接测试几个参数,如果可以用就ok

如果把数据改大一点,就不容易出错,但数据改小一点的话,速度就会变快 */

//地址建立时间(ADDSET)

readWriteTiming.FSMC_AddressSetupTime = 0x01; // 数据是试出来的,且有一定余量

 

//数据保持时间(DATAST)

readWriteTiming.FSMC_DataSetupTime = 0x04; // 数据是试出来的,且有一定余量

 

//地址保持时间(ADDHLD)模式B未用到

readWriteTiming.FSMC_AddressHoldTime = 0x00;

//设置总线转换周期,仅用于复用模式的NOR操作

readWriteTiming.FSMC_BusTurnAroundDuration = 0x00;

//设置时钟分频,仅用于同步类型的存储器

readWriteTiming.FSMC_CLKDivision = 0x00;

 

//数据保持时间,仅用于同步型的NOR

readWriteTiming.FSMC_DataLatency = 0x00;

//选择匹配SRAM的模式

readWriteTiming.FSMC_AccessMode = FSMC_AccessMode_B;  

    

// 选择FSMC映射的存储区域: Bank1 sram1

FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1;

//设置地址总线与数据总线是否复用,仅用于NOR

FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; 

//设置要控制的存储器类型:NOR类型

FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;   

//存储器数据宽度:16位

FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; 

//设置是否使用突发访问模式,仅用于同步类型的存储器

FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode =FSMC_BurstAccessMode_Disable;

//设置是否使能等待信号,仅用于同步类型的存储器

FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait=FSMC_AsynchronousWait_Disable;

//设置等待信号的有效极性,仅用于同步类型的存储器

FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;

//设置是否支持把非对齐的突发操作,仅用于同步类型的存储器

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_Disable; 

//突发写操作

FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;  

//读写时序配置

FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &readWriteTiming;

//读写同样时序,使用扩展模式时这个配置才有效

FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &readWriteTiming; 

 

FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);  //初始化FSMC配置

 

FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE);  // 使能BANK

}

读写数据的函数:


#define ILI9341_CMD_ADDR ((volatile uint16_t *)(0X60000000))

#define ILI9341_DATA_ADDR ((volatile uint16_t *)(0X60020000))

 

/**

  * @brief  向ILI9341写入命令

  * @param  usCmd :要写入的命令(表寄存器地址)

  * @retval 无

  */

__inline void ILI9341_Write_Cmd ( uint16_t usCmd )

{

*ILI9341_CMD_ADDR = usCmd;

}

 

 

/**

  * @brief  向ILI9341写入数据

  * @param  usData :要写入的数据

  * @retval 无

  */

__inline void ILI9341_Write_Data ( uint16_t usData )

{

*ILI9341_DATA_ADDR = usData;

}

 

 

/**

  * @brief  从ILI9341读取数据

  * @param  无

  * @retval 读取到的数据

  */

__inline uint16_t ILI9341_Read_Data ( void )

{

return (*ILI9341_DATA_ADDR);

}

设置背光的函数(起始就是把背光的IO口置成高低电平):


/**

 * @brief  ILI9341背光LED控制

 * @param  enumState :决定是否使能背光LED

  *   该参数为以下值之一:

  *     @arg ENABLE :使能背光LED

  *     @arg DISABLE :禁用背光LED

 * @retval 无

 */

void ILI9341_BackLed_Control ( FunctionalState enumState )

{

if ( enumState )

GPIO_ResetBits ( ILI9341_BK_PORT, ILI9341_BK_PIN );

else

GPIO_SetBits ( ILI9341_BK_PORT, ILI9341_BK_PIN );

}

同理,复位函数就是把接复位引脚的IO口置高低电平:


/**

 * @brief  ILI9341 软件复位

 * @param  无

 * @retval 无

 */

void ILI9341_Rst ( void )

{

GPIO_ResetBits ( ILI9341_RST_PORT, ILI9341_RST_PIN ); //低电平复位

 

ILI9341_Delay ( 0xAFF );    

 

GPIO_SetBits ( ILI9341_RST_PORT, ILI9341_RST_PIN );  

 

ILI9341_Delay ( 0xAFF );

}


初始化寄存器:


这其中值得关注的有三个地方,其他的配置不用过于纠结。


设置列的开始和结束坐标(0X2A):

设置行的开始和结束坐标(0X2B):

显存数据写入:

举个例子如下:

整个设置范围到写入数据的流程图如下:

看一下代码中的列设置:


/* column address control set */

ILI9341_Write_Cmd ( CMD_SetCoordinateX ); 

ILI9341_Write_Data ( 0x00 );

ILI9341_Write_Data ( 0x00 );

ILI9341_Write_Data ( 0x00 );

ILI9341_Write_Data ( 0xEF );

起始列为0,结束列为00EF,EF转成10进制为239,那么列的范围就是0 ~ 239,共240列。

行设置代码:


/* page address control set */

DEBUG_DELAY ();

ILI9341_Write_Cmd ( CMD_SetCoordinateY ); 

ILI9341_Write_Data ( 0x00 );

ILI9341_Write_Data ( 0x00 );

ILI9341_Write_Data ( 0x01 );

ILI9341_Write_Data ( 0x3F );

起始行为0,结束列为013F,EF转成10进制为319,那么行的范围就是0 ~ 319,共320行。

我们使用的屏幕,就正好是 320行 + 240列。


像素格式设置:


/*  Pixel Format Set (3Ah)  */

DEBUG_DELAY ();

ILI9341_Write_Cmd ( 0x3a ); 

ILI9341_Write_Data ( 0x55 );

命令解析:首先发送命令0X3A,这个是用来设置像素格式的(多少位颜色数据),实际上我们希望使用的是RGB565,正好是16位数据对应2字节。对应的正好是0X55。

完整的配置ILI9341寄存器的代码如下:


/**

 * @brief  初始化ILI9341寄存器

 * @param  无

 * @retval 无

 */

static void ILI9341_REG_Config ( void )

{

/*  Power control B (CFh)  */

DEBUG_DELAY  ();

ILI9341_Write_Cmd ( 0xCF  );

ILI9341_Write_Data ( 0x00  );

ILI9341_Write_Data ( 0x81  );

ILI9341_Write_Data ( 0x30  );

/*  Power on sequence control (EDh) */

DEBUG_DELAY ();

ILI9341_Write_Cmd ( 0xED );

ILI9341_Write_Data ( 0x64 );

ILI9341_Write_Data ( 0x03 );

ILI9341_Write_Data ( 0x12 );

ILI9341_Write_Data ( 0x81 );

/*  Driver timing control A (E8h) */

DEBUG_DELAY ();

ILI9341_Write_Cmd ( 0xE8 );

ILI9341_Write_Data ( 0x85 );

ILI9341_Write_Data ( 0x10 );

ILI9341_Write_Data ( 0x78 );

/*  Power control A (CBh) */

DEBUG_DELAY ();

ILI9341_Write_Cmd ( 0xCB );

ILI9341_Write_Data ( 0x39 );

ILI9341_Write_Data ( 0x2C );

ILI9341_Write_Data ( 0x00 );

ILI9341_Write_Data ( 0x34 );

ILI9341_Write_Data ( 0x02 );

/* Pump ratio control (F7h) */

DEBUG_DELAY ();

ILI9341_Write_Cmd ( 0xF7 );

ILI9341_Write_Data ( 0x20 );

/* Driver timing control B */

DEBUG_DELAY ();

ILI9341_Write_Cmd ( 0xEA );

ILI9341_Write_Data ( 0x00 );

ILI9341_Write_Data ( 0x00 );

/* Frame Rate Control (In Normal Mode/Full Colors) (B1h) */

DEBUG_DELAY ();

ILI9341_Write_Cmd ( 0xB1 );

ILI9341_Write_Data ( 0x00 );

ILI9341_Write_Data ( 0x1B );

/*  Display Function Control (B6h) */

DEBUG_DELAY ();

ILI9341_Write_Cmd ( 0xB6 );

ILI9341_Write_Data ( 0x0A );

ILI9341_Write_Data ( 0xA2 );

/* Power Control 1 (C0h) */

DEBUG_DELAY ();

ILI9341_Write_Cmd ( 0xC0 );

ILI9341_Write_Data ( 0x35 );

/* Power Control 2 (C1h) */

DEBUG_DELAY ();

ILI9341_Write_Cmd ( 0xC1 );

ILI9341_Write_Data ( 0x11 );

推荐阅读

史海拾趣

Headland Technology Product Group公司的发展小趣事

在电子行业中,产品质量是企业生存和发展的基石。HBControls深知这一点,因此始终将品质管理放在首位。公司建立了完善的质量管理体系,从原材料采购、生产加工到成品检验,每一个环节都严格把关。此外,HBControls还定期对员工进行质量意识培训,确保每一位员工都能将品质理念融入到日常工作中。正是凭借卓越的产品质量和优质的服务,HBControls赢得了众多客户的信赖和好评。

Global Components & Controls公司的发展小趣事
将挡住光线的纸拿开,观察灯光亮度的变化。如果灯光稍有变化但趋于稳定,说明RP2的调节已到位;如果亮度变化很大,则需要进一步调节RP2使灯光稍有下降直至稳定。
C&K公司的发展小趣事

通过不断的努力和创新,C&K在90年代中期已经成为世界领先的开关制造商之一,也是业内最受信赖的品牌之一。这一成就的取得离不开公司对产品质量的严格把控和对技术创新的持续追求。同时,C&K还积极与全球各地的客户合作,根据他们的需求量身定制开关产品,赢得了广泛的赞誉。

屹晶微(EG)公司的发展小趣事

随着业务的不断拓展和市场的不断扩大,屹晶微逐渐意识到与合作伙伴建立长期战略合作关系的重要性。于是,在2023年,他们与电子产业一站式服务平台华秋电子达成了授权代理合作。这一合作不仅为屹晶微提供了更广阔的市场渠道和客户资源,也为其未来的发展奠定了坚实的基础。

在合作过程中,华秋电子为屹晶微提供了全方位的支持和服务。他们共同推广屹晶微的芯片产品,为客户提供更优质的解决方案和服务。同时,华秋电子还利用自身的技术优势和渠道优势,帮助屹晶微拓展海外市场,提升品牌知名度和影响力。

以上两个故事只是屹晶微在电子行业中发展起来的一部分。他们的发展历程充满了挑战和机遇,但黄米龙和他的团队始终保持着坚定的信念和不懈的努力,为中国的芯片产业做出了积极的贡献。

ELM Technology Corporation公司的发展小趣事

ELM Technology Corporation一直将产品质量视为企业的生命线。公司建立了严格的质量管理体系,从原材料采购到产品生产的每一个环节都进行严格把控。这种对品质的坚持不仅赢得了客户的信任,还为ELM赢得了良好的口碑。在激烈的市场竞争中,ELM凭借卓越的产品品质赢得了市场份额。

Greenliant公司的发展小趣事

随着电动汽车市场的爆发式增长,GPS在2025年决定涉足电动汽车充电基础设施领域。公司推出了一系列快速、智能的电动汽车充电桩,支持多种充电标准和支付方式,满足了不同用户的需求。同时,GPS还开发了充电站管理软件,实现了充电桩的远程监控和运维管理,提高了充电服务的可靠性和便捷性。GPS的电动汽车充电基础设施解决方案在多个城市得到广泛应用,为电动汽车的普及提供了有力支持。

问答坊 | AI 解惑

ATM监控专业评标标准!!!

ATM监控专业评标标准!!! 资质审查1. 数字录像设备和微型摄像机同时获得公安部安全防范报警系统产品质量监督检验测试中心出具的型式检验报告。 依据标准: A. 公安部关于贯彻实施《安全技术防范产品管理办法》有关问题的补充通知第二条 B. 《 ...…

查看全部问答>

开发板mount 不上PC机

使用是HHARM2410的开发板。NFS服务器配置操作是正确的,PC与开发板之间相互能ping通,但是开发板正常启动后mount 不了PC机。我已经关了防火墙。我主机IP为192.168.2.222。/etc/exports文件设置的是(rw)。在minnicon里执行mount 192.168.2.222:/ /m ...…

查看全部问答>

GSM AT命令 查询手机卡余额

兄弟们,我想做一个GSM短信模块,不知道查询手机卡余额是什么,有人做过吗…

查看全部问答>

vxWorks的etherOutput()是可重入的吗?

vxWorks的etherOutput()是可重入的吗? 似乎从内存池中取内存块没有做保护。…

查看全部问答>

如何申请STM32样片(做电机控制用)代替2406??

                                 如何申请STM32  样片(做电机控制用)代替2406??…

查看全部问答>

总结stm32的i2c的缺陷与使用

如题,本人两个月的经验~~希望对后来者有所帮助 总结STM32的I2C的缺陷与使用.pdf (92.94 KB) 下载次数:672 2010-12-1 08:49 …

查看全部问答>

verilog的一个语法问题

verilog中,一个always中如果含有好几个case语句,那么这些case语句是并发执行,还是顺序执行呢??如下 always begin case(a)    ………… case(b)    ………… case(c)    ………… end  …

查看全部问答>

MSP430G2553串口连接12864显示,只用连接三个引脚,大大节省资源

#include <msp430g2553.h>#define uint unsigned int#define uchar unsigned char#define ulong unsigned longunsigned char a[]={\"波天神终于把12864学会了!\"};#define SID  BIT1#define SCLK BIT2#define CS   BIT3#define ...…

查看全部问答>

IAR仿真问题

我的程序在DEBAG里面可以仿真,并且运行正常,但是在RELEASE状态就不能仿真,进去之后跑没几行就不走了。个人觉得是不是仿真器的事?求指教,求讨论! 下面是option里面的设置: 1.option——linker里的设置:    2.debag里的设置 ...…

查看全部问答>

DIY示波器开源了没有

我很喜欢DIY但是我是菜鸟,楼主DIY的100M数字示波器进行得怎样了,关注中。…

查看全部问答>