粤嵌第一周

写在开始

本周使用的开发板是s6818,使用c语言编程。

第一天作业:测试在windows端以及linux段的各个数据类型大小

 

 如图所示。主要的知识点是sizeof()函数,可以获取数据类型的字节大小。

1byte = 8 bits。

题外话:面对这种数据类型不同的情况,假如需要移植系统,使用typedef;

typedef  double   int8_t;    //给double取别名

typedef  long       int8_t;   //给long取别名

 作出声明之后,就可进行移植了,不用困扰字节数不对的情况。

第二天:如何在一个有hello world文本文件前面插入hi

思路:用字符串把源文本存起来,然后写入hi,最后用printf把字符串内容打印出来

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include<stdlib.h>

int main()
 {
    FILE *src_file, *dest_file;
    char ch;

    // 打开原始文件和目标文件
    
    int hello = open("hello.txt",O_RDWR|O_CREAT, 0777);
    int  hi   = open("hi.txt",   O_RDWR|O_CREAT, 0777);

    const char *content = "hello world";
    
    if(write(hello, content, 12) == -1)
    {
        printf("输入hello world失败");
    }
    
    src_file  = fopen("hello.txt" ,  "r");
    dest_file = fopen("output.txt", "w");
    
    // 写入需要添加的内容
    fprintf(dest_file, "hi\t");

    // 读取原始文件中的内容,并将其写入目标文件中
    while ((ch = fgetc(src_file)) != EOF) //如果成功如果读取失败或到达文件结尾,返回EOF。while循环,加入未到达文件结尾,就一直输出字符到目标文件
    {
        fputc(ch, dest_file);//ch是要写入的字符
    }

    // 关闭文件
    fclose(src_file);
    fclose(dest_file);

    return 0;
}

我这里是放到了另外一个文件,其实用字符串存起来更好。

open函数:

C语言中的open函数用于打开一个文件,并返回一个文件描述符(file descriptor),以便后续的读写操作。

函数原型如下:

```c
#include <fcntl.h>

int open(const char *pathname, int flags, mode_t mode);
```

参数说明:

- `pathname`:要打开的文件路径名。
- `flags`:打开文件的方式和权限,可以是以下几个常量的按位或(`|`)组合:
  - `O_RDONLY`:只读方式打开文件。
  - `O_WRONLY`:只写方式打开文件。
  - `O_RDWR`:读写方式打开文件。
  - `O_CREAT`:如果文件不存在,则创建文件。
  - `O_EXCL`:与`O_CREAT`一起使用,如果文件已经存在,则返回错误。
  - `O_TRUNC`:如果文件存在,且以写方式打开,则清空文件内容。
  - `O_APPEND`:以追加方式打开文件。
- `mode`:文件的权限,只有在创建文件时才有意义,可以是以下几个常量的按位或(`|`)组合:
  - `S_IRUSR`:用户可读权限。
  - `S_IWUSR`:用户可写权限。
  - `S_IXUSR`:用户可执行权限。
  - `S_IRGRP`:组可读权限。
  - `S_IWGRP`:组可写权限。
  - `S_IXGRP`:组可执行权限。
  - `S_IROTH`:其他人可读权限。
  - `S_IWOTH`:其他人可写权限。
  - `S_IXOTH`:其他人可执行权限。

函数返回值:

- 如果成功,返回文件描述符(非负整数)。
- 如果失败,返回-1,并设置errno变量表示错误原因。

write函数:

C语言中的write函数是用来向文件描述符(文件、标准输入输出、网络套接字等)写入数据的函数。它的函数原型如下:

```
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
```

其中,参数fd是文件描述符,buf是要写入的数据的指针,count是要写入的数据的字节数。

函数返回值是写入的字节数,如果出现错误则返回-1

第三天:

    作业:1:利用映射的方式画一个彩虹

    作业:2:画一个4个格子形成的整个格子

    作业:3:在屏幕中间做一个进度条(选做)

作业1

#include"stdio.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
/*
    作业:1:利用映射的方式画一个彩虹
    作业:2:画一个4个格子形成的整个格子
    作业:3:在屏幕中间做一个进度条(选做)
i*/
 
#define RED      0x00FF0000
#define ORIANGE  0x00FFA500
#define YELLOW   0x00FFFF00
#define GREEN    0x00008000
#define CYAN     0x0000FFFF
#define BLUE     0x000000FF
#define PURPLE   0x00800080


int main()
{
    int x   = 0; 
    int y   = 0;
    int i = 0;

    //1打开文件
    int fd_lcd = open("./dev/fb0",O_RDWR);
    if(-1 == fd_lcd)
    {
        printf("打开文件失败\n");
        return 0;
    }
    printf("打开文件成功\n");


    //准备数据(用映射内存的方式)
    int buf[800 * 480];

    int *lcd_mp = mmap(NULL, 800*480*4, PROT_READ|PROT_WRITE, MAP_SHARED, fd_lcd, 0);
   
    int color[] = {RED, ORIANGE, YELLOW, GREEN, CYAN, BLUE, PURPLE};
    
    //作业:1:利用映射的方式画一个彩虹
    for ( i = 0; i < 800 * 480; i++)
    {   
        //拆开
        x = i % 800;//x轴
        y = i / 800;//y轴

        lcd_mp [ i ] = color[ y / 68 ];
    }
    
    close(fd_lcd);

    return 0;
}

作业二

#include"stdio.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
 #include <sys/mman.h>
/*
    作业:1:利用映射的方式画一个彩虹
    作业:2:画一个4个格子形成的整个格子
    作业:3:在屏幕中间做一个进度条(选做)
*/

#define RED      0x00FF0000
#define ORIANGE  0x00FFA500
#define YELLOW   0x00FFFF00
#define GREEN    0x00008000
#define CYAN     0x0000FFFF
#define BLUE     0x000000FF
#define PURPLE   0x00800080



int main()
{ 
    int x = 0;
    int y = 0;
    int i = 0;

    //1打开文件
    int fd_lcd = open("./dev/fb0",O_RDWR);
    if(-1 == fd_lcd)
    {
        printf("打开文件失败\n");
        return 0;
    }
    printf("打开文件成功\n");

    //准备数据(用映射内存的方式)
    int buf[800*240];
    int color[] = {RED, ORIANGE, YELLOW, GREEN, CYAN, BLUE, PURPLE};
    int *lcd_mp = mmap(NULL, 800*480*4, PROT_READ|PROT_WRITE, MAP_SHARED, fd_lcd, 0);

    for ( i = 0; i < 800 * 480; i++)
    {
        x = i % 800;
        y = i / 800;
        if (x < 400 && y < 240)
        {
            lcd_mp  [ i ] = color[0];
        }

    }
    
    
    close(fd_lcd);

    return 0;
}

 mmap函数:

mmap函数是一种内存映射文件的方法,可以将一个文件或者设备映射到进程的地址空间中,使得进程可以像访问内存一样访问文件或设备。

mmap函数的用法如下:

```c
#include <sys/mman.h>

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
```

参数说明:

- addr:映射区的开始地址,通常设置为0,表示由系统自动分配。
- length:映射区的长度,单位是字节。
- prot:映射区的保护方式,可以是以下几种取值的组合:
  - PROT_READ:可读
  - PROT_WRITE:可写
  - PROT_EXEC:可执行
  - PROT_NONE:不可访问
- flags:映射区的标志,可以是以下几种取值的组合:
  - MAP_SHARED:共享映射
  - MAP_PRIVATE:私有映射
  - MAP_ANONYMOUS:匿名映射
  - MAP_FIXED:强制将映射区放在指定地址处
- fd:要映射的文件描述符,如果是匿名映射,则设置为-1。
- offset:文件映射的偏移量,通常设置为0。

mmap函数返回映射区的起始地址,如果出错则返回MAP_FAILED。

使用mmap函数需要注意以下几点:

- 映射区的长度必须是页大小的整数倍。
- 映射区的起始地址必须是页大小的整数倍。
- 映射区的保护方式和标志必须是合法的组合。
- 映射区的长度不能超过进程的地址空间大小。
- 映射区的起始地址不能与其他映射区重叠。
- 映射区的起始地址不能是NULL,除非设置了MAP_FIXED标志。
- 映射区的起始地址和长度必须对齐到页大小。
- 映射区的保护方式和标志不能与已有的映射区冲突

作业三

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>

#define WHITE 0xFFFFFFFF
#define BLACK 0xFF000000
#define RED   0xFFFF0000

int main()
{
    int fd_lcd = open("/dev/fb0", O_RDWR);
    if (fd_lcd == -1)
    {
        printf("打开文件失败\n");
        return -1;
    }

    int *lcd_mp = mmap(NULL, 800*480*4, PROT_READ|PROT_WRITE, MAP_SHARED, fd_lcd, 0);
    if (lcd_mp == MAP_FAILED)
    {
        printf("内存映射失败\n");
        close(fd_lcd);
        return -1;
    }

    // 绘制背景
    int x, y;
    for (y = 190; y < 290; y++)
    {
        for (x = 200; x < 600; x++)
        {
            lcd_mp[800 * y + x] = WHITE;
        }
    }

    // 绘制进度条指示器
    for (x = 200; x < 600; x++)
    {
        for (y = 190; y < 290; y++)
        {
            lcd_mp[800 * y + x] = BLACK;
        }
        usleep(100000);
    }

    munmap(lcd_mp, 800*480*4);
    close(fd_lcd);

    return 0;
}

其中最难的点就是两个for循环嵌套了

之前一直往横着一条一条打印,就无法实现

for ( y = 0; y < 800; y++)
{
    for ( x = 0; x < 480; i++)
    {
        
    }
    
}

 假如第一个for循环是x的话,那么就是竖着一起打印,进度条的问题就自然解决了。

第四天

打印图片

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>

#define BMP "./1.bmp"

int main()
{
    int x,y;
    int i = 0;
    int color;
    char r,g,b;

    //打开lcd
	int lcd_fd = open("/dev/fb0",O_RDWR); 
	if(-1 == lcd_fd)
	{
		perror("open() lcd failed");
		return -1;
	}
	//进行内存映射
	int *p = mmap(NULL,800*480*4,PROT_READ | PROT_WRITE,MAP_SHARED,lcd_fd,0);
	if(NULL == p)
	{
		perror("mmap() failed");
		return -1;
	}

    //1:打开一个我们的图片
    int lcd_bmp = open(BMP,O_RDWR);
    if(-1 == lcd_bmp)
    {
        printf("打开失败了吧\n");
    }
    printf("打开成功了吧\n");

    //进行图片操作之前,光标位移54个字节
    lseek(lcd_bmp,54,SEEK_SET);

    //读取我们图片的一个数据
    char buf_bmp[800*480*3];     
    read(lcd_bmp,buf_bmp,800*480*3);



    for(y=479; y>=0; y--)
    {
        for(x=0; x<800; x++)
        {
            r = buf_bmp[i++]; //0
            g = buf_bmp[i++]; //1
            b = buf_bmp[i++]; //2

            color = b <<16 | g <<8  | r ;
            *(p+x+800*y) = color;
        }
    }
    
    close(lcd_fd);
    close(lcd_bmp);
    
    return 0;
}

 lseek函数:

lseek函数是C语言中用于移动文件指针的函数,其原型如下:

```c
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
```

其中,参数fd为文件描述符,offset为偏移量,whence为起始位置。

lseek函数的返回值为文件指针的新位置,如果出现错误则返回-1。

lseek函数的常用起始位置和偏移量如下:

- SEEK_SET:文件开头,偏移量为正数表示向后移动,为负数表示向前移动。
- SEEK_CUR:当前位置,偏移量为正数表示向后移动,为负数表示向前移动。
- SEEK_END:文件结尾,偏移量为正数表示向后移动,为负数表示向前移动

 分析:

color = b <<16 | g <<8  | r ;
这里进行了位运算里面的或运算,目的就是将原本图片的RGB文件改成BRG。

for(y=479; y>=0; y--)
这里是因为假如是正序的话,图片是反过来的,因为图片是从开发板左下角开始打印。

 r = buf_bmp[i++]; //0
 g = buf_bmp[i++]; //1
 b = buf_bmp[i++]; //2
这个实现rgb交替的一个赋值

第五天

触摸屏

#include <stdio.h>
#include <string.h>
#include <sys/types.h> 
#include <sys/stat.h>
#include <fcntl.h> //open
#include <unistd.h> //sleep close
#include <linux/input.h>
#include <sys/mman.h>

//显示屏文件
#define BMP0 "./background.bmp"
#define BMP1 "./1.bmp"
#define BMP2 "./2.bmp"
#define BMP3 "./3.bmp"
#define BMP4 "./4.bmp"
#define BMP5 "./5.bmp"
#define BMP6 "./6.bmp"
#define BMP7 "./7.bmp"

int x, y, j = 0;//全局变量

//显示屏函数
int  open_printf(char* which_bmp, int array_size, int x1, int x2)
{   
    int color,i = 0;
    char r, g, b;   

    int fd_lcd = open("/dev/fb0",O_RDWR);    //打开显示屏文件
	int *p = mmap(NULL,800*480*4,PROT_READ | PROT_WRITE,MAP_SHARED,fd_lcd,0);
	if(NULL == p)
	{
		perror("mmap() failed");
		return -1;
	}

    int lcd_bmp = open(which_bmp,O_RDWR);//打开背景图
    //进行图片操作之前,光标位移54个字节
    lseek(lcd_bmp,54,SEEK_SET);
    //读取我们图片的一个数据
    char buf_bmp[array_size];     
    read(lcd_bmp,buf_bmp,sizeof(buf_bmp));
    //打印图片
    for(y=479; y>=0; y--)
    {
        for(x = x1; x < x2; x++)
        {
            r = buf_bmp[i++]; //0
            g = buf_bmp[i++]; //1
            b = buf_bmp[i++]; //2
            color = b << 16 | g << 8 | r ;
            *(p+x+800*y) = color;
        }
    }
}
//触摸屏函数
int axis()
{   
    int cnt;
    //打开触摸屏文件
    int fd_ts = open("/dev/input/event0",O_RDWR);
    struct input_event init_eventStruct;
    memset(&init_eventStruct,0,sizeof(struct input_event));
    read(fd_ts,&init_eventStruct,sizeof(struct input_event));
    //触摸屏默认的一个xy的大小是1024*600
    if(init_eventStruct.type == EV_ABS)
    {
        if(init_eventStruct.code == ABS_X)
        {
            x = init_eventStruct.value*800/1024;
            //x = (int)(800*1.0)/1024*init_eventStruct.value;
            printf("x = %d\n",x);
            cnt++;
        }
    }
    return x;
}

//while循环函数
int loop()
{   
    char* photo[] = {BMP1, BMP2, BMP3, BMP4, BMP5, BMP6, BMP7};
    while(1)
    {   
        x = axis();
        if(x > 600 && x < 800)//右滑
        {
            j = j + 1;
            if (j == 7){j = 0;}
            open_printf(photo[j], 400*480*3, 200, 600);
        }
        if (x > 0 && x < 200)//左滑
        {
            j = j - 1;
            if (j == -1){j = 6;}
            open_printf(photo[j], 400*480*3, 200, 600);
        }
        x = 0;
    } 
}

//主函数
int main(void)
{       
    open_printf(BMP0, 800*480*3, 0, 800);//背景图
    open_printf(BMP1, 400*480*3 ,200, 600);//显示第一张图片
    loop();
}

主要实现一个切换图片

效果如下:

粤嵌第一周项目作业

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值