触摸屏驱动随笔

最近一直纠结于触摸驱动的学习,使用的模块编译,开发板为tiny4412,过程中有个小细节纠结了一天,就是设备节点文件,之前看网上触摸用event0,然而并不成功,修改了event1,上传应用层才会得到正确的xy坐标,使用的输入子系统。代码如下

有些不完善的地方还请各路大神指正,

驱动:
#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/uaccess.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <asm/io.h>
#include <mach/gpio.h>
#include <linux/gpio.h>
#include <plat/gpio-cfg.h>

#include <linux/interrupt.h>
#include <linux/irqreturn.h>
#include <linux/delay.h>
#include <linux/wait.h>

//引用函数时用到了宏
#include <linux/sched.h>
#include <linux/timer.h>

#include <linux/workqueue.h>
#include <linux/poll.h>

#include <linux/input.h>
#include <linux/i2c.h>
#include <linux/mod_devicetable.h>

#define TOUCH_X 0
#define TOUCH_Y 1
#define TOUCH_TP 33


static struct i2c_client *pt_arg= NULL;
static struct timer_list g_timer;
static struct work_struct g_list;
static struct input_dev *g_input_dev=NULL; //输入设备结构体


static irqreturn_t TOUCH_interrupt(int irq,void *arg)
{

pt_arg = (struct i2c_client *)arg;
//防抖 时间不能长,否则会检测不到连按下
mod_timer(&g_timer,jiffies+HZ/100); //5ms 10ms 20


return IRQ_HANDLED;
}

static void Timer_handle(unsigned long data)
{


// wake_up_interruptible(&wq); //将进程等待态唤醒至就绪态

//紧急事件
// printk("Timer_handle--name: %s addr:%u\n",pt_arg->name,pt_arg->addr);

//不紧急事件 开线程完成
schedule_work(&g_list);

}


static void Work_pthread(struct work_struct *work)
{
//work_queue 不支持传参 用全局变量

unsigned char buff[15]={0};
unsigned int GEST_ID=0;
unsigned int Touch_ID=0;
unsigned int touchpoints=0;
unsigned int x_value=0;
unsigned int y_value=0;
unsigned int Touch_Weight=0;
unsigned int Touch_Area=0;
unsigned int Direction=0;
unsigned int Speed=0;

//读取内存的值,Address指令
buff[0] = i2c_smbus_read_byte_data(pt_arg, 0x01); //GEST_ID
buff[1] = i2c_smbus_read_byte_data(pt_arg, 0x02);
buff[2] = i2c_smbus_read_byte_data(pt_arg, 0x03);
buff[3] = i2c_smbus_read_byte_data(pt_arg, 0x04);
buff[4] = i2c_smbus_read_byte_data(pt_arg, 0x05);
buff[5] = i2c_smbus_read_byte_data(pt_arg, 0x06);
buff[6] = i2c_smbus_read_byte_data(pt_arg, 0x07);
buff[7] = i2c_smbus_read_byte_data(pt_arg, 0x08);

// buff[8] = i2c_smbus_read_byte_data(pt_arg, 0x09);

GEST_ID = (unsigned int)buff[0];
touchpoints = (unsigned int)(buff[1] & 0x0f);
x_value = (((unsigned int)(buff[2] & 0x0f)) <<8 ) | buff[3];
Touch_ID = (unsigned int)((buff[4] & 0xf0)>>4);
y_value = (((unsigned int)(buff[4] & 0x0f))<<8 ) | buff[5];
Touch_Weight= (unsigned int)buff[6];
Touch_Area = (unsigned int)((buff[7] & 0xf0)>>4);
Direction = (unsigned int)((buff[7] & 0x0c)>>2);
Speed = (unsigned int)((buff[7] & 0x03));

// printk("GEST_ID:%d Touch_ID:%d touchpoints:%d \n",GEST_ID,Touch_ID,touchpoints);
// printk("Touch_Weight:%d Direction:%d Speed:%d \n",Touch_Weight,Direction,Speed);
// printk("(x_value,y_value):(%d,%d) \n",x_value,y_value);

//pt_arg->value = x_value;

if(touchpoints==0) //按键松开
{
input_report_key(g_input_dev,BTN_TOUCH, 0); //触点松开
input_report_abs(g_input_dev,ABS_PRESSURE,0);//压力为0
input_sync(g_input_dev);
}
else if(touchpoints==1)
{
input_report_abs(g_input_dev,ABS_X,(int)x_value);
input_report_abs(g_input_dev,ABS_Y,(int)y_value);
input_report_key(g_input_dev,BTN_TOUCH, 1); //触点按下
input_report_abs(g_input_dev,ABS_PRESSURE,1);//压力为1
input_sync(g_input_dev);
}
else
{
//
}

//输入子设备数据上传 子系统有写好的文件操作集合,无需自己写
// input_event(struct input_dev * dev, unsigned int type, unsigned int code, int value)

//ABS_X BTN_TOUCH ABS_MT_POSITION_X
//input_event(g_input_dev, EV_ABS,TOUCH_X,(int)x_value);
//input_event(g_input_dev, EV_ABS,TOUCH_Y,(int)y_value);
//input_event(g_input_dev, EV_ABS,TOUCH_TP,(int)touchpoints);
//input_sync(g_input_dev); //同步一下此次完成


}

static int i2c_dri_probe(struct i2c_client *p_client , const struct i2c_device_id * stu_data)
{
//EV_ABS
int ret=0;
unsigned long data = 8888;
printk("---matching successful probe---\n");
//此方法不能读写管脚
ret = request_irq(IRQ_EINT(14),TOUCH_interrupt,
IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_SHARED,
"TOUCH_COME", (void*)p_client);
//中断处理函数 ↑ | IRQF_TRIGGER_RISING
if(ret)
{
printk("request_irq error\n");
// goto request_irq_error;
}

//初始化定时器
setup_timer(&g_timer, Timer_handle, data);
//
INIT_WORK(&g_list, Work_pthread);

//申请设备结构体空间 及初始化部分
g_input_dev = input_allocate_device();
g_input_dev->name = "Input_Touch";

//表示设备支持EV_ABS事件
// input_set_capability(g_input_dev, EV_ABS, ABS_DISTANCE);
//触发类型 同步/绝对坐标
// set_bit(EV_SYN, g_input_dev->evbit );
set_bit(EV_KEY, g_input_dev->evbit );
set_bit(EV_ABS, g_input_dev->evbit );
//set_bit(EV_REP, g_input_dev->evbit ); //鼠标
//EV_REP 重复
//检测那些数据按键
set_bit(ABS_X,g_input_dev->absbit);
set_bit(ABS_Y,g_input_dev->absbit);
set_bit(ABS_PRESSURE,g_input_dev->absbit);
set_bit(BTN_TOUCH,g_input_dev->keybit);

//各个轴范围
input_set_abs_params(g_input_dev,ABS_X, 0,799, 0, 0);
input_set_abs_params(g_input_dev,ABS_Y, 0,479, 0, 0);
input_set_abs_params(g_input_dev,ABS_PRESSURE, 0,1, 0, 0);//按下1 无0
//注册到输入子系统
ret = input_register_device(g_input_dev); //0成功
if(ret)
{
printk("input_register_device error\n");
// goto input_register_device_error;
}

return 0;

input_register_device_error :
input_unregister_device(g_input_dev);
ret= -ENOMEM;
request_irq_error:
printk("--------\n");

return ret;
}

static int i2c_dri_remove(struct i2c_client *r_client)
{
printk("---i2c_dri_remove---\n");
del_timer(&g_timer);
free_irq(IRQ_EINT(14), (void*)r_client);
flush_work(&g_list);
input_unregister_device(g_input_dev);
input_free_device(g_input_dev);

return 0;

}

//匹配列表
static const struct i2c_device_id g_table[]={

{ .name = "TOUCH_XXX",
.driver_data = 555,
},
{ .name = "TOUCH_I2C",
.driver_data = 888,
},
{
"YWX_XXX", 5858,
},
{

},

};

static struct i2c_driver g_i2c_driver= {

.probe = i2c_dri_probe,
.remove = i2c_dri_remove,
.driver = {
.name = "TOUCH_YWX", //后期匹配

},
.id_table = g_table,


};


static int __init I2C_Driver_Init(void)
{
i2c_register_driver(THIS_MODULE, &g_i2c_driver);


return 0;
}

static void __exit I2C_Driver_Exit(void)
{
i2c_del_driver(&g_i2c_driver);

}

module_init(I2C_Driver_Init);
module_exit(I2C_Driver_Exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("YWX<[email protected]>");
MODULE_DESCRIPTION("THIS IS Ft5x06 TouchScreen driver");

                                                                                                                                                                                                                                                    

 

 应用层

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

#include <sys/select.h>

#include <poll.h>

#include <sys/wait.h>
#include <signal.h>

#include <sys/mman.h>

#include <linux/input.h>
#include "lcdconst.h"

#define LCD_WIDE 800 //分辨率
#define LCD_HIGH 480

#define LEN 800*480*4
#define RGB888(R,G,B) ((R<<16) | (G<<8) | (B))


#define RED RGB888(255,0,0) //红色
#define GREEN RGB888(0,255,0) //绿色
#define BLUE RGB888(0,0,255) //蓝色
#define BLACK RGB888(0,0,0) //黑色
#define WHITE RGB888(255,255,255) //白色
#define Color_1 RGB888(239,148,29) //暗黄
#define Color_2 RGB888(246,144,202) //粉红
#define Color_3 RGB888(219,252,234) // 初音未来


#define C_word_wide 24
#define C_word_high 24

#define Font_word_wide 16
#define Font_word_high 16

char C_Chinese[]=
{
0x00,0x00,0x00,0x0C,0x0C,0x00,0x0E,0x06,0x00,0x0E,0x06,0x18,0x0E,0x06,0x78,0x0F,0xF6,0xE0,0x0E,0x07,0x80,0x0E,0x06,0x0C,0x0E,0x06,0x0C,0x0E,0x36,0x0C,0x0F,0xE6 ,
0x0E,0x0F,0x07,0xFC,0x06,0x18,0x00,0x00,0x1C,0x00,0x00,0x1C,0x0C,0x7F,0xFF,0xFE,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00 ,
0x1C,0x00,0x00,0x18,0x00,0x00,0x00,0x00 ,/*"毕",0*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x00,0x63,0x80,0x00,0x63,0x00,0x00,0x63,0x00,0x00,0x63,0x00,0x30,0x63,0x0C,0x18,0x63,0x0E,0x18,0x63,0x1C,0x0C,0x63 ,
0x1C,0x0C,0x63,0x38,0x0E,0x63,0x30,0x07,0x63,0x30,0x07,0x63,0x60,0x07,0x63,0xC0,0x07,0x63,0xC0,0x00,0x63,0x80,0x00,0x63,0x00,0x00,0x63,0x00,0x00,0x63,0x06,0x7F ,
0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00 ,/*"业",1*/
0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xFF,0xF8,0x00,0x00,0x78,0x00,0x00,0xF0,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x1E,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C ,
0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x01,0xDC,0x00,0x00 ,
0x78,0x00,0x00,0x30,0x00,0x00,0x00,0x00 /*"了",2*/

};

char A_zifu[16]=
{
0x00,0x00,0x00,0xFC,0x66,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x66,0xFC,0x00,0xFF /*"D",0*/
};


int fp=0; //供信号函数用

unsigned char *pnew_addr = NULL; //保存用户空间的映射地址


void signal_handle(int sig);
void LCD_S702_draw_point(unsigned int xpox,unsigned int ypos,unsigned int color);
void LCD_S702_ractangle(unsigned int x_start,unsigned int y_start,unsigned int wide,unsigned int high,unsigned int color);
void LCD_S702_clear(unsigned int x_start,unsigned int y_start,unsigned int x_end,unsigned int y_end,unsigned int color);
void LCD_S702_Bresenhamline(int x0,int y0,int x1, int y1,int color);
void LCD_S702_Midpoint_Line(int x0,int y0,int x1, int y1,int color);
void LCD_S702_draw_strline(unsigned int sxpos, unsigned int sypos, unsigned int expos, unsigned int eypos,unsigned int color);
void LCD_S702_draw_circle_8(unsigned int xc, unsigned int yc, unsigned int x, unsigned int y, unsigned int color);
void LCD_S702_draw_circle(unsigned int xpos, unsigned int ypos, unsigned int radius, unsigned int color,unsigned int fill_color, char fill);
void LCD_S702_Display_A_Char(unsigned int spos,unsigned int ypos,char A_Char, unsigned int pcolor,unsigned int bcolor);
void LCD_S702_Display_String(unsigned int xpos,unsigned int ypos, char* Str, unsigned int pcolor,unsigned int bcolor);
void LCD_S702_Display_A_Char_word(unsigned int spos,unsigned int ypos,char *word ,unsigned int pcolor,unsigned int bcolor,char wide,char high);
void LCD_S702_Display_More_Chinese(unsigned int xpos,unsigned int ypos,char *word ,unsigned int Hanzi_Num,unsigned int pcolor,unsigned int bcolor,char wide,char high);
void LCD_S702_Font_Display_A_Word(unsigned int xpos,unsigned int ypos,char *word,unsigned int pcolor,unsigned int bcolor);
void LCD_S702_Font_Display_more(unsigned int xpos,unsigned int ypos,char *word,unsigned int pcolor,unsigned int bcolor);
void LCD_S702_Display_Picture(unsigned int sxpos,unsigned int sypos,unsigned int expos,unsigned int eypos,const unsigned char *picture);


int show_file_char(char *file_str);
int show_file_word(char *file_word,unsigned int s_xpos,unsigned int s_ypos);




int main(int argc,char *argv[])
{

int fp=0;

//光触摸用event0 上传应用程序用event1
fp=open("/dev/event1",O_RDWR,0666);
if(fp<0 )
{
printf("文件打开失败!");
perror("open"); //接收错误宏,每个宏数都有对应解释
printf("我的错误:%s errno:%d \r\n",strerror(errno),errno);
}


int re_num=0;
int x=0,y=0,tp=0;
int x_flag=0,y_flag=0;
struct input_event event_up;


unsigned int fl_state=0;

int fbb;
fbb=open("/dev/fb0",O_RDWR,0666);
if(fbb<0 )
{
printf("文件打开失败!");
printf("我的错误:%s errno:%d \r\n",strerror(errno),errno);
}




/* void *mmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset);
void *mmap64(void *addr, size_t length, int prot, int flags,
int fd, off64_t offset);
int munmap(void *addr, size_t length);
*/

//NULL自动分配 利用mmap内存映射,从内核映射到用户空间,在用户空间操作效率高
pnew_addr = mmap(NULL, LEN , PROT_READ | PROT_WRITE , MAP_SHARED,fbb, 0);


char pbuf[]=
" If addr is NULL, then the kernel chooses the address at which to createthe mapping;\
this is the most portable method of creating a new mapping.\n\
If addr is not NULL,\
then the kernel takes it as a hint about where to place the mapping; on Linux,\
the mapping will be created at a nearby page boundary.\r\n\
The address of the new mapping is returned as the result of the call. 123456789000123456 ";



LCD_S702_clear(0,0,LCD_WIDE,LCD_HIGH,WHITE);
/*
LCD_S702_draw_point(100,180,RED);
LCD_S702_draw_strline( 30,10,730,210,RED);
LCD_S702_Midpoint_Line(30,30,730,230,RED);
LCD_S702_Bresenhamline(30,50,730,250,RED);
LCD_S702_draw_circle(100, 240,60,GREEN,Color_3,1);
LCD_S702_draw_circle(700, 240,60,Color_2,Color_3,0);
LCD_S702_draw_circle(700, 100,60,RED,Color_3,1);
LCD_S702_Display_String(0,400, pbuf,BLUE,Color_3);


LCD_S702_Display_Picture(300,100,540,158,gImage_picture);//240*58
*/
//while(1);



//LCD_S702_Display_A_Char_word(0,230,A_zifu,Color_1,Color_3,8,16);
//LCD_S702_Display_More_Chinese(12,230,C_Chinese,3,Color_1,Color_3,C_word_wide,C_word_high);



//((0XCE-0XA1)*94 + (0XD2-0XA1))*32 偏移

while(1)
{
memset(&event_up,0,sizeof(event_up));
re_num = read(fp,&event_up,sizeof(event_up));
if(re_num < 0)
{ printf("re_num < 0 \n");
continue ;
}


switch(event_up.type)
{
case EV_SYN:
printf("EV_SYN!!value=%d\n",event_up.value); break;
case EV_REP:
printf("EV_REP!!value=%d\n",event_up.value); break;

case EV_KEY:
printf("EV_KEY!! BTN_TOUCH=%d\n",event_up.code);
break;

case EV_ABS:

if(event_up.code == ABS_X)
{
printf("ABS_X=%d\n",event_up.value);
x=event_up.value;
x_flag=1;
break;
}
if(event_up.code == ABS_Y)y=event_up.value;
{
printf("ABS_Y=%d\n",event_up.value);
y=event_up.value;
y_flag=1;
break;
}
// printf("EV_ABS**code =%d\n",event_up.code);
// printf("EV_ABS**value=%d\n",event_up.value);


default :
printf("+++default++++value=%d\n",event_up.value);
break;

}

if(x_flag==1 && y_flag==1)
{
x_flag=0;
y_flag=0;
printf("****(x,y)=(%d,%d) ****from up*****\n", x,y);
LCD_S702_draw_circle(x, y,3,GREEN,Color_3,1);

}




}
munmap(pnew_addr, LEN);

close(fp);
close(fbb);
return 0;

}



int show_file_word(char *file_word,unsigned int s_xpos,unsigned int s_ypos)
{

char backupbuf[2500]; //[1000]; //480*800/16/16=1500汉字
int ret;
int num_size=0;
int fw=0;
int my_control=0;
fw=open(file_word,O_RDONLY,0666);
if(fw < 0 )
{
printf("文件打开失败!");
printf("我的错误:%s errno:%d \r\n",strerror(errno),errno);
}

do
{
memset(backupbuf,0,sizeof(backupbuf));
ret = read(fw,backupbuf,sizeof(backupbuf));
if(ret>0)
{
//换行

LCD_S702_Font_Display_more(s_xpos + (num_size*16%LCD_WIDE),s_ypos + (num_size*16/LCD_WIDE)*16 , backupbuf,BLACK,Color_3);
num_size += ret; //字节个数

//满屏

}


}while(ret > 0 && my_control);
close(fw);
return 0;
}






int show_file_char(char *file_str)
{

char backupbuf[3500]; //[1000];
int ret;
int num_size=0;
int ft=0;
ft=open(file_str,O_RDONLY,0666);
if(ft<0 )
{
printf("文件打开失败!");
printf("我的错误:%s errno:%d \r\n",strerror(errno),errno);
}

do
{
memset(backupbuf,0,sizeof(backupbuf));
ret = read(ft,backupbuf,sizeof(backupbuf));
if(ret>0)
{
//换行

LCD_S702_Display_String(0 + (num_size*8%LCD_WIDE),3 + (num_size*8/LCD_WIDE)*16 , backupbuf,BLACK,Color_3);
num_size += ret; //字节个数

//满屏

}


}while(ret > 0);
close(ft);
return 0;
}


void LCD_S702_Font_Display_A_Word(unsigned int xpos,unsigned int ypos,char *word,unsigned int pcolor,unsigned int bcolor)
{
char Font_Buff[32];
unsigned int Font_Offset;
Font_Offset = ((*word - 0XA1)*94 + *(word+1)-0XA1) * 32; //文件偏移字节
//Flash_Read_NBytes(Font_Offset,Font_Buff,32);

char word_font[32]; //[1000];
int ret;
int ff;
ff=open("./GBK2312.DZK",O_RDONLY,0666);
if(ff<0 )
{
printf("ff文件打开失败!");
printf("我的错误:%s errno:%d \r\n",strerror(errno),errno);
}

lseek(ff,Font_Offset,SEEK_SET); //偏移
ret = read(ff,word_font,sizeof(word_font));
close(ff);

LCD_S702_Display_A_Char_word(xpos,ypos,word_font, pcolor,bcolor,Font_word_wide,Font_word_high);
//LCD_ILI9486_Display_Word(xpos,ypos,Font_Buff,pcolor,bcolor);


}

void LCD_S702_Font_Display_more(unsigned int xpos,unsigned int ypos,char *word,unsigned int pcolor,unsigned int bcolor)
{
while(*word != '\0')
{
if(*word >= 0XA1)
{

if((LCD_WIDE - xpos) < 16)
{
ypos += 16;
xpos = 0;
}
if((LCD_HIGH - ypos)<16)
{
break;
}
LCD_S702_Font_Display_A_Word(xpos,ypos,word,pcolor,bcolor);
word += 2;
xpos += 16;
}
//字母用ascii[]好,占用空间8*16,显示好看
else
{
if( *word == '\r')
{
word++;
continue;
}


if( *word == '\n')
{
xpos=0;
ypos +=16; //自定义换行
word++;
continue;
}


if((LCD_WIDE- xpos) < 8)
{
ypos += 16;
xpos = 0;
}
if((LCD_HIGH - ypos)<16)
{
break;
}
LCD_S702_Display_A_Char(xpos,ypos,*word,pcolor,bcolor);
word += 1;
xpos += 8;
}
}
}





void LCD_S702_Display_A_Char_word(unsigned int spos,unsigned int ypos,char *word ,unsigned int pcolor,unsigned int bcolor,char wide,char high)
{

unsigned int x,y;
char i;
for(y=ypos;y<ypos+high;y++)
{
i=0; //
for(x=spos;x<spos+wide;x++)
{
//画点 啄行式扫描

if( ((x-spos)%8==0 ) && (x != spos))i++; //控制宽度内移动wide=8*i

if( ( ( (word[((y-ypos)*(wide/8)+i)]) >> (7+spos+i*8-x) ) & 0X01 ) ) //高位在前
{

LCD_S702_draw_point(x,y,pcolor); //阳码
//LCD_S702_draw_point(x,y,bcolor); //阴码
}
else
{
LCD_S702_draw_point(x,y,bcolor);
//LCD_S702_draw_point(x,y,pcolor);
}
// printf("i=%d ,(y-ypos)*(wide/8)+i=%d 7+spos+i*8-x=%d\r\n",i,((y-ypos)*4+i),(7+spos+i*8-x));

}
}
}

void LCD_S702_Display_More_Chinese(unsigned int xpos,unsigned int ypos,char *word ,unsigned int Hanzi_Num,unsigned int pcolor,unsigned int bcolor,char wide,char high)
{

while( Hanzi_Num-- ) // *(word)!='\0'
{


LCD_S702_Display_A_Char_word(xpos,ypos,word,pcolor,bcolor,wide, high);

xpos+=wide;

if(xpos> (LCD_WIDE-wide) )
{
xpos=0;
ypos +=high;
}
if(ypos> (LCD_HIGH-high) )
{
break;
}
word += (wide*high/8) ;
}
}




void LCD_S702_Display_A_Char(unsigned int spos,unsigned int ypos,char A_Char, unsigned int pcolor,unsigned int bcolor)
{
//A_zifu[16] 8*16 阳码 顺高位在前 行列扫描(8位)
unsigned int x,y;
for(y=ypos;y<ypos+16;y++)
{
//ascill[]
for(x=spos;x<spos+8;x++)
{
//画点
// if( ( (A_zifu[y-ypos]>>(7+spos-x) )&0X01 ) ) //高位在前
if( ( (ascill[ (A_Char-' ')*16+y-ypos]>>(7+spos-x) )&0X01 ) ) //高位在前
{
LCD_S702_draw_point(x,y,pcolor); //阳码
//LCD_S702_draw_point(x,y,bcolor); //阴码
}
else
{
LCD_S702_draw_point(x,y,bcolor);
//LCD_S702_draw_point(x,y,pcolor);
}
}
}
}

void LCD_S702_Display_String(unsigned int xpos,unsigned int ypos, char* Str, unsigned int pcolor,unsigned int bcolor)
{
while( *Str !='\0') //'\0'=NULL ascii=0;
{
if( *Str == '\r')
{
Str++;
continue;
}


if( *Str == '\n')
{
xpos=0;
ypos +=16; //自定义换行
Str++; //下一个字母
}
LCD_S702_Display_A_Char(xpos,ypos,*Str , pcolor,bcolor);
Str++;
xpos+=8;

if(xpos>LCD_WIDE-8+1)
{
xpos=0;
ypos +=16;
}
if(ypos>LCD_HIGH-16+1)
{
break;
}
}
}




void LCD_S702_draw_point(unsigned int xpox,unsigned int ypos,unsigned int color)
{
static unsigned char *pdp_addr = NULL;
static unsigned int *pnew_32_addr = NULL;
pdp_addr = pnew_addr + (ypos*LCD_WIDE + xpox)*4;
pnew_32_addr = (unsigned int *)pdp_addr;

*pnew_32_addr = color;
}

void LCD_S702_ractangle(unsigned int x_start,unsigned int y_start,unsigned int wide,unsigned int high,unsigned int color)
{
int x,y;

for(y=y_start; y<(y_start + high); y++ )
{
for(x=x_start; x< (x_start + wide); x++ )
{
LCD_S702_draw_point( x, y, color);
}
}

}

void LCD_S702_clear(unsigned int x_start,unsigned int y_start,unsigned int x_end,unsigned int y_end,unsigned int color)
{
int x,y;

for(y=y_start; y<y_end; y++ )
{
for(x=x_start; x< x_end; x++ )
{
LCD_S702_draw_point( x, y, color);
}
}

}


//显示图片,俩个字节组成一个颜色数据 画点传组合数据<<8
void LCD_S702_Display_Picture(unsigned int sxpos,unsigned int sypos,unsigned int expos,unsigned int eypos,const unsigned char *picture)
{

unsigned int x,y;

for(y=sypos;y< (eypos ) ;y++)
{

for(x=sxpos;x< (expos);x++) // (expos+1)
{

LCD_S702_draw_point( x, y, ( ((*picture) <<16 ) | (*(picture+1)<<8) | (*(picture+2)) ) );
picture+=3;
}

//gImage_11
// LCD_ILI9486_draw_Point(unsigned int xpos,unsigned int ypos,unsigned int color)

}

}


//Bresenham算法 k>0
void LCD_S702_Bresenhamline(int x0,int y0,int x1, int y1,int color)
{
int x, y, dx, dy,e,i;

dx = x1-x0;
dy = y1- y0;
e=-dx;
x=x0;
y=y0;
for (i=0; i<dx; i++)
{
LCD_S702_draw_point(x, y, color);
x++;
e=e+2*dy;
if (e >= 0) { y++; e=e-2*dx;}
}
}

//中点法 k>0
void LCD_S702_Midpoint_Line(int x0,int y0,int x1, int y1,int color)

{ int a, b, d1, d2, d, x, y;

a=y0-y1;
b=x1-x0;
d=2*a+b;
d1=2*a;
d2=2*(a+b);
x=x0;y=y0;
LCD_S702_draw_point(x, y, color);
while (x<x1)
{
if(d<0){x++;y++; d+=d2; }
else
{x++; d+=d1;}

LCD_S702_draw_point(x, y, color);
}

} /* mid PointLine */

//画直线
void LCD_S702_draw_strline(unsigned int sxpos, unsigned int sypos, unsigned int expos, unsigned int eypos,unsigned int color)
{
unsigned int t;
int xerr=0,yerr=0,delta_x,delta_y,distance;
int incx,incy,uRow,uCol;
delta_x = expos-sxpos; //计算坐标增量
delta_y = eypos-sypos;
uRow=sxpos;
uCol=sypos;
if(delta_x>0)
{
incx=1; //设置单步方向
}
else if(delta_x==0)
{
incx=0;//垂直线
}
else
{
incx=-1;
delta_x=-delta_x;
}

if(delta_y>0)
{
incy=1;
}
else if(delta_y==0)
{
incy=0;//水平线
}
else
{
incy=-1;
delta_y=-delta_y;
}

if( delta_x>delta_y)
{
distance=delta_x; //选取基本增量坐标轴
}
else
{
distance=delta_y;
}

for(t=0;t<=distance+1;t++ )//画线输出
{
LCD_S702_draw_point(uRow,uCol,color);//画点
xerr+=delta_x ;
yerr+=delta_y ;
if(xerr>distance) //每次加1
{
xerr-=distance;
uRow+=incx;
}
if(yerr>distance) //每2次加1
{
yerr-=distance;
uCol+=incy;
}
}
}

/********************************************************************************************
* 函 数 名: LCD_ILI9486_draw_circle_8
* 描 述: LCD 画圆八点算法
* 输入参数: uint6 xc, uint6 yc, uint6 x, uint6 y, uint6 color
* 输出参数: 无
* 注意事项: 无
********************************************************************************************/
void LCD_S702_draw_circle_8(unsigned int xc, unsigned int yc, unsigned int x, unsigned int y, unsigned int color)
{
// 参数 c 为颜色值
LCD_S702_draw_point(xc + x, yc + y, color); // 7/8
LCD_S702_draw_point(xc - x, yc + y, color); // 6/8
LCD_S702_draw_point(xc + x, yc - y, color); // 2/8
LCD_S702_draw_point(xc - x, yc - y, color); // 3/8
LCD_S702_draw_point(xc + y, yc + x, color); // 8/8
LCD_S702_draw_point(xc - y, yc + x, color); // 5/8
LCD_S702_draw_point(xc + y, yc - x, color); // 1/8
LCD_S702_draw_point(xc - y, yc - x, color); // 7/8
}

/********************************************************************************************
* 函 数 名: LCD_ILI9341_draw_circle
* 描 述: LCD 画圆
* 输入参数: unsigned int xpos:X轴坐标, unsigned int ypos:Y轴坐标, unsigned int radius:半径,
* : unsigned int color:颜色, unsigned int fill_color填充颜色,char fill:是否填充
* 输出参数: 无
* 返 回 值: 无
* 注意事项: 无
********************************************************************************************/
void LCD_S702_draw_circle(unsigned int xpos, unsigned int ypos, unsigned int radius, unsigned int color,unsigned int fill_color, char fill)
{

unsigned int x = 0, y = radius, yi;
int d;

d = 3 - 2 * radius;
if(fill)
{
// 如果填充(画实心圆)
while (x <= y)
{
for (yi = x; yi <= y; yi ++)
LCD_S702_draw_circle_8(xpos, ypos, x, yi, fill_color);
if (d < 0)
{
d = d + 4 * x + 6;
}
else
{
d = d + 4 * (x - y) + 10;
y --;
}
x++;
}
}
else
{
// 如果不填充(画空心圆)
while (x <= y)
{
LCD_S702_draw_circle_8(xpos, ypos, x, y, color);
if (d < 0)
{
d = d + 4 * x + 6;
}
else
{
d = d + 4 * (x - y) + 10;
y --;
}
x ++;
}
}
}

 

猜你喜欢

转载自www.cnblogs.com/YWX888/p/9750775.html