目录
概述
1 软硬件介绍
1.1 软件版本信息
1.2 ST7796-LCD
1.3 MCU IO与LCD PIN对应关系
2 FSP配置项目
2.1 配置项目参数
2.2 生成项目框架
3 代码实现
3.1 SPI的库函数
3.1.1 R_SCI_SPI_Open()
3.1.2 R_SCI_SPI_Read()
3.1.3 R_SCI_SPI_Write()
3.2 应用函数接口
3.2.1 SPI初始化函数
3.2.2 读数据接口
3.2.3 写数据接口
3.2.4 回调函数
3.2.5 SPI应用程序源代码
3.3 LCD驱动程序实现
3.3.1 驱动代码
3.3.2 测试代码实现
4 测试结果
概述
本文主要介绍使用Renesas MCU之SPI读写数据功能,包括硬件资源介绍,FSP配置项目的方法,还介绍了SCI_SPI的接口函数,笔者使用一款SPI接口类型的LCD作为Device,使用SCI_SPI接口驱动该LCD,还编写测试函数验证其功能。
1 软硬件介绍
1.1 软件版本信息
软硬件信息 | 版本信息 |
---|---|
Renesas MCU | R7FA4M2AD3C |
Keil | MDK ARM 5.38 |
FSP 版本 | 5.3.0 |
调试工具:st-link | ST-LINK/V2-1 |
注意:
在Keil MDK中可以更改FSP的版本,方法如下
1.2 ST7796-LCD
LCD的PIN引脚功能介绍
序号 | 模块引脚 | 引脚说明 |
1 | VCC | 屏电源正 |
2 | GND | 屏电源地 |
3 | LCD_CS | 液晶屏片选控制信号,低电平有效 |
4 | LCD_RST | 液晶屏复位控制信号,低电平复位 |
5 | LCD_RS | 液晶屏命令/数据选择控制信号 高电平:数据,低电平:命令 |
6 | SDI(MOSI) | SPI总线写数据信号(SD卡和液晶屏共用) |
7 | SCK | SPI总线时钟信号(SD卡和液晶屏共用) |
8 | LED | 液晶屏背光控制信号(如需要控制,请接引脚,如不需要控制,可以不接) |
9 | SDO(MISO) | SPI总线读数据信号(SD卡和液晶屏共用) |
10 | CTP_SCL | 电容触摸屏IIC总线时钟信号(无触摸屏的模块不需连接) |
11 | CTP_RST | 电容触摸屏复位控制信号,低电平复位(无触摸屏的模块不需连接) |
12 | CTP_SDA | 电容触摸屏IIC总线数据信号(无触摸屏的模块不需连接) |
13 | CTP_INT | 电容触摸屏IIC总线触摸中断信号,产生触摸时,输入低电平到主控(无触摸屏的模块不需连接) |
14 | SD_CS | SD卡片选控制信号,低电平有效(不使用SD卡功能,可不接) |
实体LCD Port对应关系如下图所示
1.3 MCU IO与LCD PIN对应关系
RA4M2 PIN引脚 | LCD PIN引脚 |
---|---|
BSP_IO_PORT_01_PIN_01 | MOSI |
BSP_IO_PORT_01_PIN_00 | MISO |
BSP_IO_PORT_01_PIN_02 | SCK |
BSP_IO_PORT_01_PIN_05 | CS |
BSP_IO_PORT_01_PIN_06 | RST |
BSP_IO_PORT_01_PIN_03 | RS |
2 FSP配置项目
2.1 配置项目参数
1)配置系统工作时钟,笔者的开发板使用的外部晶振为12M Hz
2) 在Pins面板上使能SCI0配置,选择IO口如下
3)在stack面板上创建SPI模块
4)配置SPI的相关参数
2.2 生成项目框架
完成参数配置之后,就可以生成项目框架,点击Generate project就可以生成项目代码,使用Keil打开项目,其结构如下:
3 代码实现
3.1 SPI的库函数
3.1.1 R_SCI_SPI_Open()
函数原型:
fsp_err_t R_SCI_SPI_Open( spi_ctrl_t * p_api_ctrl,spi_cfg_t const *const p_cfg )
函数功能: 初始化SPI通信模式
该函数的主要任务如下:
1)执行参数检查和处理错误条件。
2)开启SCI通道时钟。
3)使用默认值和用户可配置选项初始化相关的寄存器。
4)提供与其他API函数一起使用的通道句柄。参数介绍:
返回值:
p_api_ctrl Pointer to the control structure. p_cfg Pointer to a configuration structure.
FSP_SUCCESS Channel initialized successfully. FSP_ERR_ASSERTION An input parameter is invalid or NULL. FSP_ERR_ALREADY_OPEN The instance has already been opened. FSP_ERR_IP_CHANNEL_NOT_PRESENT The channel number is invalid.
3.1.2 R_SCI_SPI_Read()
函数原型:
fsp_err_t R_SCI_SPI_Read ( spi_ctrl_t *const p_api_ctrl,void * p_dest,uint32_t const length,spi_bit_width_t const bit_width )
函数功能:从SPI设备接收数据。
该函数的主要任务如下:
1)执行参数检查和处理错误条件。
2)使发射机。
3)使接收机。
4)启用中断。
5)通过向TXD寄存器写入数据来启动数据传输。
6)从接收缓冲区接收数据发生完全中断,并将数据复制到目标缓冲区。
7)通过接收缓冲区完全中断和发送虚拟数据完成数据接收。
8)禁用发射机。
9)禁用接收机。
10)禁用中断。参数介绍:
返回值介绍:
p_api_ctrl Pointer to the control structure. p_dest Pointer to the destination buffer. length The number of bytes to transfer. bit_width Invalid for SCI_SPI (Set to SPI_BIT_WIDTH_8_BITS).
FSP_SUCCESS Read operation successfully completed. FSP_ERR_ASSERTION One of the following invalid parameters passed:
- Pointer p_api_ctrl is NULL
- Bit width is not 8 bits
- Length is equal to 0
- Pointer to destination is NULL
FSP_ERR_NOT_OPEN The channel has not been opened. Open the channel first. FSP_ERR_UNSUPPORTED The given bit_width is not supported. FSP_ERR_IN_USE A transfer is already in progress.
3.1.3 R_SCI_SPI_Write()
函数原型:
fsp_err_t R_SCI_SPI_Write ( spi_ctrl_t *const p_api_ctrl,void const * p_src,uint32_t const length,spi_bit_width_t const bit_width )
函数功能:将数据传输到SPI设备
该函数的主要任务如下:
1)执行参数检查和处理错误条件。
2)使发射机。
3)启用中断。
4)开始数据传输与数据通过传输缓冲区空中断。
5)从源缓冲区复制数据到SPI数据寄存器进行传输。
6)通过传输缓冲区空中断完成数据传输。
7)禁用发射机。
8)禁用接收机。
9)禁用中断。参数介绍
返回值
p_api_ctrl Pointer to the control structure. p_src Pointer to the source buffer. length The number of bytes to transfer. bit_width Invalid for SCI_SPI (Set to SPI_BIT_WIDTH_8_BITS).
FSP_SUCCESS Write operation successfully completed. FSP_ERR_ASSERTION One of the following invalid parameters passed:
- Pointer p_api_ctrl is NULL
- Pointer to source is NULL
- Length is equal to 0
- Bit width is not equal to 8 bits
FSP_ERR_NOT_OPEN The channel has not been opened. Open the channel first. FSP_ERR_UNSUPPORTED The given bit_width is not supported. FSP_ERR_IN_USE A transfer is already in progress.
3.2 应用函数接口
3.2.1 SPI初始化函数
代码第25行:调用R_SCI_SPI_Open函数初始化SPI接口
3.2.2 读数据接口
代码第48行:调用R_SCI_SPI_Read接口读取数据
代码第50行:等待数据读取完成
3.2.3 写数据接口
代码第37行:调用R_SCI_SPI_Write接口写数据
代码第39行:等待写数据完成
3.2.4 回调函数
代码第14行:检测传输数据事件
代码第15行:数据传输完成,传输数据控制字置位
3.2.5 SPI应用程序源代码
/*FILE NAME : bsp_spi.cDescription: generate pwm by timerAuthor : tangmingfei2013@126.comDate : 2024/06/03*/#include "bsp_spi.h"
#include "hal_data.h"static volatile bool g_transfer_complete = false;
void g_spi0_callback (spi_callback_args_t * p_args)
{if (SPI_EVENT_TRANSFER_COMPLETE == p_args->event){g_transfer_complete = true;}
}void sci_spi_basic_init (void)
{fsp_err_t err = FSP_SUCCESS;/* Initialize the SPI module. */err = R_SCI_SPI_Open(&g_spi0_ctrl, &g_spi0_cfg);/* Handle any errors. This function should be defined by the user. */assert(FSP_SUCCESS == err);
}void hal_spi_writebyte( uint8_t byte )
{fsp_err_t err = FSP_SUCCESS;uint8_t buff[1];g_transfer_complete = false;buff[0] = byte;err = R_SCI_SPI_Write(&g_spi0_ctrl, buff, 1, SPI_BIT_WIDTH_8_BITS);assert(FSP_SUCCESS == err);while (false == g_transfer_complete);
}uint8_t hal_spi_readbyte(void)
{fsp_err_t err = FSP_SUCCESS;uint8_t buff[1];g_transfer_complete = false;err = R_SCI_SPI_Read( &g_spi0_ctrl, buff, 1, SPI_BIT_WIDTH_8_BITS);assert(FSP_SUCCESS == err);while (false == g_transfer_complete);return buff[0];
}/* End of this file */
3.3 LCD驱动程序实现
3.3.1 驱动代码
LCD的驱动代码在改文章中已经实现:
使用SPI驱动串行LCD的驱动实现(STM32F4)_spi+lcd-CSDN博客
这里只需修改SPI相关的接口即可,和LCD相关的代码不需要修改,直接引用。
修改和MCU相关的底代码:
1)SPI接口代码。这里需要编写读写数据函数,其函数原型如下:
源代码:
void SPI_WriteByte(uint8_t byte)
{hal_spi_writebyte(byte);
} uint8_t SPI_ReadByte(void)
{return hal_spi_readbyte();
}
2)其他IO库配置
源代码:
#include <stdlib.h>
#include <stdio.h>
#include "bsp_spi.h"
#include "hal_data.h"#define LCD_CS_CLR R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_05, BSP_IO_LEVEL_LOW)
#define LCD_CS_SET R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_05, BSP_IO_LEVEL_HIGH)#define LCD_RST_CLR R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_06, BSP_IO_LEVEL_LOW)
#define LCD_RST_SET R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_06, BSP_IO_LEVEL_HIGH)#define LCD_RS_CLR R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_03, BSP_IO_LEVEL_LOW)
#define LCD_RS_SET R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_03, BSP_IO_LEVEL_HIGH)
3.3.2 测试代码实现
代码第341行:初始化SPI接口
代码第343行:初始化LCD
源代码:
void disp_init(void)
{sci_spi_basic_init();/*You code here*/LCD_Init();LCD_direction(0);LCD_Clear(GREEN);
}
编写一个改变屏幕颜色变化的测试函数
void lcd_test( void )
{uint16_t color_list[6]= {BRRED, BLUE, MAGENTA, RED, YELLOW, GREEN};static int index = 0;LCD_Clear( color_list[index] );index++;R_BSP_SoftwareDelay( 1, BSP_DELAY_UNITS_SECONDS);if( index > 6 )index = 0;
}
4 测试结果
1)改变屏幕的颜色:粉色
2)改变屏幕的颜色:蓝色