本帖最后由 jinglixixi 于 2025-7-7 08:39 编辑
#申请原创#
@21小跑堂
CH585是沁恒出品的一款集成了 BLE 无线通讯和高速 USB 及 NFC 的 RISC-V MCU 微控制器。并在片上集成了 2Mbps 低功耗蓝牙 BLE 通讯模块、USB 全速控制器及收发器、USB 高速控制器及收发器(480Mbps)、NFC 近场通信无线接口、段式 LCD 驱动模块、LED 点阵屏接口、2 个 SPI、4 个串口、14 路 ADC、触摸按键检测模块等丰富的外设资源。
其内核框架如图1所示,与以前产品不同的是减少了RTC的介绍。
图1 内核框架
开发板的外观如图2和图3所示,可见它采用的是单面器件布局。
图2 开发板正面
图3 开发板背面
为了便于显示,就为其配置了一个SPI接口的2.2’ TFT显示屏,其分辨率为240*320像素点。
在显示驱动方面,有2种驱动可供选择,一种是采用模拟的方式,另一种则是以硬件的方式。
对于模拟的方式,其好处就是易于实现,不受硬件在引脚方面的制约;而对于硬件方式,其好处就是处理速度快,可以充分发挥SPI接口的作用。此外,相对其他的开发板,似乎在CH585上也更易于实现,通过后面的对比会加深大家对这种想法的认识。
1. 模拟方式
要以模拟的方式来实现TFT显示屏的驱动,先要定义引脚的连接关系并对所用引脚加以配置。
这里为显示屏所建立的连接关系为:
CS -----PA0
RST ----PA1
DC ----PA2
MOSI-----PA3
SCK -----PA5
其引脚配置的函数为:
void TFT_CONFIG()
{
GPIOA_ModeCfg( GPIO_Pin_4, GPIO_ModeOut_PP_5mA );
GPIOA_ModeCfg( GPIO_Pin_0, GPIO_ModeOut_PP_5mA );
GPIOA_ModeCfg( GPIO_Pin_1, GPIO_ModeOut_PP_5mA );
GPIOA_ModeCfg( GPIO_Pin_2, GPIO_ModeOut_PP_5mA );
GPIOA_ModeCfg( GPIO_Pin_3, GPIO_ModeOut_PP_5mA );
GPIOA_ModeCfg( GPIO_Pin_5 , GPIO_ModeOut_PP_5mA );
}
实现引脚输出高低电平的语句定义为:
#define LCD_CS_High() GPIOA_SetBits(GPIO_Pin_0)
#define LCD_CS_Low() GPIOA_ResetBits(GPIO_Pin_0)
#define LCD_REST_High() GPIOA_SetBits(GPIO_Pin_1)
#define LCD_REST_Low() GPIOA_ResetBits(GPIO_Pin_1)
#define LCD_DC_High() GPIOA_SetBits(GPIO_Pin_2)
#define LCD_DC_Low() GPIOA_ResetBits(GPIO_Pin_2)
#define LCD_SDI_High() GPIOA_SetBits(GPIO_Pin_3)
#define LCD_SDI_Low() GPIOA_ResetBits(GPIO_Pin_3)
#define LCD_SCK_High() GPIOA_SetBits(GPIO_Pin_5)
#define LCD_SCK_Low() GPIOA_ResetBits(GPIO_Pin_5)
在模拟方式下,最为关键的是模拟SPI方式进行字节数据的方式,其函数内容为:
void LCD_Writ_Bus(unsigned char com)
{
unsigned char uci;
for(uci=0;uci<8;uci++)
{
if(com & 0x80)
{
LCD_SDI_High();
}
else
{
LCD_SDI_Low();
}
com = com << 1;
DelayUs(1);
LCD_SCK_Low();
LCD_SCK_High();
}
}
其他一些支持显示驱动的辅助函数有:
单字节数据发送函数LCD_WR_DATA8(char da)
双字节数据发送函数LCD_WR_DATA(int da)
寄存器发送函数LCD_WR_REG(char da)
向寄存器发送双字节数据函数LCD_WR_REG_DATA(int reg,int da)
对显示屏的初始化函数为:void TFT_Init(void)
{
LCD_REST_Low();
DelayMs(20);
LCD_REST_High();
DelayMs(20);
LCD_CS_Low();
LCD_WR_REG(0xCB);
LCD_WR_DATA8(0x39);
LCD_WR_DATA8(0x2C);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x34);
LCD_WR_DATA8(0x02);
LCD_WR_REG(0xCF);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0XC1);
LCD_WR_DATA8(0X30);
LCD_WR_REG(0xE8);
LCD_WR_DATA8(0x85);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x78);
LCD_WR_REG(0xEA);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x00);
LCD_WR_REG(0xED);
LCD_WR_DATA8(0x64);
LCD_WR_DATA8(0x03);
LCD_WR_DATA8(0X12);
LCD_WR_DATA8(0X81);
LCD_WR_REG(0xF7);
LCD_WR_DATA8(0x20);
LCD_WR_REG(0xC0);
LCD_WR_DATA8(0x23);
LCD_WR_REG(0xC1);
LCD_WR_DATA8(0x10);
LCD_WR_REG(0xC5);
LCD_WR_DATA8(0x3e);
LCD_WR_DATA8(0x28);
LCD_WR_REG(0xC7);
LCD_WR_DATA8(0x86);
LCD_WR_REG(0x36);
LCD_WR_DATA8(0xE8);
LCD_WR_REG(0x3A);
LCD_WR_DATA8(0x55);
LCD_WR_REG(0xB1);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x18);
LCD_WR_REG(0xB6);
LCD_WR_DATA8(0x08);
LCD_WR_DATA8(0x82);
LCD_WR_DATA8(0x27);
LCD_WR_REG(0xF2);
LCD_WR_DATA8(0x00);
LCD_WR_REG(0x26);
LCD_WR_DATA8(0x01);
LCD_WR_REG(0xE0);
LCD_WR_DATA8(0x0F);
LCD_WR_DATA8(0x31);
LCD_WR_DATA8(0x2B);
LCD_WR_DATA8(0x0C);
LCD_WR_DATA8(0x0E);
LCD_WR_DATA8(0x08);
LCD_WR_DATA8(0x4E);
LCD_WR_DATA8(0xF1);
LCD_WR_DATA8(0x37);
LCD_WR_DATA8(0x07);
LCD_WR_DATA8(0x10);
LCD_WR_DATA8(0x03);
LCD_WR_DATA8(0x0E);
LCD_WR_DATA8(0x09);
LCD_WR_DATA8(0x00);
LCD_WR_REG(0XE1);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x0E);
LCD_WR_DATA8(0x14);
LCD_WR_DATA8(0x03);
LCD_WR_DATA8(0x11);
LCD_WR_DATA8(0x07);
LCD_WR_DATA8(0x31);
LCD_WR_DATA8(0xC1);
LCD_WR_DATA8(0x48);
LCD_WR_DATA8(0x08);
LCD_WR_DATA8(0x0F);
LCD_WR_DATA8(0x0C);
LCD_WR_DATA8(0x31);
LCD_WR_DATA8(0x36);
LCD_WR_DATA8(0x0F);
LCD_WR_REG(0x11);
DelayMs(120);
LCD_WR_REG(0x29);
LCD_WR_REG(0x2c);
}
实现色彩清屏处理的函数为:
void LCD_Clear(unsigned int Color)
{
char VH,VL;
unsigned int i,j;
VH=Color>>8;
VL=Color;
Address_set(0,0,LCD_H-1,LCD_W-1);
for(i=0;i<LCD_H;i++)
{
for (j=0;j<LCD_W;j++)
{
LCD_WR_DATA8(VH);
LCD_WR_DATA8(VL);
}
}
}
有了以上函数的支持,进行驱动测试的主程序为:
int main()
{
uint8_t i;
HSECFG_Capacitance(HSECap_18p);
SetSysClock(CLK_SOURCE_HSE_PLL_62_4MHz);
TFT_CONFIG();
DelayMs(1);
TFT_Init();
LCD_Clear(RED);
while(1);
}
经编译和选择,其测试效果如图4所示,说明驱动有效。
图4 驱动测试
2. 硬件方式
有了前面模拟驱动的基础,下面再将其改为硬件方式的驱动。
SPI 是一种全双工串行接口,总线上连接有一个主机和若干从机,同一时刻,仅有一对主从在通讯。通常 SPI 接口由 4 个引脚组成:SPI 片选引脚 SCS、SPI 时钟引脚 SCK、SPI 串行数据引脚 MISO(主机输入/从机输出引脚)和 SPI 串行数据引脚 MOSI(主机输出/从机输入引脚)。 CH585 芯片提供 2 个 SPI 接口(SPI0 和 SPI1)其特性如下: SPI0 支持主机模式(Master)和从机模式(Slave),SPI1 只支持主机模式(Master) 兼容串行外设接口(SPI)规范 支持模式 0 和模式 3 数据传输方式 8 位数据传输方式,数据位序可选:字节低位在前或者高位在前 时钟频率最高可达系统主频 Fsys 的一半 8 字节 FIFO SPI0 从机模式支持首字节为命令模式或数据流模式 SPI0 支持 DMA,数据传输效率更高 SPI 支持模式 0 和模式 3 两种传输格式,通过设置 R8_SPIx_CTRL_MOD 的 RB_SPI_MST_SCK_MOD 进 行选择。总是在 SCK 上升沿采样串行数据输入,在下降沿输出串行数据。
SPI 的工作时序如图5所示: 图5 工作时序
替代模拟方式所选取的是SPI0,其所用的引脚如图6所示。
图6 所用接口
因此TFT显示屏新的引脚连接关系为:
CS -----PA12
SCK -----PA13
MOSI-----PA14
RST ----PA1
DC ----PA2
也就是说在硬件驱动方式下,只需所用2个辅助引脚进行配合,其他则是通过SPI接口来完成。
辅助引脚的配置函数为:
void TFT_CONFIG()
{
GPIOA_ModeCfg( GPIO_Pin_4, GPIO_ModeOut_PP_5mA );
GPIOA_ModeCfg( GPIO_Pin_1, GPIO_ModeOut_PP_5mA );
GPIOA_ModeCfg( GPIO_Pin_2, GPIO_ModeOut_PP_5mA );
}
配置SPI0的语句为:
GPIOA_ModeCfg(GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14, GPIO_ModeOut_PP_5mA);
SPI0_MasterDefInit();
在此基础上,新的SPI模式下方式字节数据的函数变为:
void LCD_Writ_Bus(unsigned char com)
{
GPIOA_ResetBits(GPIO_Pin_12);
SPI0_MasterSendByte(com);
}
这样就完成了模拟方式向硬件方式的转换,看上去是不是非常简单!
这里引用到2个函数,其内容为:
void SPI0_MasterDefInit(void)
{
R8_SPI0_CLOCK_DIV = 4; // 主频时钟4分频
R8_SPI0_CTRL_MOD = RB_SPI_ALL_CLEAR;
R8_SPI0_CTRL_MOD = RB_SPI_MOSI_OE | RB_SPI_SCK_OE;
R8_SPI0_CTRL_CFG |= RB_SPI_AUTO_IF;
R8_SPI0_CTRL_CFG &= ~RB_SPI_DMA_ENABLE; // 不启动DMA方式
}
void SPI0_MasterSendByte(uint8_t d)
{
R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR;
R16_SPI0_TOTAL_CNT = 1; // 设置要发送的数据长度
R8_SPI0_FIFO = d;
while(!(R8_SPI0_INT_FLAG & RB_SPI_FREE));
}
在确保硬件驱动有效的情况下,通过添加字符及字符串显示函数,实现显示测试的主程序为:
int main()
{
uint8_t i;
HSECFG_Capacitance(HSECap_18p);
SetSysClock(CLK_SOURCE_HSE_PLL_62_4MHz);
TFT_CONFIG();
GPIOA_SetBits(GPIO_Pin_12);
GPIOA_ModeCfg(GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14, GPIO_ModeOut_PP_5mA);
SPI0_MasterDefInit();
DelayMs(1);
TFT_Init();
LCD_Clear(RED);
BACK_COLOR=RED;
POINT_COLOR=WHITE;
LCD_ShowChar(10,10,'V',0);
LCD_ShowString(10,30,"CH585");
while(1);
}
经编译和下载,其测试效果如图7所示,说明硬件驱动是成功的,且明显地加快了显示的速度。
图7 测试效果
通过对模拟和硬件2种驱动方式的对比,可以发现模拟方式向硬件方式的转换是十分方便的,此外也发现CH585在SPI的使用方面也有了新的变化,且更加易于使用啦!
|