Day4_File_IO
1.内存映射
通过write去操作屏幕,有明显的缺陷
- 屏幕很慢(write的效率不高)
- 连续调用write还需要配合使用
lseek
- 只是想操作屏幕一小部分,对整个
fram buffer
赋值
即有人提出fram buffer
本身就是一块内存,在C语言中,我们知道一个内存的地址(指针)就可以通过指针来操作这块内存。
假设:
int *plcd;//指向linux你和帧缓冲的首地址
屏幕上第一个像素点在帧缓冲中的地址为plcd
*plcd = 0xff00;//屏幕上的第一个像素点会显示成绿的
第一行的第二个像素点在帧缓冲中的地址:
plcd+1
*(plcd+1) = 0xff00;
...
屏幕上坐标为x,y的像素点在帧缓冲中的地址
plcd+800*y+x
*(plcd+800*y+x) = 0xff00;
===>封装成函数 任意的在屏幕上显示一个像素点
void Lcd_draw_point(int x,int y,int color,int *plcd)
{
if(NULL == plcd)
{
printf("error:plcd == NULL\n");
return ;
}
if(x>=0&&x<800&&y>=0&&y<480)
{
*(plcd+800*y+x) = color;
}
}
LINUX操作系统提供了一个API函数:mmap
memory map 内存映射
NAME
mmap, munmap - map or unmap files or devices into memory
映射或解映射文件或设备到内存
SYNOPSIS
#include <sys/mman.h>
void *mmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset);
@addr:映射到应用程序的哪个地址上去,不知道。填NULL,表示让系统自行分配。
@length:要映射区域长度。800*480*4
@prot:指定映射区域的权限
PROT_EXEC Pages may be executed.
PROT_READ Pages may be read.
PROT_WRITE Pages may be written.
PROT_NONE Pages may not be accessed.
位定义0000 PROT_EXEC PROT_READ PROT_WRITE PROT_NONE
1000 0100 0010 0001
0110 0100 | 0010
PROT_READ | PROT_WRITE
@flags:映射标志 映射方式 有如下两种情况
MAP_SHARED:共享映射 你对映射区域的操作会立即反馈到文件或内核
MAP_PRIVATE:私有映射 你对映射区域的操作只对你可见
@fd:
@offset:偏移量 表示你想从文件的哪个位置开始映射
返回值:
成功:返回映射区域的首地址
失败:返回MAP_FAILED 同时errno被设置
int munmap(void *addr, size_t length);
2.文件io
系统IO:由操作系统提供的,LINUX/UNIX、 WIN <---- - 标准IO:为了更好的能够方便移植,同一标准。printf scanf... 它调用的系统IO屏幕
1.文件描述符
file discriptor 唯一性 整数
所有已经打开的文件都是通过文件描述符来引用。
文件描述符是在LINUX下面,唯一标识一个已经打开的文
件。后续对这个文件的所有的操作都通过文件描述符。
2.文件的操作
man:manual 手册
LINUX会为每个库函数/命令提供一个帮助文档,而 man则是用来查询该帮助文档的。
man ls 查询ls这条指令的帮助文件(默认是第一页)
选项-f 帮助文档的目录,因为你要查询的命令可能在 不同的环境下是不同的东西。函数名或者命令。
man -f ls f
man 数字 要查询的东西 :查看指定的页数
a.open/close
NAME
open - open a file
SYNOPSIS
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int
flags);
@pathname:路径名 可以是相对路径也可以是
绝对路径
@flags:打开标志,文件打开以后的权限,读和写
O_RDONLY:open_read_only
O_WRONLY
O_RDWR
三个标志任选其一
返回值:
成功返回文件描述符(>2) 代表了该文件0 1 2 标准输入 标准输出 标准出错
失败返回-1,并且errno(错误码)被设置
我 槟榔
1 买到了
0 有内鬼 终止交易
-1 被他吃完了
-2 ...
errno ---> perror
NAME
perror - print a system error message
SYNOPSIS
#include <stdio.h>
void perror(const char *s);
@s:所指向的内容由用户进行输入
比如:perror("open fail");
open fail:success\n
NAME
close - close a file descriptor
SYNOPSIS
#include <unistd.h>
int close(int fd);
参考代码
int fd = open("/LJ/1.txt",O_RDWR);
if(-1 == fd)
{
perror("open fail");
return -1;
}
//...
close(fd);
b.read/write
NAME
read - read from a file descriptor
SYNOPSIS
#include <unistd.h>
ssize_t read(int fd, void *buf,size_t count);
从文件中读取count个字节放到buf所指向的地方中去。
@fd:
@buf:
@count:
返回值:
>0 成功读取到的字节数,文件偏移量(光标)随之增加
=0 什么都没有读到 到达文件的末尾 文件结束了
<0 出错 同时errno被设置
NAME
write - write to a file descriptorSYNOPSIS
#include <unistd.h>
ssize_t write(int fd, const void*buf, size_t count);
把buf所指向的空间中最多count个字节写到fd所代表的文件中去。
返回值:
>0 成功写入的字节数,文件偏移量(光标)随之增加
=0 什么都没有写入
<0 出错 同时errno被设置
ps:
ssize_t size_t ???
使用typedef来定义的新类型
typedef unsigned int Uint_32 //定义了一个新类型,名为Uint_32 实际上就是//unsigned int
c.lseek
NAME
lseek - reposition read/write file
offset
重定位光标
SYNOPSIS
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset,
int whence);
@fd
@offset:要设置的偏移量
@whence:定位方式
SEEK_SET 基于文件的开头
The file offset is set to offset bytes.
新的光标位置=文件开头+offset(>0)
SEEK_CUR 基于光标当前的位置
The file offset is set to its current location plus offset bytes.
新的光标位置=光标当前的位置+offset(可正可负)
SEEK_END 基于文件的末尾
The file offset is set to the size of the file plus offset bytes.
新的光标位置=文件的末尾+offset(可正可负)
返回值:
成功返回新的光标位置相对于文件开头的偏移量 单位:字节
失败返回-1,并且errno被设置
重定位光标在文件的开头
lseek(fd,0,SEEK_SET);
使用lseek求文件的大小
3.LCD屏幕
一、屏幕属性
液晶显示屏
分辨率:有多少行 多少列像素点。
1080p:1080* 1920
2K:1440* 2545
4K:...
6818开发板:480p 480*800=384000个像素点
像素点:
piexl:显示某种颜色的点。
在屏幕上显示图像,就是给每个像素点一个颜色。
颜色:红色 蓝色 黑色... DC2(DREAM COLOR梦幻) 十 亿色
三基色:红绿蓝 RGB red green blue 红的程度不一样,怎么来形容这种程度呢?量化:数量化 RGB设备
红0~255 绿 蓝
255 0 0 耀世红 0XFF0000
0 255 0 原谅绿 0xFF00
0 0 255 天空蓝 0XFF
透明度: 一个像素点看起来透明的问题。A(占一个字节 0~255)
ARGB
6818开发板屏幕就是ARGB(四个字节)
二、LINUX帧缓冲
中间层OS的作用:对上层应用层提供操作硬件的接口函数, 屏蔽硬件具体实现细节。让用户不必去关系硬件的实现。
在内存中开辟一块缓冲区,用来保存屏幕上每个像素点的 颜色值,然后应用成序直接把要显示的图像的颜色值写入 到内存即可。
这块缓冲区buffer至少多大:800* 480* 4
帧缓冲设备是对图像硬件的一种抽象,它让上层应用不必 去关心具体的硬件实现细节,上层图形应用,只需要在帧 缓冲中填上合适的颜色值,然后帧缓冲的驱动按一定的刷 新频率去把颜色值在屏幕上正确的显示。
以上就是帧缓冲的原理。
LINUX中设计哲学:LINUX一切皆文件。
屏幕:/dev/fb0
三、练习
/*****************************************************************************
字符串A123aBCd&$$eNd
把大写字母->小写
小写->大写
其他字符不变
要求:需要封装成函数
*****************************************************************************/
#if 0
#include <stdio.h>
char *String_change(char str[]);
int main()
{
char str[] = {"A123aBCd&$$eNd"};
printf("%s\n",String_change(str));
return 0;
}
char *String_change(char str[])
{
int i = 0;
for(;str[i]!='\0';i++)
{
if(str[i] >= 97&&str[i] <= 122)
{
str[i] -= 32;
}
else if(str[i] >= 65&&str[i] <=90)
{
str[i] += 32;
}
}
return str;
}
#endif
/*****************************************************************************
在开发板的屏幕显示德国国旗
*****************************************************************************/
#if 0
#include<stdio.h>
/*头文件*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
/*宏定义*/
#define FILE_PATH "/dev/fb0"
int main(int argc,char **argv)
{
//1.打开帧缓冲
int fd = open("/dev/fb0",O_RDWR);
if(-1 == fd)
{
perror("open fail");
//print a system error message
return -1;
}
/*
int open(const char *pathname, int
flags);
@pathname:路径名 可以是相对路径也可以是
绝对路径
@flags:打开标志,文件打开以后的权限,读和
写
O_RDONLY : open_read_only
O_WRONLY
O_RDWR
三个标志任选其一
返回值:
成功返回文件描述符(>2) 代表了该文件
0 1 2 标准输入 标准输出 标准出错
失败返回-1,并且errno(错误码)被设
置
*/
//2.写入颜色值
int color[480][800];
int i,j;
for(j=0;j<480;j++)
{
for(i=0;i<800;i++)
{
id(j<=160)
color[j][i]=0x000000;
else if(j<=320)
color[j][i]=0xff0000;
else
color[j][i]=0xffff00;
}
}
int ret = write(fd,color,800*480*4);
if(ret < 0)
{
perror("write fail");
return -1;
}
/*
ssize_t read(int fd, void *buf,
size_t count);
从文件中读取count个字节放到buf所指向的地方中
去。
@fd:
@buf:
@count:
返回值:
>0 成功读取到的字节数,文件偏移量(光标)
随之增加
=0 什么都没有读到 到达文件的末尾 文件结束
了
<0 出错 同时errno被设置
*/
//3.关闭文件
close(fd);
}
#endif
/*****************************************************************************
使用lseek求文件的大小(单位字节)
NAME lseek - reposition read/write file offset
即重定位光标
off_t lseek(int fd, off_t offset,int whence);
@fd
@offset:要设置的偏移量
@whence:定位方式
SEEK_SET 基于文件的开头
The file offset is set to offset bytes.
新的光标位置=文件开头+offset(>0)
SEEK_CUR 基于光标当前的位置
The file offset is set to its current location plus offset bytes.
新的光标位置=光标当前的位置+offset(可正可负)
SEEK_END 基于文件的末尾
The file offset is set to the size of the file plus offset bytes.
新的光标位置=文件的末尾+offset(可正可负)
返回值:
成功返回新的光标位置相对于文件开头的偏移量
单位:字节
失败返回-1,并且errno被设置
重定位光标在文件的开头
lseek(fd,0,SEEK_SET);
*****************************************************************************/
#if 1
#include<stdio.h>
/*头文件*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
/*宏定义*/
#define FILE_PATH "../ceshi.txt"
int main(int argc,char **argv)
{
char str[1000] = "今天真好看!!";
int i=0;
/*
打开文件:open(文件路径 O_RDONLY/O_WRONLY/O_RDWR)
返回值:文件描述符(代表该文件)/-1.
*/
int fd = open(FILE_PATH,O_RDWR);
if(-1 == fd)
{
perror("open fail");
//print a system error message
return -1;
}
/*
写入:write(文件描述符<-待放数据 ,内存大小)
返回值: >0 成功读取到的字节数,文件偏移量(光标)随之增加
=0 什么都没有读到 到达文件的末尾 文件结束
<0 出错 同时errno被设置
*/
int length=lseek(fd,14,SEEK_SET);
int ret = write(fd,str,1000);
if(ret < 0)
{
perror("write fail");
return -1;
}
/*将光标移回开头*/
length=lseek(fd,0,SEEK_SET);
/*从最后开始,0偏移,返回偏移量*/
int red=read(fd,str,1000);
if(red <= 0)
{
perror("read fail");
return -1;
}
for(i=0;i<1000;i++)
printf("%c",str[i]);
length=lseek(fd,0,SEEK_END);
printf("%d",length);
close(fd);
}
#endif
4.homework
/********************************************************************
作业
1.在屏幕的x y(矩形的左上角)处显示一个颜色为color
高h宽为w的矩形
封装成函数
2.在屏幕上显示一个圆
封装成函数
拓展:显示一个太极图案
********************************************************************/
#if 0
/*头文件*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/mman.h>
/*宏定义*/
#define FILE_PATH "/dev/fb0"
/*函数声明*/
int *Init_LCD(int *fd);
void Uninit_LCD(int fd,int *plcd);
void Lcd_draw_point(int x,int y,int color,int *plcd);
void Lcd_draw_matrx(int x,int y,int h,int w,int color,int *plcd );
void Lcd_draw_circle(int x,int y,int r,int color,int *plcd );
void Lcd_draw_leftcircle(int x,int y,int r,int color,int *plcd );
void Lcd_draw_rightcircle(int x,int y,int r,int color,int *plcd );
void Lcd_draw_taiji(int x,int y,int r,int *plcd);
int main(int argc,char **argv)
{
int fd=-1;
int* plcd = Init_LCD(&fd);
Lcd_draw_matrx(0,0,880,480,0xff0000,plcd);//清屏
//Lcd_draw_circle(440,240,200,0xff0000,plcd);
Lcd_draw_taiji(440,240,200,plcd);
Uninit_LCD(fd,plcd);
}
/*
Init_LCD:初始化显示屏
参数为空
返回值 int*
成功 返回映射区域的首地址
失败 返回NULL
*/
int *Init_LCD(int *fd)
{
//1.打开帧缓冲
*fd = open("/dev/fb0",O_RDWR);
if(-1 == *fd)
{
perror("open fail");
return NULL;
}
//2.映射
int *plcd = mmap(NULL,800*480*4
,PROT_READ | PROT_WRITE,
MAP_SHARED,*fd,0);
if(MAP_FAILED == plcd)
{
perror("mmap fail");
return NULL;
}
return plcd;
}
/*
Uninit_LCD:解初始化屏幕
@fd:帧缓冲的文件描述符
@plcd:
返回值:无
*/
void Uninit_LCD(int fd,int *plcd)
{
//1.解映射
munmap(plcd,800*480*4);
//2.关闭帧缓冲
close(fd);
}
void Lcd_draw_point(int x,int y,int color,int *plcd)
{
if(NULL == plcd)
{
printf("error:plcd == NULL\n");
return ;
}
if(x>=0&&x<800&&y>=0&&y<480)
{
*(plcd+800*y+x) = color;
}
}
void Lcd_draw_matrx(int x,int y,int h,int w,int color,int *plcd)
{
int i,j;
if((x+w)>=0||(x+w)<=880||(y+h)>=0||(y+h)<=880)
for(j=x;j<x+w;j++)
{
for(i=y;i<y+h;i++)
{
Lcd_draw_point(i,j,color,plcd);
}
}
}
void Lcd_draw_circle(int x,int y,int r,int color,int *plcd )
{
int i,j;
for(j=0;j<480;j++)
{
for(i=0;i<880;i++)
{
if((x-i)*(x-i)+(y-j)*(y-j)<r*r)
Lcd_draw_point(i,j,color,plcd);
}
}
}
void Lcd_draw_leftcircle(int x,int y,int r,int color,int *plcd )
{
int i,j;
for(j=0;j<480;j++)
{
for(i=0;i<880;i++)
{
if((x-i)*(x-i)+(y-j)*(y-j)<r*r&&i<x)
Lcd_draw_point(i,j,color,plcd);
}
}
}
void Lcd_draw_rightcircle(int x,int y,int r,int color,int *plcd )
{
int i,j;
for(j=0;j<480;j++)
{
for(i=0;i<880;i++)
{
if((x-i)*(x-i)+(y-j)*(y-j)<r*r&&i>=x)
Lcd_draw_point(i,j,color,plcd);
}
}
}
void Lcd_draw_taiji(int x,int y,int r,int* plcd)
{
Lcd_draw_leftcircle(x,y,r,0x000000,plcd);
Lcd_draw_rightcircle(x,y,r,0xffffff,plcd);
Lcd_draw_circle(x,y-(r/2),r/2,0xffffff,plcd);
Lcd_draw_circle(x,y+(r/2),r/2,0x000000,plcd);
Lcd_draw_circle(x,y-(r/2),r/4,0x000000,plcd );
Lcd_draw_circle(x,y+(r/2),r/4,0xffffff,plcd );
}
#endif
/*******************************************************************************
碰壁转弯直线代码
*******************************************************************************/
#if 0
/*头文件*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/mman.h>
/*宏定义*/
#define FILE_PATH "/dev/fb0"
/*函数声明*/
int *Init_LCD(int *fd);
void Uninit_LCD(int fd,int *plcd);
void Lcd_draw_point(int x,int y,int color,int *plcd);
void Lcd_draw_matrx(int x,int y,int h,int w,int color,int *plcd );
void Lcd_draw_circle(int x,int y,int r,int color,int *plcd );
void Lcd_draw_leftcircle(int x,int y,int r,int color,int *plcd );
void Lcd_draw_rightcircle(int x,int y,int r,int color,int *plcd );
void Lcd_draw_taiji(int x,int y,int r,int *plcd);
int main(int argc,char **argv)
{
int fd=-1;
int* plcd = Init_LCD(&fd);
Lcd_draw_matrx(0,0,880,480,0xff0000,plcd);//清屏
//Lcd_draw_circle(440,240,200,0xff0000,plcd);
Lcd_draw_taiji(440,240,5,plcd);
Uninit_LCD(fd,plcd);
}
/*
Init_LCD:初始化显示屏
参数为空
返回值 int*
成功 返回映射区域的首地址
失败 返回NULL
*/
int *Init_LCD(int *fd)
{
//1.打开帧缓冲
*fd = open("/dev/fb0",O_RDWR);
if(-1 == *fd)
{
perror("open fail");
return NULL;
}
//2.映射
int *plcd = mmap(NULL,800*480*4
,PROT_READ | PROT_WRITE,
MAP_SHARED,*fd,0);
if(MAP_FAILED == plcd)
{
perror("mmap fail");
return NULL;
}
return plcd;
}
/*
Uninit_LCD:解初始化屏幕
@fd:帧缓冲的文件描述符
@plcd:
返回值:无
*/
void Uninit_LCD(int fd,int *plcd)
{
//1.解映射
munmap(plcd,800*480*4);
//2.关闭帧缓冲
close(fd);
}
void Lcd_draw_point(int x,int y,int color,int *plcd)
{
if(NULL == plcd)
{
printf("error:plcd == NULL\n");
return ;
}
if(x>=0&&x<800&&y>=0&&y<480)
{
*(plcd+800*y+x) = color;
}
}
void Lcd_draw_matrx(int x,int y,int h,int w,int color,int *plcd)
{
int i,j;
if((x+w)>=0||(x+w)<=880||(y+h)>=0||(y+h)<=880)
for(j=x;j<x+w;j++)
{
for(i=y;i<y+h;i++)
{
Lcd_draw_point(i,j,color,plcd);
}
}
}
void Lcd_draw_circle(int x,int y,int r,int color,int *plcd )
{
int i,j;
for(j=0;j<480;j++)
{
for(i=0;i<880;i++)
{
if((x-i)*(x-i)+(y-j)*(y-j)<r*r)
Lcd_draw_point(i,j,color,plcd);
}
}
}
void Lcd_draw_leftcircle(int x,int y,int r,int color,int *plcd )
{
int i,j;
for(j=0;j<480;j++)
{
for(i=0;i<880;i++)
{
if((x-i)*(x-i)+(y-j)*(y-j)<r*r&&i<x)
Lcd_draw_point(i,j,color,plcd);
}
}
}
void Lcd_draw_rightcircle(int x,int y,int r,int color,int *plcd )
{
int i,j;
for(j=0;j<480;j++)
{
for(i=0;i<880;i++)
{
if((x-i)*(x-i)+(y-j)*(y-j)<r*r&&i>=x)
Lcd_draw_point(i,j,color,plcd);
}
}
}
void Lcd_draw_taiji(int x,int y,int r,int* plcd)
{
//上圆心
int i0=x;
int j0=y-r/2;
//下圆心
int i2=x;
int j2=y+r/2;
int flog=0;
int flog1=0;
while(1)
{
if(0==flog)
{
j0--;
Lcd_draw_circle(i0,j0,r/2,0xffffff,plcd);
Lcd_draw_circle(i0,j0,r/4,0x000000,plcd );
//sleep(0.5);
if(j0==1)flog=1;
}
if(1==flog)
{
j0++;
Lcd_draw_circle(i0,j0,r/2,0xffffff,plcd);
Lcd_draw_circle(i0,j0,r/4,0x000000,plcd );
//sleep(0.5);
if(j0==480)flog=0;
}
if(0==flog1)
{
i0++;
Lcd_draw_circle(i0,j0,r/2,0xffffff,plcd);
Lcd_draw_circle(i0,j0,r/4,0x000000,plcd );
//sleep(0.5);
if(i0==800)flog1=1;
}
if(1==flog1)
{
i0--;
Lcd_draw_circle(i0,j0,r/2,0xffffff,plcd);
Lcd_draw_circle(i0,j0,r/4,0x000000,plcd );
//sleep(0.5);
if(i0==1)flog1=0;
}
}
}
#endif
/********************************************************************
* 转动太极图案代码
*
********************************************************************/
#if 1
/*头文件*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/mman.h>
/*宏定义*/
#define FILE_PATH "/dev/fb0"
/*函数声明*/
int *Init_LCD(int *fd);
void Uninit_LCD(int fd,int *plcd);
void Lcd_draw_point(int x,int y,int color,int *plcd);
void Lcd_draw_matrx(int x,int y,int h,int w,int color,int *plcd );
void Lcd_draw_circle(int x,int y,int r,int color,int *plcd );
void Lcd_draw_leftcircle(int x,int y,int r,int color,int *plcd );
void Lcd_draw_rightcircle(int x,int y,int r,int color,int *plcd );
void Lcd_draw_taiji(int x,int y,int r,int *plcd);
int main(int argc,char **argv)
{
int fd=-1;
int* plcd = Init_LCD(&fd);
Lcd_draw_matrx(0,0,880,480,0xff0000,plcd);//清屏
//Lcd_draw_circle(440,240,200,0xff0000,plcd);
Lcd_draw_taiji(400,240,200,plcd);
Uninit_LCD(fd,plcd);
}
/*
Init_LCD:初始化显示屏
参数为空
返回值 int*
成功 返回映射区域的首地址
失败 返回NULL
*/
int *Init_LCD(int *fd)
{
//1.打开帧缓冲
*fd = open("/dev/fb0",O_RDWR);
if(-1 == *fd)
{
perror("open fail");
return NULL;
}
//2.映射
int *plcd = mmap(NULL,800*480*4
,PROT_READ | PROT_WRITE,
MAP_SHARED,*fd,0);
if(MAP_FAILED == plcd)
{
perror("mmap fail");
return NULL;
}
return plcd;
}
/*
Uninit_LCD:解初始化屏幕
@fd:帧缓冲的文件描述符
@plcd:
返回值:无
*/
void Uninit_LCD(int fd,int *plcd)
{
//1.解映射
munmap(plcd,800*480*4);
//2.关闭帧缓冲
close(fd);
}
void Lcd_draw_point(int x,int y,int color,int *plcd)
{
if(NULL == plcd)
{
printf("error:plcd == NULL\n");
return ;
}
if(x>=0&&x<800&&y>=0&&y<480)
{
*(plcd+800*y+x) = color;
}
}
void Lcd_draw_matrx(int x,int y,int h,int w,int color,int *plcd)
{
int i,j;
if((x+w)>=0||(x+w)<=880||(y+h)>=0||(y+h)<=880)
for(j=x;j<x+w;j++)
{
for(i=y;i<y+h;i++)
{
Lcd_draw_point(i,j,color,plcd);
}
}
}
void Lcd_draw_circle(int x,int y,int r,int color,int *plcd )
{
int i,j;
for(j=0;j<480;j++)
{
for(i=0;i<880;i++)
{
if((x-i)*(x-i)+(y-j)*(y-j)<r*r)
Lcd_draw_point(i,j,color,plcd);
}
}
}
void Lcd_draw_leftcircle(int x,int y,int r,int color,int *plcd )
{
int i,j;
for(j=0;j<480;j++)
{
for(i=0;i<880;i++)
{
if((x-i)*(x-i)+(y-j)*(y-j)<r*r&&i<x)
Lcd_draw_point(i,j,color,plcd);
}
}
}
void Lcd_draw_rightcircle(int x,int y,int r,int color,int *plcd )
{
int i,j;
for(j=0;j<480;j++)
{
for(i=0;i<880;i++)
{
if((x-i)*(x-i)+(y-j)*(y-j)<r*r&&i>=x)
Lcd_draw_point(i,j,color,plcd);
}
}
}
void Lcd_draw_taiji(int x,int y,int r,int* plcd)
{
int i=0,j=0;
int m=i+10,n=j+10;
int time=500;
//上圆心
int i0=x;
int j0=y-r/2;
//下圆心
int i2=x;
int j2=y+r/2;
int addx[20]={400,372,340,320,304,300,304,320,340,373,400,428,460,480,496,500,496,480,460,428};
int addy[20]={140,144,160,180,212,240,268,300,320,336,340,336,320,300,268,240,212,180,160,144};
//画两个半圆
Lcd_draw_leftcircle(x,y,r,0x000000,plcd);//黑
Lcd_draw_rightcircle(x,y,r,0xffffff,plcd);//白
//画两个大圆
Lcd_draw_circle(i0,j0,r/2,0xffffff,plcd);
Lcd_draw_circle(i2,j2,r/2,0x000000,plcd);
//画两个小圆
Lcd_draw_circle(i0,j0,r/4,0x000000,plcd );
Lcd_draw_circle(i2,j2,r/4,0xffffff,plcd );
while(1)
{
//画两个大圆
Lcd_draw_circle(addx[i],addy[j],r/2,0xffffff,plcd);
Lcd_draw_circle(addx[m],addy[n],r/2,0x000000,plcd);
//sleep(0.25);
//画两个小圆
Lcd_draw_circle(addx[i],addy[j],r/4,0x000000,plcd );
Lcd_draw_circle(addx[m],addy[n],r/4,0xffffff,plcd );
i++;
j++;
m++;
n++;
sleep(0.5);
if(20==i)i=0;
if(20==j)j=0;
if(20==m)m=0;
if(20==n)n=0;
}
}
#endif
/*
//用这个程序求出解的数组:
#include<stdio.h>
int main()
{
int i, j;
//int str[10000][10000];
for (j = 140; j <= 340;j++)
{
for (i = 300; i <= 500; i++)
{
if (207600 + i * i + j * j == 800 * i + 480 * j)
{
printf("有解:%d,%d",i,j);
printf("\n");
}
}
}
return 0;
}
有解:400,140
有解:372,144
有解:428,144
有解:340,160
有解:460,160
有解:320,180
有解:480,180
有解:304,212
有解:496,212
有解:300,240
有解:500,240
有解:304,268
有解:496,268
有解:320,300
有解:480,300
有解:340,320
有解:460,320
有解:372,336
有解:428,336
有解:400,340
即:
//上圆逆时针转到下圆:0-9
400,140
372,144
340,160
320,180
304,212
300,240
304,268
320,300
340,320
372,336
//下圆逆时针转到上圆:10-19
400,340
428,336
460,320
480,300
496,268
500,240
496,212
480,180
460,160
428,144
*/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!