接口/总线/驱动
测评目的
使用PSoC™ 62 with CAPSENSE™ evaluation kit开发板适配的RTT SPI驱动,做显示测试。
硬件分析
图1 芯片内部系统框图
如图1所示,这个芯片内部的SPI是通过SCB(Serial Communications Block)实现的。并且,所有的外设都是挂在同一总线上。
图2 系统时钟连接框图
如图2所示,SPI(SCB)这些常用外设与内核时钟同一来源。
图3 摘自数据手册中对SPI的描述
可见常见的Motorola和TI标准都是支持的,鉴于本人之前只用过Motorolab标准的SPI,后面的测试也是使用的这种。
SPI的使用
RTT官方已经对这块板子进行了系统与驱动的适配,所以我们可以直接使用RTT的SPI驱动设备框架(RTT赛高!)。
使用的开发环境为RT-Thread Studio ,选择基于开发板创建工程。再是能SPI驱动就可以了。
我手上的SPI驱动模块只有屏幕和W25Q64,屏幕驱动比较简单,所以我选择了这种方式。
使用的模块为1.3寸ST7789屏幕
参考后的程序如下
rt_err_t _spi_lcd_init(void)
{
rt_err_t res = RT_EOK;
Lcd_pin_init();
spi_device_attach(PKG_ST_7789_SPI_BUS_NAME, PKG_ST_7789_SPI_DEVICE_NAME, PKG_ST_7789_CS_PIN);
lcd_dev = (struct rt_spi_device *)rt_device_find(PKG_ST_7789_SPI_DEVICE_NAME);
if (lcd_dev != RT_NULL)
{
struct rt_spi_configuration spi_config;
spi_config.data_width = 8;
spi_config.max_hz = 20 * 1000 * 1000;
spi_config.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB;
rt_spi_configure(lcd_dev, &spi_config);
}
else
{
res = -RT_ERROR;
}
LCD_Init();
return res;
}
INIT_COMPONENT_EXPORT(_spi_lcd_init);
注册设备操作如下
rt_err_t spi_device_attach(const char *bus_name, const char device_name, rt_base_t cs_pin)
{
RT_ASSERT(bus_name != RT_NULL);
RT_ASSERT(device_name != RT_NULL);
rt_err_t result = RT_EOK;
struct rt_spi_device spi_device;
/ attach the device to spi bus /
spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
RT_ASSERT(spi_device != RT_NULL);
result=rt_hw_spi_device_attach(bus_name, device_name, cs_pin);
if (RT_EOK != result)
{
LOG_E("%s attach to %s faild, %dn", device_name, bus_name, result);
}
else
{
LOG_I("%s attach to %s done", device_name, bus_name);
}
return result;
}
使用的引脚和设备名如下
#define PKG_ST_7789_SPI_BUS_NAME "spi0"
#define PKG_ST_7789_SPI_DEVICE_NAME "spi01"
#define PKG_ST_7789_DC_PIN GET_PIN(5, 6)
#define PKG_ST_7789_RES_PIN GET_PIN(5, 7)
#define PKG_ST_7789_BLK_PIN GET_PIN(11, 5)
#define PKG_ST_7789_CS_PIN GET_PIN(0, 5)
如下显示,注册成功
对刷屏进行简单的时间测试
static int lcd_spi_test(void)
{
uint8_t index = 0;
uint16_t time_tick0=0,time_tick1=0;
for (index = 0; index < sizeof(color_array) / sizeof(color_array[0]); index++)
{
time_tick0=rt_tick_get();
LCD_Clear(color_array[index]);
time_tick1=rt_tick_get();
LOG_I("lcd clear color: %#x", color_array[index]);
LOG_I("spend time:%d msn", time_tick1-time_tick0);
DELAY(200);
}
return RT_EOK;
}
MSH_CMD_EXPORT(lcd_spi_test, lcd will fill color => you need init lcd first);
全部0条评论
快来发表一下你的评论吧 !