一、C语言调用外部函数
1、使用extern关键字来声明
lcd.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int lcd_show_color(int color)
{
//1)打开液晶屏
int fd_lcd;
fd_lcd = open("/dev/fb0", O_RDWR)
if(fd_lcd == -1)
{
perror(“open lcd”);
return -1;
}
//2)向液晶屏写入数据
int lcd_buf[800480];
for(int i=0;i<800480;i++)
lcd_buf[i]=color;//green
write(fd_lcd,lcd_buf,sizeof(lcd_buf));//8004804
//3)关闭液晶屏
close(fd_lcd)
return 0;
}
main.c
#include <stdio.h>
#include <stdlib.h>
#define RED 0x00FF0000
#define GREEN 0x0000FF00
#define BLUE 0x000000FF
extern int lcd_show_color(int color);
int main(void)
{
while(1)
{
lcd_show_color(RED);
sleep(1);
lcd_show_color(GREEN);
sleep(1);
lcd_show_color(BLUE);
sleep(1);
}
return 0;
}
2.使用头文件
注意两个问题:
1)头文件的包含形式
#include <stdio.h>
#include <stdlib.h>
#include “lcd.h”
< >和" "的区别是什么?
问题:Linux系统默认的头文件的路径在哪里? /usr/include/stdio.h
2)头文件条件编译的作用
#ifndef LCD_H
#define LCD_H 1
#define RED 0x00FF0000
#define GREEN 0x0000FF00
#define BLUE 0x000000FF
int lcd_show_color(int color);
#endif /!LCD_H/
防止头文件重复包含而引起重定义。
二、多个源文件的程序如何编译:
一个源文件的程序:
gcc test.c -o test
多个源文件的编译:
gcc main.c lcd.c -o test
使用Makefile
main:main.o lcd.o
arm-linux-gcc main.o lcd.o -o main
main.o:main.c
arm-linux-gcc main.c -o main.o -c
lcd.o:lcd.c
arm-linux-gcc lcd.c -o lcd.o -c
编译程序:
#make
========================================================================
三、图片的显示
bmp图片
是RGB的位图,是没有经过压缩的,可以直接处理并显示。
jpg图片
是使用jpeg算法进行压缩的图片,需要解压再显示。
bmp图片的显示:
图片的大小:800480像素点,每个像素点是24bits的数据,24bits的数据分别是RGB=8:8:8
bmp图片的大小由两部分组成的:
1)文件的头:54B,是bmp文件的信息:分辨率、色位、创建时间、…
2)颜色数据:800480*3B=1152000B
BMP图片的显示流程
1、打开bmp文件
例:
int fd_bmp;
fd_bmp = open("./pic/test.bmp", O_RDWR)
if(fd_bmp == -1)
{
perror(“open bmp”);
return -1;
}
2、移动文件指针54B
例:
lseek(fd_bmp,54,SEEK_SET);
3、读取图片的RGB数据
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
例:
char bmp_buf[8004803];//RGB
read(fd_bmp,bmp_buf,sizeof(bmp_buf));
4、关闭bmp文件
例:
close(fd_bmp);
5、将bmp图片的RGB转换成LCD的ARGB
在bmp图片中,一个像素点是3个字节的数据(RGB);而在显存(LCD)上,一个像素点是4个字节(ARGB)
将char bmp_buf[8004803]的数据转换到int lcd_buf[800*480]中。
第0个像素点:
lcd_buf[0]<----bmp_buf[2](R)、bmp_buf[1](G)、bmp_buf[0](B)
lcd_buf[0] = (0x00<<24)+(bmp_buf[2]<<16) + (bmp_buf[1]<<8) + (bmp+buf[0]<<0)
第1个像素点:
lcd_buf[1] = (0x00<<24)+(bmp_buf[5]<<16) + (bmp_buf[4]<<8) + (bmp+buf[3]<<0)
第2个像素点:
lcd_buf[1] = (0x00<<24)+(bmp_buf[8]<<16) + (bmp_buf[7]<<8) + (bmp+buf[6]<<0)
第n个像素点:
lcd_buf[1] = (0x00<<24)+(bmp_buf[3n+2]<<16) + (bmp_buf[3n+1]<<8) + (bmp+buf[3*n]<<0)
使用for实现。
注意:
显示的图片是上下翻转的,需要正过来。
6、打开液晶屏
例:
int fd_lcd;
fd_lcd = open("/dev/fb0", O_RDWR)
if(fd_lcd == -1)
{
perror(“open lcd”);
return -1;
}
7、将显存数据写入液晶屏
例:
int lcd_buf[800*480];
write(fd_lcd, lcd_buf, sizeof(lcd_buf));
8、关闭液晶屏
例:
close(fd_lcd);
实验1
利用project实现循环显示单色。
实验2
将液晶屏显示图片封装成一个函数lcd_show_bmp(char * bmp_name),加入到lcd.c,在project中编译。
修改main.c实现多张图片循环显示。
提示:
将文件从PC机下载到开发板的方法
1)使用串口线+secureCRT,使用rx命令
比较方便,但是下载速度慢。
2)使用U盘
注意:U盘使用usb2.0,U盘的文件系统格式是fat32格式。
(1)加入图片放入U盘
U盘/pic/test1.bmp
U盘/pic/test2.bmp
U盘/pic/test3.bmp
(2)将U盘插到试验箱的USB口
Linux系统会自动的将U盘挂在到/mnt/udisk/目录下
(3)拷贝U盘中的图片
#cd /mnt/udisk/
#ls
会看到pic文件夹
#cp pic /test
在将应用程序下载到/test目录下。
3)使用网络TFTP协议下载。
============================================================
图片翻转
int lcd_buf[800480];
int lcd_new[800480];
arm-linux-gcc test.c -o test -std=c99
for(int j=0;i<480;i++)
for(int i=0;i<800;i++)
lcd_new[800*(479-j)+i] = lcd_buf[800*j+i];
#include <stdio.h>
#include <stdlib.h>
#include "lcd.h"
int main(void)
{
while(1)
{
lcd_show_color(RED);
sleep(1);
lcd_show_color(GREEN);
sleep(1);
lcd_show_color(BLUE);
sleep(1);
}
return 0;
}
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int lcd_show_color(int color)
{
//1)打开液晶屏
int fd_lcd;
fd_lcd = open("/dev/fb0", O_RDWR)
if(fd_lcd == -1)
{
perror("open lcd");
return -1;
}
//2)向液晶屏写入数据
int lcd_buf[800*480];
for(int i=0;i<800*480;i++)
lcd_buf[i]=color;//green
write(fd_lcd,lcd_buf,sizeof(lcd_buf));//800*480*4
//3)关闭液晶屏
close(fd_lcd);
return 0;
}