当前位置: 首页 > wzjs >正文

500元做网站网址关键词查询网站

500元做网站,网址关键词查询网站,网站哪家做的比较好的,成立投资公司需要什么条件Linux驱动-①电容屏②音频③CAN通信 一,电容屏触摸屏1.GT9147芯片驱动 二,音频2.1 I2S总线2.2 --hostarm-linux-gnueabihf 三,CAN通信3.1 CAN3.2 UART/CAN为什么不需要设备驱动,而SPI和I2C需要 一,电容屏触摸屏 1.GT9…

Linux驱动-①电容屏②音频③CAN通信

  • 一,电容屏触摸屏
    • 1.GT9147芯片驱动
  • 二,音频
    • 2.1 I2S总线
    • 2.2 --host=arm-linux-gnueabihf
  • 三,CAN通信
    • 3.1 CAN
    • 3.2 UART/CAN为什么不需要设备驱动,而SPI和I2C需要

一,电容屏触摸屏

1.GT9147芯片驱动

  电容触摸屏内部芯片采用的传输方式为I2C通信,因此总线驱动已经有了,要写的是电容触摸屏GT9147的驱动,包括根据电路连接方式,对设备树进行修改,将其挂载到I2C2节点上,设置好各个属性。触摸方式有单点触摸和多点触摸:
  ①单点触摸,仅支持一个触摸点,比如只能一个手指去触摸,同时放第二个手指,第二个手指触摸信息没反应。检测到 一个触点 后,会更新其寄存器中的坐标数据,通过INT引脚触发中断,通知主机读取数据。上报一个点,就相当于把此轮信息上报完了,就会发一个sync信号,然后继续上报下一个信息。(比如手划过后,会有1,2,3,4,5,点信息,上报完1,给一个sync,再上报2,再给一个sync信号…)

// 单点触控上报(仅X/Y坐标)
input_report_abs(input_dev, ABS_X, x_pos);
input_report_abs(input_dev, ABS_Y, y_pos);
input_sync(input_dev);

  ②多点触摸,可以检测多个手指触摸信息,比如五个手指同时触摸,1号手指触摸1.1,1.2-1.5点,2号手指触摸2.1-2.6点,3号手指触摸3.1-3.3点…,当上报时,会依次先报1号手指1.1,2号手指2.1点,3号手指3.1,4号手指4.1点,5号手指5.1点,信息进行上报,然后发送一个sync信号,继续把*.2点信息上报,发送sync信号。GT9147 会按顺序更新所有触点的寄存器(如触点1在 0x8140~0x8147,触点2在 0x8148~0x814F,依此类推)。所有有效触点的信息会被 一次性读取,然后通过输入子系统上报。

// 遍历所有触点(GT9147 支持最多5点)
for (i = 0; i < max_touches; i++) {status = read_reg(0x8140 + i * 8); // 触点状态if (status & TOUCH_ACTIVE) {x = read_reg(0x8140 + i * 8 + 2); // X坐标y = read_reg(0x8140 + i * 8 + 4); // Y坐标// 上报单个触点input_mt_slot(input_dev, i); // 选择触点槽input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, true);input_report_abs(input_dev, ABS_MT_POSITION_X, x);input_report_abs(input_dev, ABS_MT_POSITION_Y, y);} else {// 触点释放input_mt_slot(input_dev, i);input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, false);}
}
input_sync(input_dev); // 所有触点上报完成后发送 SYN_REPORT

  采用的是typeB方式,相当于每次将触摸点变成一个slot,用这个slot来上报触摸点的信息,slot其中的内容包括,第几个点,ID,x轴和y轴的坐标值,完成所有点的上报后,上报一个sync信息,这个作用感觉就是把信息之间给间隔起来,有个分页符。
  **总体流程:**当触摸后,触发了中断,进入中断处理函数中,先设置出了slot即id,第几次按到了,然后设置其state状态,虽然在前面,但是这些数据要先放到内核的缓冲区中,这个函数的上下和最终数据输出并不是一样的顺序,然后上报x y值,然后调用这个sync一下,就是发送数据,然后当触摸屏释放,还会触发一次中断,从而引起 input_mt_slot(dev->input, id); input_mt_report_slot_state(dev->input, MT_TOOL_FINGER, false)。
驱动:

/*4.1日内容主要有i2c,中断,input结构,电容屏反馈原理*/
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/gpio/consumer.h>
#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/input/mt.h>
#include <linux/input/touchscreen.h>
#include <linux/i2c.h>
#include <asm/unaligned.h>
#define LCD_NAME "lcd"#define GT_CTRL_REG 	        0X8040  /* GT9147控制寄存器         */
#define GT_MODSW_REG 	        0X804D  /* GT9147模式切换寄存器        */
#define GT_9xx_CFGS_REG 	        0X8047  /* GT9147配置起始地址寄存器    */
#define GT_1xx_CFGS_REG 	        0X8050  /* GT1151配置起始地址寄存器    */
#define GT_CHECK_REG 	        0X80FF  /* GT9147校验和寄存器       */
#define GT_PID_REG 		        0X8140  /* GT9147产品ID寄存器       */#define GT_GSTID_REG 	        0X814E  /* GT9147当前检测到的触摸情况 */
#define GT_TP1_REG 		        0X814F  /* 第一个触摸点数据地址 */
#define GT_TP2_REG 		        0X8157	/* 第二个触摸点数据地址 */
#define GT_TP3_REG 		        0X815F  /* 第三个触摸点数据地址 */
#define GT_TP4_REG 		        0X8167  /* 第四个触摸点数据地址  */
#define GT_TP5_REG 		        0X816F	/* 第五个触摸点数据地址   */
#define MAX_SUPPORT_POINTS      5       /* 最多5点电容触摸 */const u8 irq_table[] = {IRQ_TYPE_EDGE_RISING, IRQ_TYPE_EDGE_FALLING, IRQ_TYPE_LEVEL_LOW, IRQ_TYPE_LEVEL_HIGH};  /* 触发方式 */
struct lcd_dev{int irqtype; //中断类型int ret_pin,irq_pin;struct device dev;struct input_dev *input;	/* input结构体 */struct i2c_client *client;};
struct lcd_dev lcd;static int lcd_read_regs(struct lcd_dev *dev,u16 reg,u8 *buf ,int len)
{int ret;u8 reg_adress[2]={0};struct i2c_client *client = lcd.client;//传递数据struct i2c_msg msg[2];reg_adress[0] = reg >> 8;reg_adress[1] = reg & 0xff;msg[0].addr  = client->addr;//设备地址msg[0].flags = 0;//写操作msg[0].len   = 2;msg[0].buf   = reg_adress;msg[1].addr  = client->addr;//设备地址msg[1].flags = I2C_M_RD;//读msg[1].len   = len;//这样就能连续读数据msg[1].buf   = buf;ret = i2c_transfer(client->adapter, msg, 2);if (ret < 0) {printk(KERN_ERR "error %d\n", ret);ret = -EREMOTEIO;}else ret = 0;return ret;
}
static void lcd_write_regs(struct lcd_dev *dev,u16 reg,u8 *buf,u8 len)
{u8 b[6];struct i2c_client *client = lcd.client;//传递数据struct i2c_msg msg[1];b[0] = reg >> 8;//寄存器地址b[1] = reg & 0xff;memcpy(&b[2],buf,len);//每次写入一个数据msg[0].addr  = client->addr;//设备地址msg[0].flags = 0;//写操作msg[0].len   = len+2;//长度为2msg[0].buf   = b;//b中放的先是寄存器地址,后面是数据i2c_transfer(client->adapter, msg, 1);
}
// static void lcd_write_reg(struct lcd_dev *dev,u16 reg,u8 data)
// {
//     lcd_write_regs(&lcd,reg,&data,1);
// }
// static int gt9147_read_firmware(struct i2c_client *client, struct lcd_dev *dev)
// {
// 	int ret = 0, version = 0;
// 	u16 id = 0;
// 	u8 data[7]={0};
// 	char id_str[5];
// 	ret = lcd_read_regs(dev, GT_PID_REG, data, 6);
// 	if (ret) {
// 		dev_err(&client->dev, "Unable to read PID.\n");
// 		return ret;
// 	}
// 	memcpy(id_str, data, 4);
// 	id_str[4] = 0;
//     if (kstrtou16(id_str, 10, &id))
//         id = 0x1001;
// 	version = get_unaligned_le16(&data[4]);
// 	dev_info(&client->dev, "ID %d, version: %04x\n", id, version);
// 	switch (id) {    /* 由于不同的芯片配置寄存器地址不一样需要判断一下  */
//     case 1151:
//     case 1158:
//     case 5663:
//     case 5688:    /* 读取固件里面的配置信息  */
//         ret = lcd_read_regs(dev, GT_1xx_CFGS_REG, data, 7);  
// 		break;
//     default:
//         ret = lcd_read_regs(dev, GT_9xx_CFGS_REG, data, 7);
// 		break;
//     }
// 	if (ret) {
// 		dev_err(&client->dev, "Unable to read Firmware.\n");
// 		return ret;
// 	}
// 	// dev->max_x = (data[2] << 8) + data[1];
// 	// dev->max_y = (data[4] << 8) + data[3];
// 	dev->irqtype = data[6] & 0x3;
// 	printk("irq type  = %d\r\n", dev->irqtype);
// 	return 0;
// }
static irqreturn_t lcd_irq_handler(int irq,void *dev_id)
{int touch_num = 0;int input_x, input_y;int id = 0;int ret = 0;u8 data;u8 touch_data[5];struct lcd_dev *dev = (struct lcd_dev *)dev_id;    ret = lcd_read_regs(dev,GT_GSTID_REG,&data,1);if(data!=0){touch_num = data & 0x0f;}else {goto irq_fail;}if(touch_num){lcd_read_regs(dev,GT_TP1_REG,touch_data,5);id = touch_data[0] & 0x0f;if(id == 0){input_x  = touch_data[1] | (touch_data[2] << 8);input_y  = touch_data[3] | (touch_data[4] << 8);input_mt_slot(dev->input, id);input_mt_report_slot_state(dev->input, MT_TOOL_FINGER, true);input_report_abs(dev->input, ABS_MT_POSITION_X, input_x);input_report_abs(dev->input, ABS_MT_POSITION_Y, input_y);            }}else if(touch_num ==0){input_mt_slot(dev->input, id);input_mt_report_slot_state(dev->input, MT_TOOL_FINGER, false);}input_mt_report_pointer_emulation(dev->input, true);input_sync(dev->input);data = 0x00;                /* 向0X814E寄存器写0 */lcd_write_regs(dev, GT_GSTID_REG, &data, 1);
irq_fail:    return IRQ_HANDLED;      // 中断已处理
}
static int lcd_probe(struct i2c_client *client, const struct i2c_device_id *id)
{int ret = 0;u8 data;//u8  *reslu = NULL;lcd.client = client;/*1.中断以及引脚*/lcd.irq_pin = of_get_named_gpio(client->dev.of_node,"interrupt-gpios", 0);lcd.ret_pin = of_get_named_gpio(client->dev.of_node,"reset-gpios", 0);if(!lcd.irq_pin||! lcd.ret_pin){printk("get gpio error !\r\n");}ret = devm_gpio_request_one(&client->dev,lcd.irq_pin,GPIOF_OUT_INIT_HIGH,"lcd_irq");if(ret<0){printk("gpio request error !\r\n");}/*复位*/ret = devm_gpio_request_one(&client->dev,lcd.ret_pin, GPIOF_OUT_INIT_HIGH,"ret_pin");if(ret<0){printk("ret  request error !\r\n");}gpio_set_value(lcd.ret_pin,0);msleep(10);gpio_set_value(lcd.ret_pin,1);msleep(10);gpio_set_value(lcd.irq_pin,0);msleep(50);gpio_direction_input(lcd.irq_pin);  /*2.初始化lcd*/data = 0x02;lcd_write_regs(&lcd,GT_CTRL_REG,&data,1);mdelay(100);// lcd_read_regs(&lcd,GT_CTRL_REG,reslu,1);// printk("read data = %d\r\n",reslu[0]);data = 0;lcd_write_regs(&lcd,GT_CTRL_REG, &data,1);mdelay(100); /*3.input初始化及注册*/// ret = gt9147_read_firmware(client, &lcd);// if(ret!=0)// {//     printk("firmware error\r\n");// }lcd.input = devm_input_allocate_device(&client->dev);lcd.input->name = client->name;lcd.input->id.bustype = BUS_I2C;lcd.input->dev.parent = &client->dev;//还是不太懂,为什么要加parent__set_bit(EV_KEY,lcd.input->evbit);__set_bit(EV_ABS,lcd.input->evbit);__set_bit(BTN_TOUCH,lcd.input->keybit);input_set_abs_params(lcd.input,ABS_X,0,800,0,0);input_set_abs_params(lcd.input,ABS_Y,0,480,0,0);input_set_abs_params(lcd.input,ABS_MT_POSITION_X,0,800,0,0);input_set_abs_params(lcd.input,ABS_MT_POSITION_Y,0,480,0,0);ret =  input_mt_init_slots(lcd.input, MAX_SUPPORT_POINTS, 0);if(ret<0){printk("input_mt_init_slots error !\r\n");}ret = input_register_device(lcd.input); /*client->irq表示这是i2c引起的中断*/ret = devm_request_threaded_irq(&client->dev,client->irq,NULL,lcd_irq_handler,IRQ_TYPE_EDGE_FALLING| IRQF_ONESHOT ,client->name, &lcd);if(ret<0){printk("irq request error !\r\n");} printk("probe probe probe  !\r\n");  return ret;
}static int lcd_remove(struct i2c_client *client)
{input_unregister_device(lcd.input);return 0;
}
static const struct i2c_device_id lcd_id[] = {{ "www", 0 },{ }
};
const struct of_device_id	lcd_of_match[]={{.compatible = "wyt,lcd"},{ /*sentinel*/ },
};
static struct i2c_driver lcd_driver = {.probe		= lcd_probe,.remove		= lcd_remove,.driver		= {.owner = THIS_MODULE,.name	= "lcd666",//1.无设备树,匹配名字.of_match_table = lcd_of_match,//2.有设备树,直接利用设备树中compatible属性},.id_table = lcd_id,
};
static int __init lcd_init(void)
{ int ret = 0;ret = i2c_add_driver(&lcd_driver);return ret;
}
static void  __exit lcd_exit(void)
{i2c_del_driver(&lcd_driver);  
}/*驱动入口和出口*/
module_init(lcd_init);
module_exit(lcd_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("wyt");

二,音频

2.1 I2S总线

  同步串行通信,全双工,用于控制音频,三根基本线SCK,WS,SD,可选MCLK,主模式下,主设备提供时钟,从设备同步接收。SCLK:位时钟,频率=采样率 × 位数 × 通道数。WS:字选择(Word Select)/左右声道时钟,0=左声道,1=右声道。SD:串行数据(Serial Data),传输 PCM 样本。MCLK:主时钟,提供系统参考时钟。
在这里插入图片描述

2.2 --host=arm-linux-gnueabihf

–host:指定编译生成的代码在哪个平台上运行(目标平台)。
arm:目标 CPU 架构为 ARM(如树莓派、嵌入式开发板等)。
linux:目标操作系统为 Linux。
gnueabihf ABI 类型:GNU 嵌入式应用二进制接口,支持硬件浮点(Hard-Float)加速。

三,CAN通信

3.1 CAN

在这里插入图片描述
  CAN使用消息ID区分不同的数据帧,不是设备地址,相当于给每个ID设置一种类型,比如0X100表示发动机转速,0x200表示刹车,CAN设备有自己的过滤器,比如单元1想往单元二发消息,单元二只接受ID为0x200的数据,其他的就会过滤掉。其次是优先级,当多个单元同时工作,谁发出去的ID号越小,优先级越高。
  CAN 协议提供了 5 种帧格式来传输数据:数据帧、遥控帧、错误帧、过载帧和帧间隔。数据帧:①、帧起始,表示数据帧开始的段。②、仲裁段,表示该帧优先级的段。③、控制段,表示数据的字节数及保留位的段。④、数据段,数据的内容,一帧可发送 0~8 个字节的数据。⑤、CRC 段,检查帧的传输错误的段。⑥、ACK 段,表示确认正常接收的段。⑦、帧结束,表示数据帧结束的段。

在这里插入图片描述
  异步串行通信(异步是因为没有时钟线),差分信号CAN_H/CAN_L,,CAN 总线电平分为显性电平和隐性电平两种。显性电平表示逻辑“0”,此时 CAN_H 电平比 CAN_L 高,分别为 3.5V 和 1.5V,电位差为 2V。隐形电平表示逻辑“1”,此时 CAN_H 和 CAN_L 电压都为 2.5V 左右,电位差为 0V。

3.2 UART/CAN为什么不需要设备驱动,而SPI和I2C需要

  RS485,422,232最后都要归属到UART驱动,CAN通信采用单独的驱动框架,这两种驱动框架,无论什么设备,都直接用这个驱动就行,不需要额外再写设备的驱动,因为UART/CAN设备简单,直接读取数据就行,设置一下波特率,传输速率就行了,I2C和SPI不一样,设备复杂,不同设备有不同的寄存器访问方式,需要设置设备驱动。

http://www.dtcms.com/wzjs/326263.html

相关文章:

  • 男生女生一起嗟嗟嗟很痛真人seo排名工具
  • 网站开发微信公众号自定义菜单北京网优化seo公司
  • 网站怎么做关键词排名宁波搜索引擎优化seo
  • 成立公司股份怎么分配seo推广专员
  • 建设网站的服务费是指什么代发软文
  • 花钱做推广广告哪个网站好网址搜索
  • 专业做网站的人软文怎么写
  • 济南市城乡建设委网站正规的网店培训机构有哪些
  • 做网站的项目流程seo怎么做优化排名
  • 徐东网站建设百度推广用户注册
  • 佛山网站设计制作免费咨询百度推广关键词怎么设置好
  • 四川省建设厅网站官网成都网站建设seo
  • 南安市城乡住房建设局网站hs网站推广
  • 山东省德州市疫情最新消息正规seo一般多少钱
  • 济南做网站维护的公司推广引流方法与渠道
  • 做淘宝团购的网站免费推广的途径与原因
  • 北京 网站设计 公司重庆公司网站seo
  • 商贸公司的网站建设小程序seo推广技巧
  • 赣州市人才网招聘信息查询信息宁波网站seo诊断工具
  • 深圳住房网站app关键词查询网站
  • WordPress的手机菜单键抖音搜索排名优化
  • win7本地做网站seo网站平台
  • 怎么给公司做个网站爱营销电信版下载app最新版
  • 学校网站怎么做小程序开发文档
  • 海参企业网站怎么做百度认证平台
  • wordpress 自定义排序seo优化流程
  • 容城网站建设做任务赚佣金一单10块
  • 广州活动网站设计营销软文范例大全
  • 武进网站建设优化百度seo
  • html网站源码下载服务器