STM32——FSMC接口驱动调试ATK-MD0700 模块

本文内容主要记录自己调试正点原子FSMC接口驱动LCD屏代码的过程。

硬件平台

  • 正点原子战舰V3开发板(主控STM32F103ZET6)
  • 正点原子LCD电容触摸屏(ATK-MD0700 V2模块)

(模块驱动代码来自正点原子例程)

使能FSMC时钟和IO口时钟

FSMC 接口有 34 个引脚,使用到了 GPIOD、GPIOE、GPIOF、GPIOG ,需要使能这几个 IO 口的时钟。

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC,ENABLE);	// 使能FSMC时钟
RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOD |
						RCC_APB2Periph_GPIOE |
						RCC_APB2Periph_GPIOF |
						RCC_APB2Periph_GPIOG, ENABLE);

FSMC接口与GPIO引脚的对照如下:

LCD模块需要为 GPIO RS、CS、RD、WR、D0~D15 这几个引脚初始化对应的 GPIO 引脚。配置引脚模式为 复用推挽输出 ,设置为高速率的 50M Hz

// Example:
GPIO_InitTypeDef gpio_init_struct = {0};
/* 初始化RS引脚 */
gpio_init_struct.GPIO_Pin    = GPIOG;
gpio_init_struct.GPIO_Mode   = GPIO_Mode_AF_PP;
gpio_init_struct.GPIO_Speed  = GPIO_Speed_50MHz;
GPIO_Init(GPIOG, &gpio_init_struct);

配置FSMC接口

调试目标是利用 FSMC 接口将 LCD 屏内部存储视为 SRAM 进行操作,需要设置存储类型为 SRAM ,配置为使用 Bank1 Sector4 。
工作模式选择异步方式下的 Module A,并允许对 SRAM 的写操作,设置字长为 16 bit。

/* FSMC 配置 */
FSMC_NSInitStructure.FSMC_Bank 					= ATK_MD0700_FSMC_BANK;				// 使用bank第4区
FSMC_NSInitStructure.FSMC_DataAddressMux 		= FSMC_DataAddressMux_Disable; 		// 不复用数据地址
FSMC_NSInitStructure.FSMC_MemoryType 			= FSMC_MemoryType_SRAM;				// SRAM
FSMC_NSInitStructure.FSMC_MemoryDataWidth 		= FSMC_MemoryDataWidth_16b;
FSMC_NSInitStructure.FSMC_BurstAccessMode 		= FSMC_BurstAccessMode_Disable;
FSMC_NSInitStructure.FSMC_WaitSignalPolarity 	= FSMC_WaitSignalPolarity_Low;
FSMC_NSInitStructure.FSMC_AsynchronousWait 		= FSMC_AsynchronousWait_Disable;
FSMC_NSInitStructure.FSMC_WrapMode 				= FSMC_WrapMode_Disable;
FSMC_NSInitStructure.FSMC_WaitSignalActive 		= FSMC_WaitSignalActive_BeforeWaitState;
FSMC_NSInitStructure.FSMC_WriteOperation 		= FSMC_WriteOperation_Enable;		// 存储器写使能
FSMC_NSInitStructure.FSMC_WaitSignal 			= FSMC_WaitSignal_Disable;
FSMC_NSInitStructure.FSMC_ExtendedMode 			= FSMC_ExtendedMode_Enable;
FSMC_NSInitStructure.FSMC_WriteBurst 			= FSMC_WriteBurst_Disable;

// 读时序配置,单位为 HCLK
readWriteTiming.FSMC_AddressSetupTime			= 0x00;					// 地址建立时间
readWriteTiming.FSMC_DataSetupTime				= 0x0F;					// 数据保存时间
readWriteTiming.FSMC_BusTurnAroundDuration		= 0x00;
readWriteTiming.FSMC_AccessMode 				= FSMC_AccessMode_A;	// 模式 A

// 写时序配置,单位为 HCLK
writeTiming.FSMC_AddressSetupTime 				= 0x00;					// 地址建立时间
writeTiming.FSMC_DataSetupTime 					= 0x01;					// 数据保存时间
writeTiming.FSMC_BusTurnAroundDuration 			= 0x00;
writeTiming.FSMC_AccessMode 					= FSMC_AccessMode_A;	// 模式A

FSMC_NSInitStructure.FSMC_ReadWriteTimingStruct = &readWriteTiming;
FSMC_NSInitStructure.FSMC_WriteTimingStruct 	= &writeTiming;

FSMC_NORSRAMInit(&FSMC_NSInitStructure); 				// 初始化FSMC配置
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE);  			// 使能Bank1

对外开放的API

LCD屏初始化

uint8_t atk_md0700_init(void);

获取LCD屏分辨率信息

uint16_t atk_md0700_get_lcd_width(void);	/* 获取ATK-MD0700模块LCD宽度 */
uint16_t atk_md0700_get_lcd_height(void);	/* 获取ATK-MD0700模块LCD高度 */

显示设置

void atk_md0700_backlight_config(uint8_t pwm);	// 调节背光,范围在 [0, 255],亮度由暗到亮
void atk_md0700_display_on(void);	/* 开启ATK-MD0700模块LCD显示 */
void atk_md0700_display_off(void); 	/* 关闭显示*/

图案绘制

//区域填充,起点坐标(xs,ys),终点坐标(xe,ye),向两点形成的区域填充颜色color
void atk_md0700_fill(uint16_t xs, uint16_t ys, uint16_t xe, uint16_t ye, uint16_t color);

// 清屏,全屏填充为颜色color
void atk_md0700_clear(uint16_t color);

// 在(x,y)处绘制颜色为color的点
void atk_md0700_draw_point(uint16_t x, uint16_t y, uint16_t color);

// 读取点(x,y)的颜色
uint16_t atk_md0700_read_point(uint16_t x, uint16_t y);

// 在(x1,y1)、(x2,y2)两点之间绘制直线,并染色为color
void atk_md0700_draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);

// 绘制点(x1,y1)、(x2,y2)形成的矩形框,染色为color
void atk_md0700_draw_rect(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);

// 以点(x,y)为圆心,r为半径,画圆,圆周线框的颜色为color
void atk_md0700_draw_circle(uint16_t x, uint16_t y, uint16_t r, uint16_t color);

显示字符

void atk_md0700_show_char(uint16_t x, uint16_t y, 
							char ch, atk_md0700_lcd_font_t font, 
							uint16_t color);	/* ATK-MD0700模块LCD显示1个字符 */
							
void atk_md0700_show_string(uint16_t x, uint16_t y, 
							uint16_t width, uint16_t height, 
							char *str, atk_md0700_lcd_font_t font, 
							uint16_t color);	/* ATK-MD0700模块LCD显示字符串 */
							
void atk_md0700_show_xnum(uint16_t x, uint16_t y, 
							uint32_t num, uint8_t len, 
							atk_md0700_num_mode_t mode, atk_md0700_lcd_font_t font, 
							uint16_t color);   /* ATK-MD0700模块LCD显示数字,可控制显示高位0 */
							
void atk_md0700_show_num(uint16_t x, uint16_t y, 
							uint32_t num, uint8_t len, 
							atk_md0700_lcd_font_t font, 
							uint16_t color);	/* ATK-MD0700模块LCD显示数字,不显示高位0 */
							
void atk_md0700_show_pic(uint16_t x, uint16_t y, 
						uint16_t width, uint16_t height, 
						uint8_t *pic);			/* ATK-MD0700模块LCD显示图片 */
posted @ 2023-03-01 22:32  ZenonX  阅读(922)  评论(0编辑  收藏  举报