• 售前

  • 售后

热门帖子
入门百科

Linux驱动开发+QT应用编程实现IIC读取ap3216c

[复制链接]
yfyffuuy 显示全部楼层 发表于 2022-8-13 22:33:54 |阅读模式 打印 上一主题 下一主题
Linux驱动开发:IIC驱动开发
Linux I2C驱动框架的简介

bsp_i2c.c 称之为 主机驱动,写完不必要修改。
bsp_ap3216c.c称之为装备驱动,根据主机驱动适配到装备上。
Linux内核将IIC驱动分为


  • IIC总线驱动:总线驱动等同于裸机中的IIC主机驱动,这里叫IIC适配器驱动
  • IIC装备驱动:装备驱动就是针对ap3216c专门编写的驱动。
1、IIC读写代码示例(紧张)

利用 i2c_transfer 函数发送数据之前要先构建好 i2c_msg,利用 i2c_transfer 举行 I2C 数据收发的示例代码如下:
  1. /* 设备结构体 */
  2. struct xxx_dev {
  3.                 ......
  4.                 void *private_data; /* 私有数据,一般会设置为 i2c_client */
  5. };
  6. /*
  7. * @description : 读取 I2C 设备多个寄存器数据
  8. * @param – dev : I2C 设备
  9. * @param – reg : 要读取的寄存器首地址
  10. * @param – val : 读取到的数据
  11. * @param – len : 要读取的数据长度
  12. * @return : 操作结果
  13. */
  14. static int xxx_read_regs(struct xxx_dev *dev, u8 reg, void *val,int len)
  15. {
  16.                 int ret;
  17.                 struct i2c_msg msg[2];
  18.                 struct i2c_client *client = (struct i2c_client *)
  19.                 dev->private_data;
  20.                 /* msg[0],第一条写消息,发送要读取的寄存器首地址 */
  21.                 msg[0].addr = client->addr; /* I2C 器件地址 */
  22.                 msg[0].flags = 0; /* 标记为发送数据 */
  23.                 msg[0].buf = ® /* 读取的首地址 */
  24.                 msg[0].len = 1; /* reg 长度 */
  25.                 /* msg[1],第二条读消息,读取寄存器数据 */
  26.                 msg[1].addr = client->addr; /* I2C 器件地址 */
  27.                 msg[1].flags = I2C_M_RD; /* 标记为读取数据 */
  28.                 msg[1].buf = val; /* 读取数据缓冲区 */
  29.                 msg[1].len = len; /* 要读取的数据长度 */
  30.                 ret = i2c_transfer(client->adapter, msg, 2);
  31.                 if(ret == 2) {
  32.                                 ret = 0;
  33.                 } else {
  34.                                 ret = -EREMOTEIO;
  35.                 }
  36.                 return ret;
  37. }
  38. /*
  39. * @description : 向 I2C 设备多个寄存器写入数据
  40. * @param – dev : 要写入的设备结构体
  41. * @param – reg : 要写入的寄存器首地址
  42. * @param – buf : 要写入的数据缓冲区
  43. * @param – len : 要写入的数据长度
  44. * @return : 操作结果
  45. */
  46. static s32 xxx_write_regs(struct xxx_dev *dev, u8 reg, u8 *buf,u8 len)
  47. {
  48.                 u8 b[256];
  49.                 struct i2c_msg msg;
  50.                 struct i2c_client *client = (struct i2c_client *)
  51.                 dev->private_data;
  52.                
  53.                 b[0] = reg; /* 寄存器首地址 */
  54.                 memcpy(&b[1],buf,len); /* 将要发送的数据拷贝到数组 b 里面 */
  55.                
  56.                 msg.addr = client->addr; /* I2C 器件地址 */
  57.                 msg.flags = 0; /* 标记为写数据 */
  58.                
  59.                 msg.buf = b; /* 要发送的数据缓冲区 */
  60.                 msg.len = len + 1; /* 要发送的数据长度 */
  61.                
  62.                 return i2c_transfer(client->adapter, &msg, 1);
  63. }
复制代码
别的两个API函数分别用于I2C数据的收发操纵,这两个函数终极都会调用i2c_transfer。
函数原型如下:
  1. int i2c_master_send(const struct i2c_client *client, const char *buf, int count)
  2. 函数参数和返回值含义如下:
  3. client:I2C 设备对应的 i2c_client。
  4. buf:要发送的数据。
  5. count:要发送的数据字节数,要小于 64KB,以为 i2c_msg 的 len 成员变量是一个 u16(无符号 16 位)类型的数据。
  6. 返回值:负值,失败,其他非负值,发送的字节数。
复制代码
I2C 数据汲取函数为 i2c_master_recv,函数原型如下:
  1. int i2c_master_recv(const struct i2c_client *client, char *buf, int count)
  2. 函数参数和返回值含义如下:
  3. client:I2C 设备对应的 i2c_client。
  4. buf:要接收的数据。
  5. count:要接收的数据字节数,要小于 64KB,以为 i2c_msg 的 len 成员变量是一个 u16(无符号 16 位)类型的数据。
  6. 返回值:负值,失败,其他非负值,发送的字节数。
复制代码
2、i2c_driver 的装备树注册示例代码如下:

  1. i2c 驱动的 probe 函数
  2. static int xxx_probe(struct i2c_client *client,const struct i2c_device_id *id)
  3. {
  4.          /* 函数具体程序 */
  5.         return 0;
  6. }
  7. i2c 驱动的 remove 函数
  8. static int xxx_remove(struct i2c_client *client)
  9. {
  10.         函数具体程序
  11.          return 0;
  12. }
  13. 设备树匹配列表
  14. static const struct of_device_id xxx_of_match[] = {
  15. { .compatible = "xxx" },
  16. { /* Sentinel */ }
  17. };
  18. i2c 驱动结构体
  19. static struct i2c_driver xxx_driver = {
  20.                 .probe = xxx_probe,
  21.                 .remove = xxx_remove,
  22.                 .driver = {
  23.                 .owner = THIS_MODULE,
  24.                 .name = "xxx",
  25.                 .of_match_table = xxx_of_match,
  26.                 },
  27.                 .id_table = xxx_id,
  28. };
  29. 驱动入口函数
  30. static int __init xxx_init(void)
  31. {
  32.                 int ret = 0;
  33.                 ret = i2c_add_driver(&xxx_driver);
  34.                 return ret;
  35. }
  36. 驱动出口函数
  37. static void __exit xxx_exit(void)
  38. {
  39.         i2c_del_driver(&xxx_driver);
  40. }
  41. module_init(xxx_init);
  42. module_exit(xxx_exit);
复制代码


  • of_device_id,装备树所利用的匹配表。
  • i2c_driver,当 I2C 装备和 I2C 驱动匹配乐成以后 probe 函数就会实行,这些和 platform 驱动一样,probe函数内里根本就是标准的字符装备驱动那一套了。
ap3216c驱动开发

1、修改装备树,pinctrl子节点添加装备的电气属性,设置GPIO而且设置电气属性:

pinctrl_i2c1 就是 I2C1 的 IO 节点,这里将 UART4_TXD 和 UART4_RXD 这两个 IO 分别复用为 I2C1_SCL 和 I2C1_SDA,电气属性都设置为 0x4001b8b0。
2、在 i2c1 节点追加 ap3216c 子节点
  1. &i2c1 {
  2.         clock-frequency = <100000>;
  3.         pinctrl-names = "default";
  4.         pinctrl-0 = <&pinctrl_i2c1>;
  5.         status = "okay";
  6.         ap3216c@1e {
  7.                 compatible = "alientek,ap3216c";
  8.                 reg = <0x1e>;
  9.         };
  10. };
复制代码
结果:

寄存器所在:
  1. #ifndef AP3216C_H
  2. #define AP3216C_H
  3. #define AP3216C_ADDR            0X1E        /* AP3216C器件地址  */
  4. /* AP3316C寄存器 */
  5. #define AP3216C_SYSTEMCONG        0x00        /* 配置寄存器       */
  6. #define AP3216C_INTSTATUS        0X01        /* 中断状态寄存器   */
  7. #define AP3216C_INTCLEAR        0X02        /* 中断清除寄存器   */
  8. #define AP3216C_IRDATALOW        0x0A        /* IR数据低字节     */
  9. #define AP3216C_IRDATAHIGH        0x0B        /* IR数据高字节     */
  10. #define AP3216C_ALSDATALOW        0x0C        /* ALS数据低字节    */
  11. #define AP3216C_ALSDATAHIGH        0X0D        /* ALS数据高字节    */
  12. #define AP3216C_PSDATALOW        0X0E        /* PS数据低字节     */
  13. #define AP3216C_PSDATAHIGH        0X0F        /* PS数据高字节     */
  14. #endif
复制代码
驱动代码:
  1. #include <linux/types.h>
  2. #include <linux/kernel.h>
  3. #include <linux/delay.h>
  4. #include <linux/ide.h>
  5. #include <linux/init.h>
  6. #include <linux/module.h>
  7. #include <linux/errno.h>
  8. #include <linux/gpio.h>
  9. #include <linux/cdev.h>
  10. #include <linux/device.h>
  11. #include <linux/of_gpio.h>
  12. #include <linux/semaphore.h>
  13. #include <linux/timer.h>
  14. #include <linux/i2c.h>
  15. #include <asm/mach/map.h>
  16. #include <asm/uaccess.h>
  17. #include <asm/io.h>
  18. #include "ap3216creg.h"
  19. #define AP3216C_CNT        1
  20. #define AP3216C_NAME        "ap3216c"
  21. struct ap3216c_dev {
  22.         dev_t devid;                        /* 设备号          */
  23.         struct cdev cdev;                /* cdev         */
  24.         struct class *class;        /* 类                 */
  25.         struct device *device;        /* 设备          */
  26.         struct device_node        *nd; /* 设备节点 */
  27.         int major;                        /* 主设备号 */
  28.         void *private_data;        /* 私有数据 */
  29.         unsigned short ir, als, ps;                /* 三个光传感器数据 */
  30. };
  31. static struct ap3216c_dev ap3216cdev;
  32. /*
  33. * @description        : 从ap3216c读取多个寄存器数据
  34. * @param - dev:  ap3216c设备
  35. * @param - reg:  要读取的寄存器首地址
  36. * @param - val:  读取到的数据
  37. * @param - len:  要读取的数据长度
  38. * @return                 : 操作结果
  39. */
  40. static int ap3216c_read_regs(struct ap3216c_dev *dev, u8 reg, void *val, int len)
  41. {
  42.         int ret;
  43.         struct i2c_msg msg[2];
  44.         struct i2c_client *client = (struct i2c_client *)dev->private_data;
  45.         /* msg[0]为发送要读取的首地址 */
  46.         msg[0].addr = client->addr;                        /* ap3216c地址 */
  47.         msg[0].flags = 0;                                        /* 标记为发送数据 */
  48.         msg[0].buf = ®                                        /* 读取的首地址 */
  49.         msg[0].len = 1;                                                /* reg长度*/
  50.         /* msg[1]读取数据 */
  51.         msg[1].addr = client->addr;                        /* ap3216c地址 */
  52.         msg[1].flags = I2C_M_RD;                        /* 标记为读取数据*/
  53.         msg[1].buf = val;                                        /* 读取数据缓冲区 */
  54.         msg[1].len = len;                                        /* 要读取的数据长度*/
  55.         ret = i2c_transfer(client->adapter, msg, 2);
  56.         if(ret == 2) {
  57.                 ret = 0;
  58.         } else {
  59.                 printk("i2c rd failed=%d reg=%06x len=%d\n",ret, reg, len);
  60.                 ret = -EREMOTEIO;
  61.         }
  62.         return ret;
  63. }
  64. /*
  65. * @description        : 向ap3216c多个寄存器写入数据
  66. * @param - dev:  ap3216c设备
  67. * @param - reg:  要写入的寄存器首地址
  68. * @param - val:  要写入的数据缓冲区
  69. * @param - len:  要写入的数据长度
  70. * @return           :   操作结果
  71. */
  72. static s32 ap3216c_write_regs(struct ap3216c_dev *dev, u8 reg, u8 *buf, u8 len)
  73. {
  74.         u8 b[256];
  75.         struct i2c_msg msg;
  76.         struct i2c_client *client = (struct i2c_client *)dev->private_data;
  77.        
  78.         b[0] = reg;                                        /* 寄存器首地址 */
  79.         memcpy(&b[1],buf,len);                /* 将要写入的数据拷贝到数组b里面 */
  80.                
  81.         msg.addr = client->addr;        /* ap3216c地址 */
  82.         msg.flags = 0;                                /* 标记为写数据 */
  83.         msg.buf = b;                                /* 要写入的数据缓冲区 */
  84.         msg.len = len + 1;                        /* 要写入的数据长度 */
  85.         //msg 的 len 为 len+1,因为要加上一个字节的寄存器地址。
  86.         return i2c_transfer(client->adapter, &msg, 1);
  87. }
  88. /*
  89. * @description        : 读取ap3216c指定寄存器值,读取一个寄存器
  90. * @param - dev:  ap3216c设备
  91. * @param - reg:  要读取的寄存器
  92. * @return           :   读取到的寄存器值
  93. */
  94. static unsigned char ap3216c_read_reg(struct ap3216c_dev *dev, u8 reg)
  95. {
  96.         u8 data = 0;
  97.         ap3216c_read_regs(dev, reg, &data, 1);
  98.         return data;
  99. #if 0
  100.         struct i2c_client *client = (struct i2c_client *)dev->private_data;
  101.         return i2c_smbus_read_byte_data(client, reg);
  102. #endif
  103. }
  104. /*
  105. * @description        : 向ap3216c指定寄存器写入指定的值,写一个寄存器
  106. * @param - dev:  ap3216c设备
  107. * @param - reg:  要写的寄存器
  108. * @param - data: 要写入的值
  109. * @return   :    无
  110. */
  111. static void ap3216c_write_reg(struct ap3216c_dev *dev, u8 reg, u8 data)
  112. {
  113.         u8 buf = 0;
  114.         buf = data;
  115.         ap3216c_write_regs(dev, reg, &buf, 1);
  116. }
  117. /*
  118. * @description        : 读取AP3216C的数据,读取原始数据,包括ALS,PS和IR, 注意!
  119. *                                : 如果同时打开ALS,IR+PS的话两次数据读取的时间间隔要大于112.5ms
  120. * @param - ir        : ir数据
  121. * @param - ps         : ps数据
  122. * @param - ps         : als数据
  123. * @return                 : 无。
  124. */
  125. void ap3216c_readdata(struct ap3216c_dev *dev)
  126. {
  127.         unsigned char i =0;
  128.     unsigned char buf[6];
  129.        
  130.         /* 循环读取所有传感器数据 */
  131.     for(i = 0; i < 6; i++)       
  132.     {
  133.         buf[i] = ap3216c_read_reg(dev, AP3216C_IRDATALOW + i);       
  134.     }
  135.     if(buf[0] & 0X80)         /* IR_OF位为1,则数据无效 */
  136.                 dev->ir = 0;                                       
  137.         else                                 /* 读取IR传感器的数据                   */
  138.                 dev->ir = ((unsigned short)buf[1] << 2) | (buf[0] & 0X03);                        
  139.        
  140.         dev->als = ((unsigned short)buf[3] << 8) | buf[2];        /* 读取ALS传感器的数据                          */  
  141.        
  142.     if(buf[4] & 0x40)        /* IR_OF位为1,则数据无效                         */
  143.                 dev->ps = 0;                                                                                                           
  144.         else                                 /* 读取PS传感器的数据    */
  145.                 dev->ps = ((unsigned short)(buf[5] & 0X3F) << 4) | (buf[4] & 0X0F);
  146. }
  147. /*
  148. * @description                : 打开设备
  149. * @param - inode         : 传递给驱动的inode
  150. * @param - filp         : 设备文件,file结构体有个叫做private_data的成员变量
  151. *                                           一般在open的时候将private_data指向设备结构体。
  152. * @return                         : 0 成功;其他 失败
  153. */
  154. static int ap3216c_open(struct inode *inode, struct file *filp)
  155. {
  156.         filp->private_data = &ap3216cdev;
  157.         /* 初始化AP3216C */
  158.         ap3216c_write_reg(&ap3216cdev, AP3216C_SYSTEMCONG, 0x04);                /* 复位AP3216C                         */
  159.         mdelay(50);                                                                                                                /* AP3216C复位最少10ms         */
  160.         ap3216c_write_reg(&ap3216cdev, AP3216C_SYSTEMCONG, 0X03);                /* 开启ALS、PS+IR                 */
  161.         return 0;
  162. }
  163. /*
  164. * @description                : 从设备读取数据
  165. * @param - filp         : 要打开的设备文件(文件描述符)
  166. * @param - buf         : 返回给用户空间的数据缓冲区
  167. * @param - cnt         : 要读取的数据长度
  168. * @param - offt         : 相对于文件首地址的偏移
  169. * @return                         : 读取的字节数,如果为负值,表示读取失败
  170. */
  171. static ssize_t ap3216c_read(struct file *filp, char __user *buf, size_t cnt, loff_t *off)
  172. {
  173.         short data[3];
  174.         long err = 0;
  175.         struct ap3216c_dev *dev = (struct ap3216c_dev *)filp->private_data;
  176.        
  177.         ap3216c_readdata(dev);
  178.         data[0] = dev->ir;
  179.         data[1] = dev->als;
  180.         data[2] = dev->ps;
  181.         err = copy_to_user(buf, data, sizeof(data));
  182.         return 0;
  183. }
  184. /*
  185. * @description                : 关闭/释放设备
  186. * @param - filp         : 要关闭的设备文件(文件描述符)
  187. * @return                         : 0 成功;其他 失败
  188. */
  189. static int ap3216c_release(struct inode *inode, struct file *filp)
  190. {
  191.         return 0;
  192. }
  193. /* AP3216C操作函数 */
  194. static const struct file_operations ap3216c_ops = {
  195.         .owner = THIS_MODULE,
  196.         .open = ap3216c_open,
  197.         .read = ap3216c_read,
  198.         .release = ap3216c_release,
  199. };
  200. /*
  201.   * @description     : i2c驱动的probe函数,当驱动与
  202.   *                    设备匹配以后此函数就会执行
  203.   * @param - client  : i2c设备
  204.   * @param - id      : i2c设备ID
  205.   * @return          : 0,成功;其他负值,失败
  206.   */
  207. static int ap3216c_probe(struct i2c_client *client, const struct i2c_device_id *id)
  208. {
  209.         /* 1、构建设备号 */
  210.         if (ap3216cdev.major) {
  211.                 ap3216cdev.devid = MKDEV(ap3216cdev.major, 0);
  212.                 register_chrdev_region(ap3216cdev.devid, AP3216C_CNT, AP3216C_NAME);
  213.         } else {
  214.                 alloc_chrdev_region(&ap3216cdev.devid, 0, AP3216C_CNT, AP3216C_NAME);
  215.                 ap3216cdev.major = MAJOR(ap3216cdev.devid);
  216.         }
  217.         /* 2、注册设备 */
  218.         cdev_init(&ap3216cdev.cdev, &ap3216c_ops);
  219.         cdev_add(&ap3216cdev.cdev, ap3216cdev.devid, AP3216C_CNT);
  220.         /* 3、创建类 */
  221.         ap3216cdev.class = class_create(THIS_MODULE, AP3216C_NAME);
  222.         if (IS_ERR(ap3216cdev.class)) {
  223.                 return PTR_ERR(ap3216cdev.class);
  224.         }
  225.         /* 4、创建设备 */
  226.         ap3216cdev.device = device_create(ap3216cdev.class, NULL, ap3216cdev.devid, NULL, AP3216C_NAME);
  227.         if (IS_ERR(ap3216cdev.device)) {
  228.                 return PTR_ERR(ap3216cdev.device);
  229.         }
  230.         ap3216cdev.private_data = client;
  231.         return 0;
  232. }
  233. /*
  234. * @description     : i2c驱动的remove函数,移除i2c驱动的时候此函数会执行
  235. * @param - client         : i2c设备
  236. * @return          : 0,成功;其他负值,失败
  237. */
  238. static int ap3216c_remove(struct i2c_client *client)
  239. {
  240.         /* 删除设备 */
  241.         cdev_del(&ap3216cdev.cdev);
  242.         unregister_chrdev_region(ap3216cdev.devid, AP3216C_CNT);
  243.         /* 注销掉类和设备 */
  244.         device_destroy(ap3216cdev.class, ap3216cdev.devid);
  245.         class_destroy(ap3216cdev.class);
  246.         return 0;
  247. }
  248. /* 传统匹配方式ID列表 */
  249. static const struct i2c_device_id ap3216c_id[] = {
  250.         {"alientek,ap3216c", 0},  
  251.         {}
  252. };
  253. /* 设备树匹配列表 */
  254. static const struct of_device_id ap3216c_of_match[] = {
  255.         { .compatible = "alientek,ap3216c" },
  256.         { /* Sentinel */ }
  257. };
  258. /* i2c驱动结构体 */       
  259. static struct i2c_driver ap3216c_driver = {
  260.         .probe = ap3216c_probe,
  261.         .remove = ap3216c_remove,
  262.         .driver = {
  263.                         .owner = THIS_MODULE,
  264.                            .name = "ap3216c",
  265.                            .of_match_table = ap3216c_of_match,
  266.                    },
  267.         .id_table = ap3216c_id,
  268. };
  269.                   
  270. /*
  271. * @description        : 驱动入口函数
  272. * @param                 : 无
  273. * @return                 : 无
  274. */
  275. static int __init ap3216c_init(void)
  276. {
  277.         int ret = 0;
  278.         ret = i2c_add_driver(&ap3216c_driver);
  279.         return ret;
  280. }
  281. /*
  282. * @description        : 驱动出口函数
  283. * @param                 : 无
  284. * @return                 : 无
  285. */
  286. static void __exit ap3216c_exit(void)
  287. {
  288.         i2c_del_driver(&ap3216c_driver);
  289. }
  290. /* module_i2c_driver(ap3216c_driver) */
  291. module_init(ap3216c_init);
  292. module_exit(ap3216c_exit);
  293. MODULE_LICENSE("GPL");
  294. MODULE_AUTHOR("zdyz");
复制代码
QT应用编程

“mainwindow.cpp”文件重要负担着布局及数据表现的功能。
获取传感器信息的函数:
  1. void MainWindow::getAp3216cData()
  2. {
  3.     static QString als = ap3216c->alsData();
  4.     if (als != ap3216c->alsData()) {
  5.         als = ap3216c->alsData();
  6.         arcGraph[0]->setangleLength(als.toUInt() * 360 / 65535);
  7.     }
  8.     static QString ps = ap3216c->psData();
  9.     if (ps != ap3216c->psData()) {
  10.         ps = ap3216c->psData();
  11.         arcGraph[1]->setangleLength(ps.toUInt() * 360 / 1023);
  12.     }
  13.     static QString ir = ap3216c->irData();
  14.     if (ir != ap3216c->irData()) {
  15.         ir = ap3216c->irData();
  16.         arcGraph[2]->setangleLength(ir.toUInt() * 360 / 1023);
  17.     }
  18.     glowText[0]->setTextData(als);
  19.     glowText[1]->setTextData(ps);
  20.     glowText[2]->setTextData(ir);
  21. }
复制代码
HeadView类

重要是来设置界面的顶部样式和布局:
比力简单
  1. iconWidget = new QWidget(this);//图标配置
  2. textLabel = new QLabel(this);//内容显示配置
  3. lineWidget = new QWidget(this);//底部白色线条的显示
  4. vBoxLayout = new QVBoxLayout();//垂直布局
  5. hBoxLayout = new QHBoxLayout();//水平布局
复制代码
ArcGraph类


  1.    /******************************************************************
  2. Copyright © Deng Zhimao Co., Ltd. 1990-2021. All rights reserved.
  3. * @projectName   08_ii2_ap3216c_sensor
  4. * @brief         arcgraph.cpp
  5. * @author        Deng Zhimao
  6. * @email         1252699831@qq.com
  7. * @net           www.openedv.com
  8. * @date          2021-05-22
  9. *******************************************************************/
  10. #include "arcgraph.h"
  11. ArcGraph::ArcGraph(QWidget *parent)
  12.     : QWidget(parent),
  13.       startAngle(90),
  14.       angleLength(100)
  15. {
  16.     this->setMinimumSize(100, 100);
  17.     setAttribute(Qt::WA_TranslucentBackground, true);
  18. }
  19. ArcGraph::~ArcGraph()
  20. {
  21. }
  22. void ArcGraph::setstartAngle(int angle)
  23. {
  24.     startAngle = angle;
  25.     this->repaint();
  26. }
  27. void ArcGraph::setangleLength(int length)
  28. {
  29.     angleLength = length;
  30.     this->repaint();
  31. }
  32. void ArcGraph::paintEvent(QPaintEvent *event)
  33. {
  34.     QPainter painter(this);
  35.     /* 保存状态 */
  36.     painter.save();
  37.     /* 设置抗锯齿 */
  38.     painter.setRenderHints(QPainter::Antialiasing, true);
  39.     /* 最外层的圆 */
  40.     QRect drawRect = event->rect();
  41.     QRadialGradient gradient1(drawRect.center(),
  42.                               drawRect.width() / 2,
  43.                               drawRect.center());
  44.     gradient1.setColorAt(0, Qt::transparent);
  45.     gradient1.setColorAt(0.5, Qt::transparent);
  46.     gradient1.setColorAt(0.51, QColor("#00237f"));
  47.     gradient1.setColorAt(0.58, QColor("#00237f"));
  48.     gradient1.setColorAt(0.59, Qt::transparent);
  49.     gradient1.setColorAt(1, Qt::transparent);
  50.     painter.setBrush(gradient1);
  51.     painter.setPen(Qt::NoPen);
  52.     painter.drawEllipse(drawRect);
  53.     /* 里层的圆 */
  54.     QRadialGradient gradient2(drawRect.center(),
  55.                               drawRect.width() / 2,
  56.                               drawRect.center());
  57.     gradient2.setColorAt(0, Qt::transparent);
  58.     gradient2.setColorAt(0.420, Qt::transparent);
  59.     gradient2.setColorAt(0.421, QColor("#885881e3"));
  60.     gradient2.setColorAt(0.430, QColor("#5881e3"));
  61.     gradient2.setColorAt(0.440, QColor("#885881e3"));
  62.     gradient2.setColorAt(0.441, Qt::transparent);
  63.     gradient2.setColorAt(1, Qt::transparent);
  64.     painter.setBrush(gradient2);
  65.     painter.setPen(Qt::NoPen);
  66.     painter.drawEllipse(drawRect);
  67.     /* 数字 */
  68.     QFont font;
  69.     font.setPixelSize(drawRect.width() / 10);
  70.     painter.setPen(Qt::white);
  71.     painter.setFont(font);
  72.     painter.drawText(drawRect, Qt::AlignCenter,
  73.                      QString::number(angleLength * 100 / 360) + "%");
  74.     /* 发光背景圆 */
  75.     painter.translate(drawRect.width() >> 1, drawRect.height() >> 1);
  76.     int radius = drawRect.width() / 2;
  77.     /* radius<< 1(左移1位)相当于radius*2 */
  78.     QRectF rect(-radius, -radius, radius << 1, radius << 1);
  79.     QRadialGradient gradient3(0, 0, radius);
  80.     gradient3.setColorAt(0, Qt::transparent);
  81.     gradient3.setColorAt(0.42, Qt::transparent);
  82.     gradient3.setColorAt(0.51, QColor("#500194d3"));
  83.     gradient3.setColorAt(0.55, QColor("#22c1f3f9"));
  84.     gradient3.setColorAt(0.58, QColor("#500194d3"));
  85.     gradient3.setColorAt(0.68, Qt::transparent);
  86.     gradient3.setColorAt(1.0, Qt::transparent);
  87.     painter.setBrush(gradient3);
  88.     QPainterPath path1;
  89.     path1.arcTo(rect, startAngle, -angleLength);
  90.     painter.setPen(Qt::NoPen);
  91.     painter.drawPath(path1);
  92.     /* 发光圆/弧 */
  93.     QRadialGradient gradient4(0, 0, radius);
  94.     gradient4.setColorAt(0, Qt::transparent);
  95.     gradient4.setColorAt(0.49, Qt::transparent);
  96.     gradient4.setColorAt(0.50, QColor("#4bf3f9"));
  97.     gradient4.setColorAt(0.59, QColor("#4bf3f9"));
  98.     gradient4.setColorAt(0.60, Qt::transparent);
  99.     gradient4.setColorAt(1.0, Qt::transparent);
  100.     painter.setBrush(gradient4);
  101.     QPainterPath path2;
  102.     path2.arcTo(rect, startAngle, -angleLength);
  103.     painter.setPen(Qt::NoPen);
  104.     painter.drawPath(path2);
  105.     /* 恢复状态 */
  106.     painter.restore();
  107.     /* 设置事件对象的accept标志 */
  108.     event->accept();
  109. }
复制代码
Ap3216c 类

Ap3216c 类的作用就是从驱动层提供给 Linux 应用层的接口获取数据,回归linux应用编程,利用C语言访问装备节点文件,之后调用驱动层代码,实现应用层访问驱动层数据,而且读取到数据。
  1. /******************************************************************
  2. Copyright © Deng Zhimao Co., Ltd. 1990-2021. All rights reserved.
  3. * @projectName   GlowText
  4. * @brief         glowtext.cpp
  5. * @author        Deng Zhimao
  6. * @email         1252699831@qq.com
  7. * @net           www.openedv.com
  8. * @date          2021-05-21
  9. *******************************************************************/
  10. #include "glowtext.h"
  11. #include <QDebug>
  12. #include <QGraphicsBlurEffect>
  13. GlowText::GlowText(QWidget *parent)
  14.     : QWidget(parent),
  15.       textColor("#4bf3f9"),
  16.       fontSize(18),
  17.       textData("100")
  18. {
  19.     QFont font;
  20.     font.setPixelSize(fontSize);
  21.     QPalette pal;
  22.     pal.setColor(QPalette::WindowText, textColor);
  23.     textLabelbg = new QLabel(this);
  24.     textLabelbg->setAttribute(Qt::WA_TranslucentBackground, true);
  25.     textLabelbg->setPalette(pal);
  26.     textLabelbg->setFont(font);
  27.     textLabelbg->setText(textData);
  28.     textLabelbg->setAlignment(Qt::AlignCenter);
  29.     /* 设置模糊特效 */
  30.     QGraphicsBlurEffect *ef = new QGraphicsBlurEffect();
  31.     ef->setBlurRadius(25);
  32.     ef->setBlurHints(QGraphicsBlurEffect::QualityHint);
  33.     textLabelbg->setGraphicsEffect(ef);
  34.     textLabel = new QLabel(this);
  35.     textLabel->setAttribute(Qt::WA_TranslucentBackground, true);
  36.     textLabel->setPalette(pal);
  37.     textLabel->setFont(font);
  38.     textLabel->setText(textData);
  39.     textLabel->setAlignment(Qt::AlignCenter);
  40.     textLabelbg->adjustSize();
  41.     textLabel->adjustSize();
  42.     this->resize(textLabel->size().width() + 10,
  43.                  textLabel->size().height() + 10);
  44.     /* 背景透明化 */
  45.     this->setAttribute(Qt::WA_TranslucentBackground, true);
  46. }
  47. GlowText::~GlowText()
  48. {
  49. }
  50. void GlowText::setTextColor(QColor color)
  51. {
  52.     QPalette pal;
  53.     pal.setColor(QPalette::WindowText, color);
  54.     textLabelbg->setPalette(pal);
  55.     textLabel->setPalette(pal);
  56. }
  57. void GlowText::setFontSize(int size)
  58. {
  59.     QFont font;
  60.     font.setPixelSize(size);
  61.     textLabelbg->setFont(font);
  62.     textLabel->setFont(font);
  63.     textLabel->adjustSize();
  64.     textLabelbg->adjustSize();
  65.     this->resize(textLabel->size().width() + 10,
  66.                  textLabel->size().height() + 10);
  67. }
  68. void GlowText::setTextData(QString text)
  69. {
  70.     textLabelbg->setText(text);
  71.     textLabel->setText(text);
  72.     textLabel->adjustSize();
  73.     textLabelbg->adjustSize();
  74.     this->resize(textLabel->size().width() + 10,
  75.                  textLabel->size().height() + 10);
  76. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作