-
Notifications
You must be signed in to change notification settings - Fork 0
lcd显示之二:手搓的8080接口,刷图和显示bmp图片
minichao9901 edited this page Feb 24, 2024
·
1 revision
- 手搓8080接口,封装成AXI4,用zynq驱动。
- 关于手搓的8080接口,因为没有fifo和dma,所以速度很慢。
![image](https://private-user-images.githubusercontent.com/61445559/307533997-daaa7529-b84b-429d-ba40-4280e3c9506d.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk0ODg5NDIsIm5iZiI6MTczOTQ4ODY0MiwicGF0aCI6Ii82MTQ0NTU1OS8zMDc1MzM5OTctZGFhYTc1MjktYjg0Yi00MjlkLWJhNDAtNDI4MGUzYzk1MDZkLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjEzVDIzMTcyMlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWIyMDdhNTM4NjRjNjI2NmQ1MjFhM2NmMDNmZmI5NjBlOWRkYWJjZWFkYTlmNjMxOTgzYzI1NTFjYWNjNDU5YzEmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.YqldyzhU5M6pE8GMHzPpxNcQxk35XpOUw1uFfbCywAc)
时钟50MHz可以,时钟100MHz不稳定,跑一会movie就死掉了。
- 这里面有一段自由游走的程序,控制结构很有意思,可以参考。
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xil_io.h"
#include "sleep.h"
#include "ff.h"
#include "xil_cache.h"
#define FMC16_BASE XPAR_MY_FMC16_IP_0_S00_AXI_BASEADDR
#define RED 0xF800
#define ORANGE 0xFC00
#define YELLOW 0xFFE0
#define GREEN 0x07E0
#define CYAN 0x07FF
#define BLUE 0x001F
#define PURPPLE 0xF81F
#define BLACK 0x0000
#define WHITE 0xFFFF
#define GRAY 0xD69A
const u16 colors[] = {
RED,
GREEN,
BLUE,
ORANGE,
YELLOW,
CYAN,
PURPPLE,
BLACK,
WHITE,
GRAY
};
/*************************************************
* basic xfer functions
************************************************/
void xfer_data(u16 data){
Xil_Out32(FMC16_BASE+0x4, data);
Xil_Out32(FMC16_BASE+0x0, 0x01);
while(Xil_In32(FMC16_BASE+0xc)==0x0);
Xil_Out32(FMC16_BASE+0xc, 0x00);
}
void xfer_cmd_pdata(u8 cmd, u16* pdata, u32 length){
Xil_Out32(FMC16_BASE+0x8, length);
xfer_data(cmd);
while(length--){
xfer_data(*pdata++);
}
}
void xfer_cmd_cdata(u8 cmd, u16 data, u32 length){
Xil_Out32(FMC16_BASE+0x8, length);
xfer_data(cmd);
while(length--){
xfer_data(data);
}
}
void xfer_cmd(u8 cmd){
xfer_cmd_pdata(cmd,NULL,0);
}
/*************************************************
* xfer_color functions
************************************************/
void xfer_win(u16 xstart, u16 ystart, u16 width, u16 height)
{
u16 cmd_list[2][5]={
{0x2a, xstart>>8, xstart&0xff, (xstart+width-1)>>8, (xstart+width-1)&0xff},
{0x2b, ystart>>8, ystart&0xff, (ystart+height-1)>>8, (ystart+height-1)&0xff},
};
xfer_cmd_pdata(cmd_list[0][0], (u16*)&(cmd_list[0][1]),4);
xfer_cmd_pdata(cmd_list[1][0], (u16*)&(cmd_list[1][1]),4);
}
void xfer_color(u16 color, u16 width, u16 height){
u32 length=width*height;
xfer_cmd_cdata(0x2C, color, length);
}
void xfer_pic(u16 *pcolor, u16 width, u16 height){
u32 length=width*height;
xfer_cmd_pdata(0x2C, pcolor, length);
}
/*************************************************
* application functions
************************************************/
u8 frame_src[1920*1080*3];
u16 frame_target[320*480];
void load_sd_bmp(u8 *frame, const char *bmp_name);
void convertRGB888toRGB565(
const uint8_t *input,
uint16_t *output,
int inputWidth, int inputHeight,
int startX, int startY,
int outputWidth, int outputHeight
) ;
void dram_eight_colors()
{
for(int i=0; i<sizeof(colors)/sizeof(*colors); i++){
xfer_win(0,0,320,480);
xfer_color(colors[i],320,480);
sleep(1);
}
}
void draw_bmp()
{
load_sd_bmp(frame_src, "aa_320x480.bmp"); //320x480
convertRGB888toRGB565(
frame_src,
frame_target,
320,480,
0,0,
320,480
);
xfer_win(0,0,320,480);
xfer_pic(frame_target,320,480);
sleep(2);
load_sd_bmp(frame_src, "bb_320x480.bmp"); //320x480
convertRGB888toRGB565(
frame_src,
frame_target,
320,480,
0,0,
320,480
);
xfer_win(0,0,320,480);
xfer_pic(frame_target,320,480);
load_sd_bmp(frame_src, "shatan.bmp"); //1920x1080
convertRGB888toRGB565(
frame_src,
frame_target,
1920,1080,
0,0,
320,480
);
xfer_win(0,0,320,480);
xfer_pic(frame_target,320,480);
}
void draw_movie()
{
load_sd_bmp(frame_src, "shatan.bmp"); //1920x1080
int x=300,y=400;
int dir_x=1, dir_y=1;
while(1){
if(dir_x) x+=100; else x-=100;
if(dir_y) y+=50; else y-=50;
if(x+320>1920) {x=1920-320; dir_x=0;} else if(x<0) {x=0; dir_x=1;}
if(y+480>1080) {y=1080-480; dir_y=0;} else if(y<0) {y=0; dir_y=1;}
// xil_printf("x=%d, y=%d\r\n", x,y);
convertRGB888toRGB565(
frame_src,
frame_target,
1920,1080,
x,y,
320,480
);
xfer_win(0,0,320,480);
xfer_pic(frame_target,320,480);
}
}
int main()
{
init_platform();
print("Hello World\n\r");
u16 cmd_list[][2]={
{0x11,0x00},
{0x29,0x00},
{0x36,0x48},
{0x3a,0x05}
};
xfer_cmd_pdata(cmd_list[0][0], NULL, 0);
xfer_cmd_pdata(cmd_list[1][0], NULL, 0);
usleep(120*1000);
xfer_cmd_pdata(cmd_list[2][0], (u16*)&(cmd_list[2][1]), 1);
xfer_cmd_pdata(cmd_list[3][0], (u16*)&(cmd_list[3][1]), 1);
//dram_eight_colors();
draw_bmp();
draw_movie();
cleanup_platform();
return 0;
}
//从SD卡中读取BMP图片
void load_sd_bmp(u8 *frame, const char *bmp_name)
{
static FATFS fatfs;
FIL fil;
u8 bmp_head[54];
UINT bmp_width,bmp_height,bmp_size;
UINT br;
f_mount(&fatfs,"",1);//挂载文件系统
f_open(&fil, bmp_name,FA_READ); //打开文件, 注意是bmp_24bits格式
xil_printf("open bmp\n\r");
f_lseek(&fil,0);//移动文件读写指针到文件开头
f_read(&fil,bmp_head,54,&br);//读取BMP文件头
//BMP图片的分辨率和大小
bmp_width = *(UINT *)(bmp_head + 0x12);
bmp_height = *(UINT *)(bmp_head + 0x16);
bmp_size = *(UINT *)(bmp_head + 0x22);
xil_printf("bmp information:\n\r");
xil_printf(" width = %d,\n\r height = %d,\n\r size = %d bytes \n\r",
bmp_width,bmp_height,bmp_size);
//读出图片,写入DDR
f_read(&fil, frame, bmp_width*bmp_height*3,&br);
xil_printf("br=%d\r\n", br);
for(int i=0; i<20; i++){
xil_printf("%x\r\n", frame[i]);
}
//关闭文件
f_close(&fil);
Xil_DCacheFlush(); //刷新Cache,将数据更新至DDR3中
xil_printf("display bmp\n\r");
}
void convertRGB888toRGB565(const uint8_t *input, uint16_t *output, int inputWidth, int inputHeight, int startX, int startY, int outputWidth, int outputHeight)
{
int i, j;
for (i = 0; i < outputHeight; i++) {
for (j = 0; j < outputWidth; j++) {
// Calculate the index in the RGB888 array
int inputIndex = ((startY + i) * inputWidth + startX + j) * 3;
// Extract RGB888 components
uint8_t b = input[inputIndex];
uint8_t g = input[inputIndex + 1];
uint8_t r = input[inputIndex + 2];
// Convert to RGB565 format
uint16_t rgb565 = ((r>>3) << 11) | ((g>>2) << 5) | (b>>3);
// Store in the output array
output[i * outputWidth + j] = rgb565;
}
}
}
- 可以刷单色图
- 可以显示bmp 888图片,输入可以是任意尺寸,输出可以是任意尺寸。只要输入比输出尺寸大即可。
- 可以实现movie的效果