5、示例程序
5.1 SPI 驱动程序
GT5GL64芯片在使用“Quad Output Fast Read”, “Quad I/O Fast Read” (6BH, EBH)指令时支持Quad SPI操作,这些指令允许数据以标准SPI的四倍速率与设备进行传输,使用Quad SPI 指令时,SI和SO引脚变为双向I/O引脚(IO0和IO1),WP#和HOLD#变为IO2和IO3。 Quad SPI指令需要设置状态寄存器中的Quad Enable bit (QE)为1。
//注:此代码是在雅特力AT32F437VGT7实现的代码,仅供参考,其他MCU请参考各自MCU厂商提供的SDK编写SPI驱动。 /** * @brief Write a byte to flash * @param data: Data to write * @retval Flash return data */ uint8_t spi_byte_write(uint8_t data) { uint8_t brxbuff; spi_i2s_dma_transmitter_enable(SPI4, FALSE); // 禁用DMA传输 spi_i2s_dma_receiver_enable(SPI4, FALSE); // 禁用DMA接收 spi_i2s_data_transmit(SPI4, data); // 发送数据 while (spi_i2s_flag_get(SPI4, SPI_I2S_RDBF_FLAG) == RESET); // 等待接收缓冲区非空 brxbuff = spi_i2s_data_receive(SPI4); // 接收数据 while (spi_i2s_flag_get(SPI4, SPI_I2S_BF_FLAG) != RESET); // 等待传输完成 return brxbuff; // 返回接收到的数据 }
/** * @brief Read a byte from flash * @param none * @retval Flash return data */ uint8_t spi_byte_read(void) { return (spi_byte_write(FLASH_SPI_DUMMY_BYTE)); // 发送虚拟字节并返回接收到的数据 }
/** * @brief Read data from flash * @param pbuffer: Pointer to data buffer * @param read_addr: Address where the data is read * @param length: Buffer length * @retval none */ void spiflash_read(uint8_t *pbuffer, uint32_t read_addr, uint32_t length) { FLASH_CS_LOW(); // 片选拉低 spi_byte_write(0x03); // 发送读取指令0x03 spi_byte_write((uint8_t)((read_addr) >> 16)); // 发送24位地址 spi_byte_write((uint8_t)((read_addr) >> 8)); spi_byte_write((uint8_t)read_addr); // spi_byte_write((uint8_t)0xff); // 使用0x0B快速读取时需额外发送一个字节 spi_bytes_read(pbuffer, length); // 读取数据 FLASH_CS_HIGH(); // 片选拉高 }
/** * @brief Erase a sector of data * @param erase_addr: Sector address to erase * @retval none */ void spiflash_sector_erase(uint32_t erase_addr) { spiflash_write_enable(); // 使能写操作 spiflash_write_enable(); // 再次使能写操作 spiflash_wait_busy(); // 等待设备空闲 FLASH_CS_LOW(); // 片选拉低 spi_byte_write(0x20); // 发送擦除指令0x20 spi_byte_write((uint8_t)((erase_addr) >> 16)); // 发送24位地址 spi_byte_write((uint8_t)((erase_addr) >> 8)); spi_byte_write((uint8_t)erase_addr); FLASH_CS_HIGH(); // 片选拉高 spiflash_wait_busy(); // 等待擦除完成 }
/** * @brief Read data continuously * @param pbuffer: Buffer to save data * @param length: Buffer length * @retval none */ void spi_bytes_read(uint8_t *pbuffer, uint32_t length) { while (length--) { while (spi_i2s_flag_get(SPI4, SPI_I2S_TDBE_FLAG) == RESET); // 等待发送缓冲区空 spi_i2s_data_transmit(SPI4, 0xa5); // 发送任意值 while (spi_i2s_flag_get(SPI4, SPI_I2S_RDBF_FLAG) == RESET); // 等待接收缓冲区非空 *pbuffer = spi_i2s_data_receive(SPI4); // 接收数据 pbuffer++; // 指针后移 } }
/** * @brief Read device ID * @param none * @retval Device ID */ uint16_t spiflash_read_id(void) { uint16_t wreceivedata = 0; FLASH_CS_LOW(); // 片选拉低 spi_byte_write(0x90); // 发送读取ID指令0x90 spi_byte_write(0x00); // 发送三个字节的0x00 spi_byte_write(0x00); spi_byte_write(0x00); wreceivedata |= spi_byte_read() << 8; // 读取高8位ID wreceivedata |= spi_byte_read(); // 读取低8位ID FLASH_CS_HIGH(); // 片选拉高 return wreceivedata; // 返回设备ID } |
5.2 Quad SPI 通信程序
//注:此代码是在雅特力AT32F437VGT7实现的代码,仅供参考,其他MCU请参考各自MCU厂商提供的SDK编写QSPI驱动。
#include "qspi_flash.h" // 假设有一个头文件包含必要的定义和声明
qspi_cmd_type qspi_flash_cmd_config;
#define QSPI_FLASH_FIFO_DEPTH (32 * 4) #define QSPI_FLASH_PAGE_SIZE 256 #define QSPI_FLASH_QSPIx QSPI1
/** * @brief qspi flash 写使能 * @param none * @retval none */ void qspi_flash_write_enable(void) { // 写使能配置 qspi_flash_cmd_wren_config(&qspi_flash_cmd_config); qspi_cmd_operation_kick(QSPI_FLASH_QSPIx, &qspi_flash_cmd_config);
// 等待命令完成 while (qspi_flag_get(QSPI_FLASH_QSPIx, QSPI_CMDSTS_FLAG) == RESET); qspi_flag_clear(QSPI_FLASH_QSPIx, QSPI_CMDSTS_FLAG); }
/** * @brief qspi_flash 擦除命令配置 * @param qspi_cmd_struct: qspi_cmd_type 参数的指针 * @param addr: 擦除地址 * @retval none */ void qspi_flash_cmd_erase_config(qspi_cmd_type *qspi_cmd_struct, uint32_t addr) { qspi_cmd_struct->pe_mode_enable = FALSE; // 性能增强模式关闭 qspi_cmd_struct->pe_mode_operate_code = 0; qspi_cmd_struct->instruction_code = 0x20; // 擦除指令 qspi_cmd_struct->instruction_length = QSPI_CMD_INSLEN_1_BYTE; // 命令长度 qspi_cmd_struct->address_code = addr; // 擦除地址 qspi_cmd_struct->address_length = QSPI_CMD_ADRLEN_3_BYTE; // 地址长度 3 字节 qspi_cmd_struct->data_counter = 0; qspi_cmd_struct->second_dummy_cycle_num = 0; qspi_cmd_struct->operation_mode = QSPI_OPERATE_MODE_111; qspi_cmd_struct->read_status_config = QSPI_RSTSC_HW_AUTO; qspi_cmd_struct->read_status_enable = FALSE; qspi_cmd_struct->write_data_enable = TRUE; }
/** * @brief qspi_flash 读状态寄存器命令配置 * @param qspi_cmd_struct: qspi_cmd_type 参数的指针 * @retval none */ void qspi_flash_cmd_rdsr_config(qspi_cmd_type *qspi_cmd_struct) { qspi_cmd_struct->pe_mode_enable = FALSE; qspi_cmd_struct->pe_mode_operate_code = 0; qspi_cmd_struct->instruction_code = 0x05; // 读状态寄存器指令 qspi_cmd_struct->instruction_length = QSPI_CMD_INSLEN_1_BYTE; // 命令长度 qspi_cmd_struct->address_code = 0; qspi_cmd_struct->address_length = QSPI_CMD_ADRLEN_0_BYTE; qspi_cmd_struct->data_counter = 0; qspi_cmd_struct->second_dummy_cycle_num = 0; qspi_cmd_struct->operation_mode = QSPI_OPERATE_MODE_111; qspi_cmd_struct->read_status_config = QSPI_RSTSC_HW_AUTO; qspi_cmd_struct->read_status_enable = TRUE; qspi_cmd_struct->write_data_enable = FALSE; }
/** * @brief qspi flash 检查忙状态 * @param none * @retval none */ void qspi_flash_busy_check(void) { qspi_flash_cmd_rdsr_config(&qspi_flash_cmd_config); qspi_cmd_operation_kick(QSPI_FLASH_QSPIx, &qspi_flash_cmd_config);
// 等待命令完成 while (qspi_flag_get(QSPI_FLASH_QSPIx, QSPI_CMDSTS_FLAG) == RESET); qspi_flag_clear(QSPI_FLASH_QSPIx, QSPI_CMDSTS_FLAG); }
/** * @brief qspi flash 擦除数据 * @param sec_addr: 擦除扇区地址 * @retval none */ void qspi_flash_erase(uint32_t sec_addr) { qspi_flash_write_enable(); // 写使能 qspi_flash_cmd_erase_config(&qspi_flash_cmd_config, sec_addr); // 擦除结构体配置 qspi_cmd_operation_kick(QSPI_FLASH_QSPIx, &qspi_flash_cmd_config); // 执行擦除操作
// 等待命令完成 while (qspi_flag_get(QSPI_FLASH_QSPIx, QSPI_CMDSTS_FLAG) == RESET); qspi_flag_clear(QSPI_FLASH_QSPIx, QSPI_CMDSTS_FLAG); qspi_flash_busy_check(); // 检查忙状态 }
/** * @brief qspi_flash 读命令配置 * @param qspi_cmd_struct: qspi_cmd_type 参数的指针 * @param addr: 读取起始地址 * @param counter: 读取数据计数 * @retval none */ void qspi_flash_cmd_read_config(qspi_cmd_type *qspi_cmd_struct, uint32_t addr, uint32_t counter) { qspi_cmd_struct->pe_mode_enable = FALSE; // 性能增强模式关闭 qspi_cmd_struct->pe_mode_operate_code = 0; qspi_cmd_struct->instruction_code = 0xEB; // 四线读指令 qspi_cmd_struct->instruction_length = QSPI_CMD_INSLEN_1_BYTE; // 命令长度 qspi_cmd_struct->address_code = addr; // 读取地址 qspi_cmd_struct->address_length = QSPI_CMD_ADRLEN_3_BYTE; // 地址长度 3 字节 qspi_cmd_struct->data_counter = counter; // 读取数据长度 qspi_cmd_struct->second_dummy_cycle_num = 6; // 第二个虚拟状态周期数 6 qspi_cmd_struct->operation_mode = QSPI_OPERATE_MODE_144; // 指令单线,地址4线,数据4线 qspi_cmd_struct->read_status_config = QSPI_RSTSC_HW_AUTO; // 硬件读取 qspi_cmd_struct->read_status_enable = FALSE; qspi_cmd_struct->write_data_enable = FALSE; }
/** * @brief qspi_flash 读命令配置 * @param qspi_cmd_struct: qspi_cmd_type 参数的指针 * @param addr: 读取起始地址 * @param counter: 读取数据计数 * @retval none */ void qspi_flash_cmd_read_config_6B(qspi_cmd_type *qspi_cmd_struct, uint32_t addr, uint32_t counter) { qspi_cmd_struct->pe_mode_enable = FALSE; // 性能增强模式关闭 qspi_cmd_struct->pe_mode_operate_code = 0; qspi_cmd_struct->instruction_code = 0x6B; // 四线读指令 qspi_cmd_struct->instruction_length = QSPI_CMD_INSLEN_1_BYTE; // 命令长度 qspi_cmd_struct->address_code = addr; // 读取地址 qspi_cmd_struct->address_length = QSPI_CMD_ADRLEN_3_BYTE; // 地址长度 3 字节 qspi_cmd_struct->data_counter = counter; // 读取数据长度 qspi_cmd_struct->second_dummy_cycle_num = 8; // 第二个虚拟状态周期数 6 qspi_cmd_struct->operation_mode = QSPI_OPERATE_MODE_114; // 指令单线,地址单线,数据4线 qspi_cmd_struct->read_status_config = QSPI_RSTSC_HW_AUTO; // 硬件读取 qspi_cmd_struct->read_status_enable = FALSE; qspi_cmd_struct->write_data_enable = FALSE; }
/** * @brief qspi flash 读取数据 * @param addr: 读取地址 * @param total_len: 读取长度 * @param buf: 读取数据的指针 * @retval none */ void qspi_flash_data_read(uint32_t addr, uint8_t* buf, uint32_t total_len) { uint32_t i, len = total_len;
// qspi_flash_cmd_read_config_6B(&qspi_flash_cmd_config, addr, total_len); qspi_flash_cmd_read_config(&qspi_flash_cmd_config, addr, total_len); qspi_cmd_operation_kick(QSPI_FLASH_QSPIx, &qspi_flash_cmd_config);
// 读取数据 do { if (total_len >= QSPI_FLASH_FIFO_DEPTH) { len = QSPI_FLASH_FIFO_DEPTH; } else { len = total_len; }
while (qspi_flag_get(QSPI_FLASH_QSPIx, QSPI_RXFIFORDY_FLAG) == RESET);
for (i = 0; i < len; ++i) { *buf++ = qspi_byte_read(QSPI_FLASH_QSPIx); }
total_len -= len;
} while (total_len);
// 等待命令完成 while (qspi_flag_get(QSPI_FLASH_QSPIx, QSPI_CMDSTS_FLAG) == RESET); qspi_flag_clear(QSPI_FLASH_QSPIx, QSPI_CMDSTS_FLAG); }
/** * @brief qspi flash 写入数据 * @param addr: 写入地址 * @param total_len: 写入长度 * @param buf: 写入数据的指针 * @retval none */ void qspi_flash_data_write(uint32_t addr, uint8_t* buf, uint32_t total_len) { uint32_t i, len;
do { qspi_flash_write_enable();
// 每次最多发送 256 字节,并且只能在一个页面内 len = (addr / QSPI_FLASH_PAGE_SIZE + 1) * QSPI_FLASH_PAGE_SIZE - addr; if (total_len < len) { len = total_len; }
qspi_flash_cmd_write_config(&qspi_flash_cmd_config, addr, len); qspi_cmd_operation_kick(QSPI_FLASH_QSPIx, &qspi_flash_cmd_config);
for (i = 0; i < len; ++i) { while (qspi_flag_get(QSPI_FLASH_QSPIx, QSPI_TXFIFORDY_FLAG) == RESET); qspi_byte_write(QSPI_FLASH_QSPIx, *buf++); }
total_len -= len; addr += len;
// 等待命令完成 while (qspi_flag_get(QSPI_FLASH_QSPIx, QSPI_CMDSTS_FLAG) == RESET); qspi_flag_clear(QSPI_FLASH_QSPIx, QSPI_CMDSTS_FLAG); qspi_flash_busy_check(); } while (total_len); }
|
-
- 高通字库芯片开发资料
- GT-HMI Designer用户手册
- GT-HMI Engine用户手册
- GTDB-X7ESP 高通智匠AI开发板规格书
- GTC-480480TFT40XP模块使用手册
- GTC-480272TFT43XP模块使用手册
- GTC-800480TFT50G模块使用手册
- GTC-800480TFT70GP模块使用手册
- GTC-1024600TFT101GP模块使用手册
- GT-GUI LCD 0.96寸液晶模组数据手册
- GT-GUI LCD 1.9寸液晶模组数据手册
- GT-GUI LCD 2.8寸液晶模组数据手册
- GT-GUI LCD 3.5寸液晶模组数据手册
- GT-GUI LCD 7.0寸液晶模组数据手册
- GT5GL64芯片产品规格书
- GUI-LCD开发板使用手册
高通字库交流群
GT-HMI交流群