作者的话
ADI的双核DSP,最早的一颗是Blackfin系列的BF561,这颗DSP我用了很久,比较熟悉,且写过一些给新手的教程。
硬件准备
ADZS-BF561-EZKIT开发板:ADI原厂评估板
AD-ICE20000仿真器:ADI现阶段性能最好的DSP仿真器
产品链接:https://item.taobao.com/item.htm?id=753233120844
软件准备
Visual DSP++5.1.2
CCES2.11.1
硬件环境的搭建
程序实现的功能
通过 BF561 的 PPI 接口,与 TFT 屏连接,实现 TFT 屏的图像显示等。
硬件的实现:
电路设计中,为了实现对 TFT 屏的关断和开启,在 PPI 控制信号线上增加了总线驱动芯片。为了使 PPI 两个设备的通讯数据不受干扰,在 PPI 总线上也增加了总线驱动芯片,用于隔离 PPI 数据总线。在其同步时钟信号线上,有一片 74AHC125,用于为其他 PPI 设备做时钟切换。
TFT 屏简介:
DM-KIT-EXBTFT 中,使用的是型号为 PT035TN01 的 24 位真彩数字屏。其数据传入方式是以 8 位RGB 方式传入的。在传送数据时,每一个点的显示是先传送 8 位 R 信号,再传送 8 位的 G 信号,最后是 B 信号,下一个 8 位信号为下一个点的 R 信号,依次传送下去。因为数据的传送是以 8 位为单位,
分批传送的,因此只需要 8 根 PPI 数据线即可完成。TFT 屏的行场同步信号线可直接连接于 BF561 的PPI 接口的行场同步信号线,用于同步 TFT 屏的数据显示。(有关 PPI 接口的资料清查阅 BF561 处理器相关的资料)
主要引脚定义:(有关 PT035TN01 的其他引脚定义请查阅它的数据手册)
VBL-:TFT 背光电源负极 DC-22+0.3V
VBL+:TFT 背光电源正极 DC-0.3-+32V
HSYNC:行同步信号
VSYNC:场同步信号
DCLK:数据时钟
AVDD:模拟电源(+5V)
VCC:数字电源(+3V)
在 开发板上,提供了 3.3V 和 5V 两个电源满足于 TFT 屏的模拟和数字供电需要,但用于背光的 VBL+和 VBL-则是通过专用的 TFT 背光驱动芯片来实现。调试背光的电压,可控制 TFT 的明暗。
为了使 PPI 接口适应不同的 PPI 外设,需要对其寄存器进行配置,主要配置以下寄存器:
PPI_DELAY:每场 PPI 延时的时钟周期数
PPI_COUNT:每场送的 PPI 数据数
TIMERx_PERIOD:定时器周期寄存器
TIMERx_WIDTH:行定时器脉冲宽度寄存器
TIMERx_CONFIG:行定时器配置寄存器
x 表示定时器编号。
为了能在 TFT 显示时,BF561 能进行其他的工作,还需要将 PPI 的传输方式设置成 DMA 传输模式,主要配置以下寄存器:
DMA0_START_ADDR:DMA 传输数据的起始地址
DMA0_X_COUNT:每一行 DMA 传输的数据次数
DMA0_X_MODIFY:隔几个数据传输,当为 1 时,为连续数据传输
DMA0_Y_COUNT:每一列 DMA 传输的数据次数
DMA0_Y_MODIFY:隔几行数据传输,当为 1 时,为连续数据传输
DMA0_CONFIG:DMA 传输控制器配置
在传输数据前,还需对 PPI 的控制和使能做配置
PPI_CONTROL:PPI 控制寄存器
TIMER_ENABLE:PPI 使能寄存器
BMP 图片格式:
为了能让 TFT 屏显示 BMP 格式的图片,我们来了解一下 BMP 图片的格式。
BMP 图片数据格式有 54 个字节的头信息,其具体格式如下
0000-0001:文件标识,为字母 ASCII 码“BM”。
0002-0005:文件大小。
0006-0009:保留,每字节以“00”填写。
000A-000D:记录图像数据区的起始位置。各字节的信息依次含义为:文件头信息块大小,图像描述信息块的大小,图像颜色表的大小,保留(为 01)。
000E-0011:图像描述信息块的大小,常为 28H。
0012-0015:图像宽度。
0016-0019:图像高度。
001A-001B:图像的 plane 总数(恒为 1)。
001C-001D:记录像素的位数,很重要的数值,图像的颜色数由该值决定。
001E-0021:数据压缩方式(数值位 0:不压缩;1:8 位压缩;2:4 位压缩)。
0022-0025:图像区数据的大小。
0026-0029:水平每米有多少像素,在设备无关位图(.DIB)中,每字节以 00H 填写。
002A-002D:垂直每米有多少像素,在设备无关位图(.DIB)中,每字节以 00H 填写。
002E-0031:此图像所用的颜色数,如 8-位/像素表示为 100h 或者 256。
0032-0035 :如值为 0,指定重要的颜色数。当该域的值等于颜色数时,表示所有颜色都一样重要
颜色表的大小根据所使用的颜色模式而定:2 色图像为 8 字节;16 色图像位 64 字节;256 色图像为 1024 字节。其中,每 4 字节表示一种颜色,依次为 B(蓝色)、G(绿色)、R(红色)、alpha(像素的透明度值,一般不需要)。即首先 4 字节表示颜色号 0 的颜色,接下来表示颜色号 1 的颜色,依此类推。
颜色表接下来为位图文件的图像数据区,在此部分记录着每点像素对应的颜色号,其记录方式也随颜色模式而定,即 2 色图像每点占 1 位(8 位为 1 字节);16 色图像每点占 4 位(半字节);256 色图像每点占 8 位(1 字节);真彩色图像每点占 BF561 位(3 字节)。所以,整个数据区的大小也会随之变化。究其规律而言,可的出如下计算公式:图像数据信息大小=(图像宽度图像高度记录像素的位数)/8。
开发板的屏为 320240 点阵 24 位色屏,它有 22 调暗线,在显示时,最开始的 22 行数据不显示出来,为了更简单的显示出图片,我们用符合屏显示的图片格式即用 windows 的画图板工具制作一张 24 位色,大小为 320262 的 BMP 图片。
用 bin to hex 工具将图片生成 dat 格式的数据:
运行 bin to hex 工具,在弹出窗口提示 Enter input file:后面输入要转换图片的路径,敲回车后会看到提示:Enter output file:,输入路径后,将文件名后缀改为.dat,敲回车后即可生成可以 fill 的.dat文件。如图所示(路径中不允许有中文名,建议设在根目录下)
24 色的数据格式是以 GBR 格式数据进行排列,而且是从左到右,从下到上排列。 TFT 屏是以 RGB 数据格式排列,扫描方式为从左到右,从上到下。为了能正确的显示出图像,需对生成的数据作转换。
PT035TN01 的初始化:
在这一过程中,通过 SPI 的配置来满足 PT035TN01 所需要的时序,通过 SPI 设置 PT035TN01 的寄存器,使 PT035TN01 能够正确输出图像,在 PT035TN01 的寄存器中 bit9 是读写控制位。在这些寄存器中R03 号寄存器非常重要,它决定了 PT035TN01 输出的数据格式,在该模块中要输出的图像是 8 位 RGB 格式的图像,所以配置次寄存器的值为:0xc8。
PT035TN01 寄存器列表如下:
通过以下函数实现 SPI 配置:
Drv_config_to_master()设置 SPI 的波特率、数据传输大小和 SPI 的模式。
Drv_SPI_write()实现对 PT035TN01 寄存器进行设置。
核心代码分析
/* PT035TN01 的初始化*/
void lcd_init(void)
{
*pCtrIner_Flag_OE = 0xff && (~SPI_OE); //SPI_switc 允许
*pCtrOut_Flag_B = 0x07; // 选择 SD_SPISS
Drv_config_to_master();
Drv_config_master_write();
Drv_SPI_enable();
lcd_write_cmd(0x02, 0x11);
lcd_write_cmd(0x03, 0xc8);
lcd_write_cmd(0x04, 0x64);
lcd_write_cmd(0x05, 0x86);
lcd_write_cmd(0x08, 0x08);
lcd_write_cmd(0x09, 0x85);
lcd_write_cmd(0x0a, 0x88);
lcd_write_cmd(0x0b, 0x88);
lcd_write_cmd(0x0c, 0x18);
lcd_write_cmd(0x0d, 0x10);
}
void BMP2rgb24(void) //将 BMP 数据格式转换成 RGB 格式
{
int i,j;
int a,b;
for(i=0;i<262;i++) //将线性数据转换成 2 维数据,空出 54 字
{
for(j=0;j<960;j++)
{
TempBuffer_img[i][j] = TempBuffer[i960+j+54];
}
}
for(i=0;i<262;i++) //将 GBR 调整成 RGB
{
for(j=0;j<320;j++)
{
a = TempBuffer_img[i][j3];
b = TempBuffer_img[i][j3+2];
TempBuffer_img[i][j3] = b;
TempBuffer_img[i][j*3+2] = a;
}
}
for(i=0;i<262;i++) //数据扫描方式调整
{
for(j=0;j<960;j++)
{
DisplayBuffer[i][j] = TempBuffer_img[261-i][j];
}
}
}
程序运行结果
运行程序后,在 TFT 屏上可看到图片。