STM32F429第二十五篇之MCU屏实验详解
Posted 海洋想想
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32F429第二十五篇之MCU屏实验详解相关的知识,希望对你有一定的参考价值。
文章目录
- 前言
- 硬件
- 软件
- 结构体
- SRAM_HandleTypeDef
- FMC_NORSRAM_InitTypeDef
- NSBank(SRAM内存块选择)
- DataAddressMux(数据地址总线)
- MemoryType(存储器类型)
- MemoryDataWidth(存储器数据总线宽度)
- BurstAccessMode(突发模式)
- WaitSignalPolarity(等待信号极性)
- WrapMode(回卷模式)
- WaitSignalActive(等待时序配置)
- WriteOperation(写操作)
- WaitSignal(等待使能)
- ExtendedMode(拓展模式)
- AsynchronousWait(同步传输等待)
- WriteBurst(写突发使能)
- ContinuousClock(连续时钟)
- WriteFifo(写队列)
- PageSize(页容量)
- FMC_NORSRAM_TimingTypeDef
- 程序
前言
本文主要介绍F429通过SRAM并口模块驱动MCU显示屏的实验详解,这部分涉及以下部分知识:
- MCU显示屏
- SRAM并口——FMC 的原理及HAL库的实现
该实验实现的功能为,每经过1秒中,执行一次以下操作:
- LED灯反转一次。
- 屏幕背景颜色变化一次。
且 在屏幕上 用不同字号显示一串信息。
硬件
硬件连接部分:
- 16位数据总线——写入读取数据
- A18——写入命令/数据
- NE1——片选信号
- NWE——写信号
- NOE——读信号
- BL——背光使能
软件
结构体
SRAM_HandleTypeDef
/**
* @brief SRAM handle Structure definition
*/
#if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1)
typedef struct __SRAM_HandleTypeDef
#else
typedef struct
#endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */
{
FMC_NORSRAM_TypeDef *Instance; /*!< Register base address */
FMC_NORSRAM_EXTENDED_TypeDef *Extended; /*!< Extended mode register base address */
FMC_NORSRAM_InitTypeDef Init; /*!< SRAM device control configuration parameters */
HAL_LockTypeDef Lock; /*!< SRAM locking object */
__IO HAL_SRAM_StateTypeDef State; /*!< SRAM device access state */
DMA_HandleTypeDef *hdma; /*!< Pointer DMA handler */
#if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1)
void (* MspInitCallback) ( struct __SRAM_HandleTypeDef * hsram); /*!< SRAM Msp Init callback */
void (* MspDeInitCallback) ( struct __SRAM_HandleTypeDef * hsram); /*!< SRAM Msp DeInit callback */
void (* DmaXferCpltCallback) ( DMA_HandleTypeDef * hdma); /*!< SRAM DMA Xfer Complete callback */
void (* DmaXferErrorCallback) ( DMA_HandleTypeDef * hdma); /*!< SRAM DMA Xfer Error callback */
#endif
} SRAM_HandleTypeDef;
Instance(FMC寄存器地址)
此处可以认为是固定值:
#define FMC_NORSRAM_DEVICE FMC_Bank1
具体的取值为:
#define FMC_R_BASE 0xA0000000UL /*!< FMC registers base address */
这是FMC的寄存器地址分配:
Extended(拓展寄存器地址)
#define FMC_NORSRAM_EXTENDED_DEVICE FMC_Bank1E
此处对应拓展寄存器,该部分地址为:
#define FMC_Bank1E_R_BASE (FMC_R_BASE + 0x0104UL)
Init(初始化变量)
结构体FMC_NORSRAM_InitTypeDef
变量。详细见后文。
Lock(锁)
取值为:
/**
* @brief HAL Lock structures definition
*/
typedef enum
{
HAL_UNLOCKED = 0x00U,
HAL_LOCKED = 0x01U
} HAL_LockTypeDef;
State(状态)
取值范围为:
/**
* @brief HAL SRAM State structures definition
*/
typedef enum
{
HAL_SRAM_STATE_RESET = 0x00U, /*!< SRAM not yet initialized or disabled */
HAL_SRAM_STATE_READY = 0x01U, /*!< SRAM initialized and ready for use */
HAL_SRAM_STATE_BUSY = 0x02U, /*!< SRAM internal process is ongoing */
HAL_SRAM_STATE_ERROR = 0x03U, /*!< SRAM error state */
HAL_SRAM_STATE_PROTECTED = 0x04U /*!< SRAM peripheral NORSRAM device write protected */
} HAL_SRAM_StateTypeDef;
hdma(dma句柄)
暂时不用
FMC_NORSRAM_InitTypeDef
/**
* @brief FMC NORSRAM Configuration Structure definition
*/
typedef struct
{
uint32_t NSBank; /*!< Specifies the NORSRAM memory device that will be used.
This parameter can be a value of @ref FMC_NORSRAM_Bank */
uint32_t DataAddressMux; /*!< Specifies whether the address and data values are
multiplexed on the data bus or not.
This parameter can be a value of @ref FMC_Data_Address_Bus_Multiplexing */
uint32_t MemoryType; /*!< Specifies the type of external memory attached to
the corresponding memory device.
This parameter can be a value of @ref FMC_Memory_Type */
uint32_t MemoryDataWidth; /*!< Specifies the external memory device width.
This parameter can be a value of @ref FMC_NORSRAM_Data_Width */
uint32_t BurstAccessMode; /*!< Enables or disables the burst access mode for Flash memory,
valid only with synchronous burst Flash memories.
This parameter can be a value of @ref FMC_Burst_Access_Mode */
uint32_t WaitSignalPolarity; /*!< Specifies the wait signal polarity, valid only when accessing
the Flash memory in burst mode.
This parameter can be a value of @ref FMC_Wait_Signal_Polarity */
uint32_t WrapMode; /*!< Enables or disables the Wrapped burst access mode for Flash
memory, valid only when accessing Flash memories in burst mode.
This parameter can be a value of @ref FMC_Wrap_Mode
This mode is not available for the STM32F446/467/479xx devices */
uint32_t WaitSignalActive; /*!< Specifies if the wait signal is asserted by the memory one
clock cycle before the wait state or during the wait state,
valid only when accessing memories in burst mode.
This parameter can be a value of @ref FMC_Wait_Timing */
uint32_t WriteOperation; /*!< Enables or disables the write operation in the selected device by the FMC.
This parameter can be a value of @ref FMC_Write_Operation */
uint32_t WaitSignal; /*!< Enables or disables the wait state insertion via wait
signal, valid for Flash memory access in burst mode.
This parameter can be a value of @ref FMC_Wait_Signal */
uint32_t ExtendedMode; /*!< Enables or disables the extended mode.
This parameter can be a value of @ref FMC_Extended_Mode */
uint32_t AsynchronousWait; /*!< Enables or disables wait signal during asynchronous transfers,
valid only with asynchronous Flash memories.
This parameter can be a value of @ref FMC_AsynchronousWait */
uint32_t WriteBurst; /*!< Enables or disables the write burst operation.
This parameter can be a value of @ref FMC_Write_Burst */
uint32_t ContinuousClock; /*!< Enables or disables the FMC clock output to external memory devices.
This parameter is only enabled through the FMC_BCR1 register, and don't care
through FMC_BCR2..4 registers.
This parameter can be a value of @ref FMC_Continous_Clock */
uint32_t WriteFifo; /*!< Enables or disables the write FIFO used by the FMC controller.
This parameter is only enabled through the FMC_BCR1 register, and don't care
through FMC_BCR2..4 registers.
This parameter can be a value of @ref FMC_Write_FIFO
This mode is available only for the STM32F446/469/479xx devices */
uint32_t PageSize; /*!< Specifies the memory page size.
This parameter can be a value of @ref FMC_Page_Size */
}FMC_NORSRAM_InitTypeDef;
NSBank(SRAM内存块选择)
/** @defgroup FMC_NORSRAM_Bank FMC NOR/SRAM Bank
* @{
*/
#define FMC_NORSRAM_BANK1 0x00000000U
#define FMC_NORSRAM_BANK2 0x00000002U
#define FMC_NORSRAM_BANK3 0x00000004U
#define FMC_NORSRAM_BANK4 0x00000006U
/**
* @}
*/
DataAddressMux(数据地址总线)
该位用于配置数据与地址是否共用一条总线,选项如下:
/** @defgroup FMC_Data_Address_Bus_Multiplexing FMC Data Address Bus Multiplexing
* @{
*/
#define FMC_DATA_ADDRESS_MUX_DISABLE 0x00000000U
#define FMC_DATA_ADDRESS_MUX_ENABLE 0x00000002U
/**
* @}
*/
对应寄存器选择如下:
MemoryType(存储器类型)
该寄存器用于指定存储器的类型:
/** @defgroup FMC_Memory_Type FMC Memory Type
* @{
*/
#define FMC_MEMORY_TYPE_SRAM 0x00000000U
#define FMC_MEMORY_TYPE_PSRAM 0x00000004U
#define FMC_MEMORY_TYPE_NOR 0x00000008U
/**
* @}
*/
MemoryDataWidth(存储器数据总线宽度)
该成员用于指定存储器的总线数据宽度:
/** @defgroup FMC_NORSRAM_Data_Width FMC NORSRAM Data Width
* @{
*/
#define FMC_NORSRAM_MEM_BUS_WIDTH_8 0x00000000U
#define FMC_NORSRAM_MEM_BUS_WIDTH_16 0x00000010U
#define FMC_NORSRAM_MEM_BUS_WIDTH_32 0x00000020U
/**
* @}
*/
BurstAccessMode(突发模式)
/** @defgroup FMC_Burst_Access_Mode FMC Burst Access Mode
* @{
*/
#define FMC_BURST_ACCESS_MODE_DISABLE 0x00000000U
#define FMC_BURST_ACCESS_MODE_ENABLE 0x00000100U
/**
* @}
*/
WaitSignalPolarity(等待信号极性)
/** @defgroup FMC_Wait_Signal_Polarity FMC Wait Signal Polarity
* @{
*/
#define FMC_WAIT_SIGNAL_POLARITY_LOW 0x00000000U
#define FMC_WAIT_SIGNAL_POLARITY_HIGH 0x00000200U
/**
* @}
*/
WrapMode(回卷模式)
/** @defgroup FMC_Wrap_Mode FMC Wrap Mode
* @{
*/
/** @note This mode is not available for the STM32F446/469/479xx devices
*/
#define FMC_WRAP_MODE_DISABLE 0x00000000U
#define FMC_WRAP_MODE_ENABLE 0x00000400U
/**
* @}
*/
WaitSignalActive(等待时序配置)
/** @defgroup FMC_Wait_Timing FMC Wait Timing
* @{
*/
#define FMC_WAIT_TIMING_BEFORE_WS 0x00000000U
#define FMC_WAIT_TIMING_DURING_WS 0x00000800U
/**
* @}
*/
WriteOperation(写操作)
写操作使能
/** @defgroup FMC_Write_Operation FMC Write Operation
* @{
*/
#define FMC_WRITE_OPERATION_DISABLE 0x00000000U
#define FMC_WRITE_OPERATION_ENABLE 0x00001000U
/**
* @}
*/
WaitSignal(等待使能)
/** @defgroup FMC_Wait_Signal FMC Wait Signal
* @{
*/
#define FMC_WAIT_SIGNAL_DISABLE 0x00000000U
#define FMC_WAIT_SIGNAL_ENABLE 0x00002000U
/**
* @}
*/
ExtendedMode(拓展模式)
/** @defgroup FMC_Extended_Mode FMC Extended Mode
* @{
*/
#define FMC_EXTENDED_MODE_DISABLE 0x00000000U
#define FMC_EXTENDED_MODE_ENABLE 0x00004000U
/**
* @}
*/
AsynchronousWait(同步传输等待)
/** @defgroup FMC_AsynchronousWait FMC Asynchronous Wait
* @{
*/
#define FMC_ASYNCHRONOUS_WAIT_DISABLE 0x00000000U
#define FMC_ASYNCHRONOUS_WAIT_ENABLE 0x00008000U
/**
* @}
*/
WriteBurst(写突发使能)
/** @defgroup FMC_Write_Burst FMC Write Burst
* @{
*/
#define FMC_WRITE_BURST_DISABLE 0x00000000U
#define FMC_WRITE_BURST_ENABLE 0x00080000U
/**
* @}
*/
ContinuousClock(连续时钟)
/** @defgroup FMC_Continous_Clock FMC Continuous Clock
* @{
*/
#define FMC_CONTINUOUS_CLOCK_SYNC_ONLY 0x00000000U
#define FMC_CONTINUOUS_CLOCK_SYNC_ASYNC 0x00100000U
/**
* @}
*/
/** @defgroup FMC_Write_FIFO FMC Write FIFO
* @note These values are available only for the STM32F446/469/479xx devices.
* @{
*/
#define FMC_WRITE_FIFO_DISABLE ((uint32_t)FMC_BCR1_WFDIS)
#define FMC_WRITE_FIFO_ENABLE 0x00000000U
/**
* @}
*/
WriteFifo(写队列)
/** @defgroup FMC_Write_FIFO FMC Write FIFO
* @note These values are available only for the STM32F446/469/479xx devices.
* @{
*/
#define FMC_WRITE_FIFO_DISABLE ((uint32_t)FMC_BCR1_WFDIS)
#define FMC_WRITE_FIFO_ENABLE 0x00000000U
/**
* @}
*/
此处有点问题FMC_BCR1_WFDIS
没有找到定义。该成员在F429中无效。
PageSize(页容量)
/** @defgroup FMC_Page_Size FMC Page Size
* @{
*/
#define FMC_PAGE_SIZE_NONE 0x00000000U
#define FMC_PAGE_SIZE_128 ((uint32_t)FMC_BCR1_CPSIZE_0)
#define FMC_PAGE_SIZE_256 ((uint32_t)FMC_BCR1_CPSIZE_1)
#define FMC_PAGE_SIZE_512 ((uint32_t)(FMC_BCR1_CPSIZE_0 | FMC_BCR1_CPSIZE_1))
#define FMC_PAGE_SIZE_1024 ((uint32_t)FMC_BCR1_CPSIZE_2)
/**
* @}
*/
FMC_NORSRAM_TimingTypeDef
/**
* @brief FMC NORSRAM Timing parameters structure definition
*/
typedef struct
{
uint32_t AddressSetupTime; /*!< Defines the number of HCLK cycles to configure
the duration of the address setup time.
This parameter can be a value between Min_Data = 0 and Max_Data = 15.
@note This parameter is not used with synchronous NOR Flash memories. */
uint32_t AddressHoldTime; /*!< Defines the number of HCLK cycles to configure
the duration of the address hold time.
This parameter can be a value between Min_Data = 1 and Max_Data = 15.
@note This parameter is not used with synchronous NOR Flash memories. */
uint32_t DataSetupTime; /*!< Defines the number of HCLK cycles to configure
the duration of the data setup time.
This parameter can be a value between Min_Data = 1 and Max_Data = 255.
@note This parameter is used for SRAMs, ROMs and asynchronous multiplexed
NOR Flash memories. */
uint32_t BusTurnAroundDuration; /*!< Defines the number of HCLK cycles to configure
the duration of the bus turnaround.
This parameter can be a value between Min_Data = 0 and Max_Data = 15.
@note This parameter is only used for multiplexed NOR Flash memories. */
uint32_t CLKDivision; /*!< Defines the period of CLK clock output signal, expressed in number of
HCLK cycles. This parameter can be a value between Min_Data = 2 and Max_Data = 16.
@note This parameter is not used for asynchronous NOR Flash, SRAM or ROM
accesses. */
uint32_t DataLatency; /*!< Defines the number of memory clock cycles to issue
to the memory before getting the first data.
The parameter value depends on the memory type as shown below:
- It must be set to 0 in case of a CRAM
- It is don't care in asynchronous NOR, SRAM or ROM accesses
- It may assume a value between Min_Data = 2 and Max_Data = 17 in NOR Flash memories
with synchronous burst mode enable */
uint32_t AccessMode; /*!< Specifies the asynchronous access mode.
This parameter can be a value of @ref FMC_Access_Mode */
}FMC_NORSRAM_TimingTypeDef;
AddressSetupTime(地址建立时间)
取值范围为:[0-15]。
AddressHoldTime(地址保持时间)
该值取值范围为:[1-15]。
DataSetupTime(数据建立时间)
取值范围:[1-255]
BusTurnAroundDuration(总线周转时间)
取值范围:[0-15]
CLKDivision(时钟分频比)
取值范围[2-16]
DataLatency(数据延时)
异步方式此数据无所谓。
AccessMode(访问模式)
/** @defgroup FMC_Access_Mode FMC Access Mode
* @{
*/
#define FMC_ACCESS_MODE_A 0x00000000U
#define FMC_ACCESS_MODE_B 0x10000000U
#define FMC_ACCESS_MODE_C 0x20000000U
#define FMC_ACCESS_MODE_D 0x30000000U
/**
* @}
*/
程序
主程序
int main(void)
{
/* 1.定义变量 */
u8 x = 0;
u8 lcd_id[12];
/* 2.硬件初始化 */
HAL_Init(); //初始化HAL库
Stm32_Clock_Init(360, 25, 2, 8); //设置时钟,180Mhz
delay_init(180); //初始化延时函数
uart_init(115200); //初始化USART
LED_Init(); //初始化LED
LCD_Init(); //初始化LCD
/* 3.功能初始化 */
POINT_COLOR = RED;
sprintf((char *)lcd_id, "LCD ID:%04X", lcddev.id); //将LCD ID打印到lcd_id数组。
/* 4.while循环 */
while (1)
{
switch (x)
{
case 0:
LCD_Clear(WHITE);
break;
case 1:
LCD_Clear(BLACK);
break;
case 2:
LCD_Clear(BLUE);
break;
case 3:
LCD_Clear(RED);
break;
case 4:
LCD_Clear(MAGENTA);
break;
case 5:
LCD_Clear(GREEN);
break;
case 6:
LCD_Clear(CYAN);
break;
case 7:
LCD_Clear(YELLOW);
break;
case 8:
LCD_Clear(BRRED);
break;
case 9:
LCD_Clear(GRAY);
break;
case 10:
LCD_Clear(LGRAY);
break;
case 11:
LCD_Clear(BROWN);
break;
}
POINT_COLOR = RED;
LCD_ShowString(10, 40, 240, 32, 32, "Apollo STM32F4/F7");
LCD_ShowString(10, 80, 240, 24, 24, "TFTLCD TEST");
LCD_ShowString(10, 110, 240, 16, 16, "ATOM@ALIENTEK");
LCD_ShowString(10, 130, 240, 16, 16, lcd_id); //显示LCD ID
LCD_ShowString(10, 150, 240, 12, 12, "2016/1/6");
x++;
if (x == 12)
x = 0;
LED0 = !LED0;
delay_ms(1000);
}
}
主程序主要分成四个部分:
- 变量初始化
- 硬件初始化
- 功能初始化
- while循环
在硬件初始化中,与本文相关的内容为LCD初始化函数LCD_Init()
。该函数会在后文详细介绍。其余硬件已在前面的博文中介绍,此处不再详细列出。
在功能初始化中,主要将文字的颜色设置为红色,且将产品的ID打印到串口中。
在while循环中,每一秒钟执行一次。分别将屏幕的背景颜色修改一次,显示不同大小的字体以及闪烁LED灯。
配置程序
由于本文程序量比较大,本文分块介绍重点实现原理,而不是程序逐条分析,大致分成以下几个部分:
- 指令与数据——分析如何区分35510的指令与数据
- FMC初始化HAL实现方式
指令与数据
在35510屏幕中D/CX管脚区分接收的是指令还是数据,该管脚在硬件上与ARM的A18管脚相连。所以,可以得知:
- 当A18管脚为低电平时,D/CX为低电平,写入的数据为指令。
- 当A18管脚为高电平时,D/CX为高电平,写入的数据为数据。
在35510的数据宽度为16位,所以,ARM的数据总线宽度采用16位。因此,ARM的A18管脚实际上对应的编址为第19位。因此,可以得到:当地址小于2^19(0x80000)时,写入的数据为指令,地址大于0x80000时,写入的数据为数据。可以总结如下:
因此,可以采用一个边界值附近,取0x7FFFE为指令,0x80000为数据。具体实现方式如下:
//LCD地址结构体
typedef struct
{
vu16 LCD_REG; //A18为低
vu16 LCD_RAM; //A18位高
} LCD_TypeDef;
//使用NOR/SRAM的 Bank1.sector1,地址位HADDR[27,26]=00 A18作为数据命令区分线
//注意设置时STM32内部会右移一位对其!
#define LCD_BASE ((u32)(0x60000000 | 0x0007FFFE))
#define LCD ((LCD_TypeDef *)LCD_BASE)
通过以上定义,可以得到:
LCD->LCD_REG//对应地址为0x7FFFE,即为指令
LCD->LCD_RAM//对应地址为0x80000,即为数据
而使用的模块为FMC中的SRAM,所以,其增加一个偏移地址为:0x60000000。
这样,下面的函数就很容易理解:
//写寄存器函数
//regval:寄存器值
void LCD_WR_REG(vu16 regval)
{
regval = regval; //使用-O2优化的时候,必须插入的延时
LCD->LCD_REG = regval; //写入要写的寄存器序号
}
//写LCD数据
//data:要写入的值
void LCD_WR_DATA(vu16 data)
{
data = data; //使用-O2优化的时候,必须插入的延时
LCD->LCD_RAM = data;
}
//读LCD数据
//返回值:读到的值
u16 LCD_RD_DATA(void)
{
vu16 ram; //防止被优化
ram = LCD->LCD_RAM;
return ram;
}
//写寄存器
//LCD_Reg:寄存器地址
//LCD_RegValue:要写入的数据
void LCD_WriteReg(u16 LCD_Reg, u16 LCD_RegValue)
{
LCD->LCD_REG = LCD_Reg; //写入要写的寄存器序号
LCD->LCD_RAM = LCD_RegValue; //写入数据
}
//读寄存器
//LCD_Reg:寄存器地址
//返回值:读到的数据
u16 LCD_ReadReg(u16 LCD_Reg)
{
LCD_WR_REG(LCD_Reg); //写入要读的寄存器序号
delay_us(5);
return LCD_RD_DATA(); //返回读到的值
}
//开始写GRAM
void LCD_WriteRAM_Prepare(void)
{
LCD->LCD_REG = lcddev.wramcmd;
}
//LCD写GRAM
//RGB_Code:颜色值
void LCD_WriteRAM(u16 RGB_Code)
{
LCD->LCD_RAM = RGB_Code; //写十六位GRAM
}
SRAM初始化
HAL_SRAM_Init
/**
* @brief Performs the SRAM device initialization sequence
* @param hsram pointer to a SRAM_HandleTypeDef structure that contains
* the configuration information for SRAM module.
* @param Timing Pointer to SRAM control timing structure
* @param ExtTiming Pointer to SRAM extended mode timing structure
* @retval HAL status
*/
HAL_StatusTypeDef HAL_SRAM_Init(SRAM_HandleTypeDef *hsram, FMC_NORSRAM_TimingTypeDef *Timing, FMC_NORSRAM_TimingTypeDef *ExtTiming)
{
/* Check the SRAM handle parameter */
if(hsram == NULL)
{
return HAL_ERROR;
}
if(hsram->State == HAL_SRAM_STATE_RESET)
{
/* Allocate lock resource and initialize it */
hsram->Lock = HAL以上是关于STM32F429第二十五篇之MCU屏实验详解的主要内容,如果未能解决你的问题,请参考以下文章