一、评测介绍
1. 前言
第二篇推文啦,这次我来做一下Nuvoton M487 的USCI外设的评测,其实这是第一次接触USCI外设,常用的MCU是没有这个外设的,不过RT-Thread 和 新唐的驱动都做的比较完善。
2. 评测介绍
之前有小伙伴已经使用Uuart和Ui2c 我就来评测一下Uspi吧。使用的外设是 ST7735S的 1.8寸TFT显示屏,分辨率是128*160的。
这个屏幕在设计的时候没有用SPI主机的读功能,只有MOSI,所以下面我在使用SPI的时候就不用啦,屏幕接口如下。
二、 评测内容
1. USCI介绍
USCI是通用串行控制接口,它相当于一个串口设备的扩展,可以扩展出Uart、I2C、SPI这三个接口来。
新唐的这块 M4780 MCU 具有两个USCI外设,分别是USCI1和USCI2。如果你需要使用USCI外设,可以查看DataSheet 1575页,可以将USCI映射成UART、SPI、I2C,不过一个USCI外设只能映射一个设备。
我使用的USPI设备映射如下,手册1619页。
2. USCI配置
这是USCI输入信号的配置,我使用的是SPI接口,而且这个屏幕没有触摸功能,商家在设计的时候只留了MOSI接口,所以不如要输入,只需要输出。
USCIx_CLK 映射了 SPI_CLK
USCIx_DAT0映射了SPI_MOSI_0
SPI
通信除了这两个接口,还有上面提到的MISO,没有读所以就没有使用啦,然后SPI_SS引脚就是CS引脚,我直接使用了软件去触发CS没有用硬件配置。
3. USCI接口查询
因为 我在RT-Thread Set
ting 中发现USCI0是开启的而且映射了外设,就选择了USCI1来作为设备。
我选择映射的引脚是 PB.1和PB.2,查询原理图时钟和数据输出引脚分别是
开发板的Arduino接口的A5和D0,直接使用即可。
4. 打开USCI设备
打开RT-Thread Setting,使用USCI1并映射为USPI1,然后保存即可。
5. USCI初始化
void nutool_pincfg_init_usci1(void)
{
SYS->GPB_MFPL &= ~( SYS_GPB_MFPL_PB1MFP_Msk|SYS_GPB_MFPL_PB2MFP_Msk);
SYS->GPB_MFPL |= (SYS_GPB_MFPL_PB1MFP_USCI1_CLK | SYS_GPB_MFPL_PB2MFP_USCI1_DAT0);
return ;
}
void nutool_pincfg_deinit_usci1(void)
{
SYS->GPB_MFPL &= ~( SYS_GPB_MFPL_PB1MFP_Msk|SYS_GPB_MFPL_PB2MFP_Msk);
return ;
}
在引脚配置中 创建 API 打开和关闭 usci1 我要使用的PB.1和PB.2引脚的时钟,并在 下面的
void nutool_pincfg_init(void)
void nutool_pincfg_deinit(void)
函数中调用
6. 设备设置
这个开发板默认打开了好多的外设和设备,作为强迫症的我特别受不了。。
可以在rtconfig.h中将不用的设备和驱动注释掉。
7. USPI挂载
我的 ST7735S驱动一共有4个文件,st7735_spi 是SPI设备的操作,
st7735_lcd.c 是 LCD屏幕的操作。
首先将st7735挂载到 uspi bus上
st7735_spi.c
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-04-13 Administrator the first version
*/
#include "rtthread.h"
#include "rtdevice.h"
#include "NuMicro.h"
#include
//PB1. CLK
//PB2. DAT
//PA5. RST
//PA4. DC
//PA3. CS
//PA0. BK
/* 这个文件是st7735的SPI配置文件*/
#define LOG_TAG "st7735_spi.c" // 该模块对应的标签。不定义时,默认:NO_TAG
#define LOG_LVL LOG_LVL_DBG // 该模块对应的日志输出级别。不定义时,默认:调试级别
#include
//创建SPI设备句柄
struct rt_spi_device spi_dev_st7735;
struct nu_hw_spi_cs
{
rt_uint32_t pin;
};
static struct nu_hw_spi_cs spi_cs;
int st7735_spi_device_init(void)
{
rt_err_t res;
struct rt_spi_configuration cfg = {0};
spi_cs.pin = LCD_CS_PIN;
rt_pin_mode(LCD_CS_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(LCD_RESET_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(LCD_DC_PIN, PIN_MODE_OUTPUT);
//挂载设备
res = rt_spi_bus_attach_device(&spi_dev_st7735, ST7735_SPI_DEVICE_NAME, USPI_BUS_NAME, (void*)&spi_cs);
if (res != RT_EOK)
{
LOG_E("st7735 Failed to attach device %sn", ST7735_SPI_DEVICE_NAME);
return RT_ERROR;
}
else
{
LOG_E("st7735 spi reset is ok n");
spi_dev_st7735.bus->owner = &spi_dev_st7735;
//Set device SPI Mode
cfg.data_width = 8;
cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB ;
//这里频率会有警告
cfg.max_hz = 4*1000*1000; /* 4M */
rt_spi_configure(&spi_dev_st7735, &cfg);
return RT_EOK;
}
}
//加入自动初始化
INIT_DEVICE_EXPORT(st7735_spi_device_init);
st7735_spi.h
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-04-13 Administrator the first version
*/
#ifndef APPLICATIONS_ST7735_SPI_H_
#define APPLICATIONS_ST7735_SPI_H_
#include "rtthread.h"
#include "rtdevice.h"
#include "NuMicro.h"
#include
//定义SPI总线
#define USPI_BUS_NAME "uspi1"
//挂载SPI总线设备
#define ST7735_SPI_DEVICE_NAME "uspi10"
extern struct rt_spi_device spi_dev_st7735;
//PB1. CLK A5
//PB2. DAT D0
//PA5. RST D8
//PA4. DC D9
//PA3. CS D10
//定义CS,RST,DC三个引脚
#define LCD_RESET_PIN NU_GET_PININDEX(NU_PA, 5)
#define LCD_DC_PIN NU_GET_PININDEX(NU_PA, 4)
#define LCD_CS_PIN NU_GET_PININDEX(NU_PA, 3)
int st7735_spi_device_init(void);
#endif /* APPLICATIONS_ST7735_SPI_H_ */
这时候总线和设备都已经挂载成功啦。
8. 驱动实现
挂载成功后,使用RT-Thread 的SPI接口实现屏幕驱动即可,屏幕点亮的效果如图。
三、评测中的问题
1. USCI的SPI频率
我在评测过程中将SPI的最高频率设置为5MHZ,发现会有警告,提示最高频率为4.8MHZ,按道理说不应该是这么低的频率,应该是我把哪个没有设置好,如果有大佬知道麻烦 戳我一下呦。
四、 总结
USCI设备可以映射成UART、I2C、SPI这三种外设,我好奇为什么不多加组外设而是做成可以自由支配的呢。
RT-Thread 和 新唐对于这款MCU的支持做的非常棒,开发起来也非常方便,期待下次的评测呦。