承接實訓第二天:zigbee無線傳感網實訓---讀、寫檔案操作以及LCD顯示屏顯示顔色(two day)
一、bmp圖檔的顯示
1、記憶體映射(給開發闆的LCD屏配置設定顯存)mmap
#include <sys/mman.h>
void *mmap(void *addr, //映射記憶體的起始位址
size_t length, //映射記憶體大小
int prot, //映射的方式(以什麼方式操作映射記憶體) PROT_EXEC PROT_READ PROT_WRITE PROT_NONE
int flags, //映射記憶體權限(其他程序和線程通路權限) MAP_SHARED MAP_PRIVATE
int fd, //映射裝置的檔案描述符
off_t offset //映射記憶體與LCDD的偏移量,0代表完全重合
);
傳回值:
成功:傳回指向該映射記憶體首位址的指針
失敗:傳回NULL
2、解除映射
int munmap(void *addr, //映射記憶體的位址
size_t length); //映射記憶體的大小
傳回值:
成功:0
失敗:-1
3、記憶體拷貝
#include <string.h> void *memcpy(void *dest, //目标記憶體位址
const void *src, //源内容的位址
size_t n //拷貝的位元組數
);
補充:
永久配置開發闆的ip:
使用vi編輯器更改/etc/profile檔案
在最後一行加上ip配置設定即可(ifconfig eth0 192.168.1.*)
若要屏蔽“物聯網系統”使用“#”注釋掉“cd /IOT”及“./iot &”後面可添加切換到工作路徑“cd /**”
重新開機開發闆“reboot”
-std=c99
練習:
1、通過程式設計實作與在指令視窗的cp(複制)功能相同的程式代碼(copy.c)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
if(argc<3)
{
printf("參數不夠!\n");
exit(0);
}
int fd1 = open(argv[1], O_RDWR);
int fd2 = open(argv[2], O_RDWR|O_CREAT|O_TRUNC, 0666);
if(fd1 == -1 || fd2==-1)
{
perror("打開檔案失敗:\n");
exit(0);
}
char buf[1024];
int ret = 1;
int k=0;
while(ret)
{
//清空緩沖區
memcpy(buf, &k, sizeof(buf));
ret = read(fd1, buf, sizeof(buf));
if(ret>0)
{
write(fd2, buf, ret);
}
if(ret<0)
{
break;
}
}
close(fd1);
close(fd2);
return 0;
}
2、實作将bmp圖檔顯示在開發闆的顯示屏上(show_bmp.c)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
int main(int argc, char **argv)
{
int lcd = open("/dev/fb0", O_RDWR);
if(lcd == -1)
{
perror("打開LCD失敗");
exit(0);
}
// 2, 映射一塊恰當大小的記憶體
char *p = mmap(NULL, // 不指定映射記憶體的位置,讓系統自動選取
800*480*4, // 映射記憶體的大小
PROT_READ | PROT_WRITE, // 以讀、寫模式操作映射記憶體
MAP_SHARED, // 其他線程、程序可以共享通路這塊記憶體
lcd, // LCD檔案描述符
0 // 映射記憶體與LCD的偏移量,0代表完全重合
);
// 3, 準備資料
if(argc < 2)
{
printf("參數不對!\n");
close(lcd);
munmap(p, 800*480*4);
exit(0);
}
int bmp = open(argv[1], O_RDONLY);
if(bmp == -1)
{
perror("打開圖檔失敗!");
close(lcd);
munmap(p, 800*480*4);
exit(0);
}
char bmp_buf[800*480*3];
int ret = read(bmp, bmp_buf, sizeof(bmp_buf));
if(ret <= 0)
{
perror("讀取bmp資料失敗!");
close(lcd);
close(bmp);
munmap(p, 800*480*4);
exit(0);
}
int lcd_buf[800*480];
// 4, 鋪滿整個映射記憶體
for(int i=0; i<800*480; i++)
{
lcd_buf[i]=bmp_buf[i*3] | bmp_buf[i*3+1]<<8 | bmp_buf[i*3+2]<<16;
}
for(int y=0; y<480; y++)
{
for(int x=0; x<800; x++)
{
memcpy(p+4*x+800*4*y, &lcd_buf[x+(479-y)*800], 4);
}
}
// 5, 釋放資源
munmap(p, 800*480*4);
close(lcd);
return 0;
步驟:
(1)編譯程式:
(2)打開tftp
(3)在開發闆上下載下傳編譯程式并執行
(4)效果顯示
3、計算資料類型所占位元組(size.c)
#include <stdio.h>
int main(void)
{
printf("int32_t size: %lu\n", sizeof(int));
printf("char size: %lu\n", sizeof(char));
printf("float size: %lu\n", sizeof(float));
printf("double size: %lu\n", sizeof(double));
return 0;
}
4、兩數相加(sum.c)
#include <stdio.h>
#include <stdlib.h>
int fun(int a, int b)
{
return a+b;
}
int main(int argc, char *argv[])
{
printf("argc = %d\n", argc);
for(int i=0; i<argc; i++)
{
printf("argv[%d] = %s\n", i, argv[i]);
}
int sum = fun(atoi(argv[1]),atoi(argv[2]));
printf("sum = %d\n",sum);
return 0;
}
注:習題2中存在bug,将在第四天解決。
實訓第四天将學習:在LCD屏上顯示JPG圖檔、 觸摸屏、相冊:zigbee無線傳感網實訓---在LCD屏上顯示JPG圖檔、 觸摸屏、相冊(The fourth day)