1、查看电路原理图,确定驱动数码管对应的元件,及GPIO口

2、这里我们用的uart2的引脚,复用为GPIO口

3、上面确定了驱动数码管涉及的元器件为CS4021B(数码管)、74HC164D(移位寄存器)以及SOC的GPIO口,所以需要先找到74HC164D的芯片资料,查看该芯片是如何驱动A-G、A1-G1并输出特定的电平控制数码管

4、当时钟信号(CP 对应 SCK)从低电平变为高电平时,芯片将读取DSA(B)输入的电平信号,并将电平信号保存到Q0上(同时Q0会输出该电平),当时钟CP第二次由低电平变为高电平的时候将 Q0 的数据移动到 Q1,新的电平信号将被保存在 Q0。依此类推,每一个时钟周期中都有一个串行数据输入到 Q0,而其他的数据则不断往高位移动直到有数据传输结束。如果不再有时钟周期输入,则这些数据将暂存在输出端。

5、确定数码管的真值表,电路采用的共阳极,因此数码管Qn输出低电平时,对应的LED会亮,对应的真值表如下

6、驱动代码

#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/delay.h>#define DIGITAL_TUBE_SCK 64
#define DIGITAL_TUBE_SDA 65#define LOW               0
#define HIGH             1struct digital_tube{int major;struct class *class;struct device *dev;};struct digital_tube *lpf_digital_tube;int digital_tube_open(struct inode *inode,struct file *filp)
{printk("---------LPF:%s----------\n",__func__);return 0;
}int digital_tube_release(struct inode *inode,struct file *filp)
{printk("---------LPF:%s----------\n",__func__);return 0;
}static const struct file_operations digital_tube_fops={.owner = THIS_MODULE,.open = digital_tube_open,.release = digital_tube_release,
};//echo X(0<= X <10) > digital_tube_value,执行此函数
static void set_single_number(int number)
{u8 true_table[] = {0x02,0x9E,0x24,0x0C,0x98,0x48,0x40,0x1E,0x00,0x08};u8 data;u8 value;int count;data = true_table[number];for(count=0;count < 8;count ++){value = data&0x01;printk("-------LPF:%o---------\n",value);gpio_direction_output(DIGITAL_TUBE_SDA,value);gpio_direction_output(DIGITAL_TUBE_SCK,LOW);gpio_direction_output(DIGITAL_TUBE_SCK,HIGH);gpio_direction_output(DIGITAL_TUBE_SCK,LOW);gpio_direction_output(DIGITAL_TUBE_SDA,LOW);data = data>>1;}data=0xFE;for(count=0;count<8;count++){value = data&0x01;printk("-------LPF:%o---------\n",value);gpio_direction_output(DIGITAL_TUBE_SDA,value);gpio_direction_output(DIGITAL_TUBE_SCK,LOW);gpio_direction_output(DIGITAL_TUBE_SCK,HIGH);gpio_direction_output(DIGITAL_TUBE_SCK,LOW);gpio_direction_output(DIGITAL_TUBE_SDA,LOW);data = data>>1;}}//echo X(X >= 10) > digital_tube_value,执行此函数static void set_double_number(int number)
{u8 true_table[] = {0x02,0x9E,0x24,0x0C,0x98,0x48,0x40,0x1E,0x00,0x08};u8 data;u8 value;int count;data = true_table[number];for(count=0;count < 8;count ++){value = data&0x01;printk("-------LPF:%o---------\n",value);gpio_direction_output(DIGITAL_TUBE_SDA,value);gpio_direction_output(DIGITAL_TUBE_SCK,LOW);gpio_direction_output(DIGITAL_TUBE_SCK,HIGH);gpio_direction_output(DIGITAL_TUBE_SCK,LOW);gpio_direction_output(DIGITAL_TUBE_SDA,LOW);data = data>>1;}}/*返回写入的字符串长度,否则会无限回调 */
static ssize_t echo_digital_tube_value(struct device *dev,struct device_attribute *attr, const char *buf, size_t len)
{int value = 0 ;//int i;int single_value,double_value;/*将应用空间传递的(char *)类型数据转换为内核空间10进制整形 */value = simple_strtoul(buf, NULL, 10);if(value<0 && value >99 )return len;single_value = value % 10;double_value = value / 10;printk("---------LPF:%s----------\n",__func__);printk("---------LPF:value %d single_value %d double_value %d----------\n",value,single_value,double_value);if(double_value == 0){set_single_number(single_value);}else{set_double_number(single_value);set_double_number(double_value);}return len;
}static ssize_t cat_digital_tube_value(struct device *dev,struct device_attribute *attr, char *buf)
{printk("---------LPF:%s----------\n",__func__);return 0;}/*#define DEVICE_ATTR(_name, _mode, _show, _store)  /struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)类似:static struct kobj_attribute hello_value_attribute = __ATTR(hello_value, 0666, hello_show, hello_store);S_IWUSR|S_IRUSR 读写权限
*/static DEVICE_ATTR(digital_tube_value, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP  ,cat_digital_tube_value, echo_digital_tube_value);/* 驱动模块入口 */
static int __init digital_tube_init_module(void)
{int ret;/*空间申请*/lpf_digital_tube = kzalloc(sizeof(struct digital_tube),GFP_KERNEL);if(IS_ERR(lpf_digital_tube)){printk("-------LPF-%s:kzalloc lpf_digital_tube failed!--------\n",__func__);ret = PTR_ERR(lpf_digital_tube);return ret;}/* 设备号申请*/lpf_digital_tube->major = register_chrdev(0, "digital_tube_major", &digital_tube_fops);if(lpf_digital_tube->major < 0){printk("-------LPF-%s:failed to creat lpf_digital_tube->major-------\n",__func__);ret = -EINVAL;goto err_kzalloc;}/*创建设备类*/lpf_digital_tube->class = class_create(THIS_MODULE, "digital_tube_class");if(IS_ERR(lpf_digital_tube->class)){printk("-------LPF-%s:failed to creat lpf_digital_tube->class--------\n",__func__);ret = PTR_ERR(lpf_digital_tube->class);goto err_register;}/*创建digital_tube_device设备节点文件*/lpf_digital_tube->dev = device_create(lpf_digital_tube->class,NULL,MKDEV(lpf_digital_tube->major, 0),NULL,"digital_tube_device");if(IS_ERR(lpf_digital_tube->dev)){printk("-------LPF-%s:failed to creat lpf_digital_tube->dev--------\n",__func__);ret = PTR_ERR(lpf_digital_tube->dev);goto err_device_create;}/* 在 设备目录下创建一个digital_tube_value属性文件 /sys/class/digital_tube_class/digital_tube_device/digital_tube_value */ret=sysfs_create_file(&(lpf_digital_tube->dev->kobj), &dev_attr_digital_tube_value.attr);if(ret != 0){printk("-------LPF-%s:failed to creat sysfs_create_file ret:%d--------\n",__func__,ret);goto err_sysfs_create_file;}/* gpio_request */ret = gpio_request(DIGITAL_TUBE_SDA, "digital_tube_sda");if(ret!=0){printk("-------LPF-%s:SDA_GPIO: %d request failed!--------\n",__func__,DIGITAL_TUBE_SDA);goto err_sda_request;}else{printk("-------LPF-%s:SDA_GPIO: %d request success!-------\n",__func__,DIGITAL_TUBE_SDA);}ret = gpio_request(DIGITAL_TUBE_SCK, "digital_tube_sck");if(ret!=0){printk("-------LPF-%s:SCK_GPIO: %d request failed!--------\n",__func__,DIGITAL_TUBE_SCK);goto err_sck_request;}else{printk("-------LPF-%s:SCK_GPIO: %d request success!-------\n",__func__,DIGITAL_TUBE_SCK);}gpio_direction_output(DIGITAL_TUBE_SDA,LOW);gpio_direction_output(DIGITAL_TUBE_SCK,LOW);return ret;/*错误处理*/
err_sck_request:    gpio_free(DIGITAL_TUBE_SDA);
err_sda_request:sysfs_remove_file(&(lpf_digital_tube->dev->kobj), &dev_attr_digital_tube_value.attr); //删除创建的属性文件
err_sysfs_create_file:device_destroy(lpf_digital_tube->class,MKDEV(lpf_digital_tube->major, 0));
err_device_create:class_destroy(lpf_digital_tube->class);
err_register:unregister_chrdev(lpf_digital_tube->major,"digital_tube_major");
err_kzalloc:kfree(lpf_digital_tube);return ret;
}/* 驱动模块出口 */
static void __exit digital_tube_exit_module(void)
{gpio_free(DIGITAL_TUBE_SCK);gpio_free(DIGITAL_TUBE_SDA);sysfs_remove_file(&(lpf_digital_tube->dev->kobj), &dev_attr_digital_tube_value.attr);device_destroy(lpf_digital_tube->class,MKDEV(lpf_digital_tube->major, 0));class_destroy(lpf_digital_tube->class);unregister_chrdev(lpf_digital_tube->major,"digital_tube_major"); kfree(lpf_digital_tube);}module_init(digital_tube_init_module);
module_exit(digital_tube_exit_module);
MODULE_LICENSE("Dual BSD/GPL");

6.查看效果

linux驱动数码管-基于74HC164D相关推荐

  1. 【Linux驱动开发】基于imx6ul平台的sht30驱动开发

    Linux 的i2c系统 Linux 的i2c系统十分庞大,主要由3部分构成,i2c核心,i2c总线驱动,以及i2c设备驱动. i2c核心 主要提供了i2c总线驱动和设备驱动的注册,注销方法,i2c通 ...

  2. 基于Proteus学习单片机系列(二)——驱动数码管

    获取更多资源,请关注微信公众号:嵌入式基地 获取项目资源:公众号后台回复:单片机仿真 基于Proteus学习单片机系列(一)--点亮LED 基于Proteus学习单片机系列(二)--驱动数码管 基于P ...

  3. 【正点原子MP157连载】第二十三章 Linux设备树-摘自【正点原子】STM32MP1嵌入式Linux驱动开发指南V1.7

    1)实验平台:正点原子STM32MP157开发板 2)购买链接:https://item.taobao.com/item.htm?&id=629270721801 3)全套实验源码+手册+视频 ...

  4. 【正点原子Linux连载】第四十三章 Linux设备树 -摘自【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.0

    1)实验平台:正点原子阿尔法Linux开发板 2)平台购买地址:https://item.taobao.com/item.htm?id=603672744434 2)全套实验源码+手册+视频下载地址: ...

  5. 基于linux的驱动设计,《基于LINUX的虚拟驱动设计》-毕业论文.doc

    PAGE 40 l 摘 要 驱动程序是当前最热门.最有发展前途的IT应用技术之一.目前的驱动程序的开发主要应用在包括键盘 .鼠标.扫描仪.打印机以及存储设备等日益普及的设备之间的通讯上.但是要使这些设 ...

  6. arm裸机与嵌入式linux驱动开发,如何编写基于ARM的裸机程序和基于Linux的驱动程序?...

    在嵌入式开发中,ADC应用比较频繁,本文主要讲解ADC的基本原理以及如何编写基于ARM的裸机程序和基于Linux的驱动程序. ARM架构:Cortex-A9Linux内核:3.14 在讲述ADC之前, ...

  7. 74hc164驱动数码管c语言程序,基于51单片机的74HC164驱动数码管显示程序与仿真

    基于51单片机的74HC164驱动数码管显示程序与仿真 基于51单片机的74HC164驱动一位数码管显示程序与仿真 #include #include #define uchar unsigned c ...

  8. STM32F1与STM32CubeIDE编程实例-MAX7219驱动8位7段数码管(基于SPI)

    MAX7219驱动8位7段数码管(基于SPI) 在前面的文章中,我们实现了纯GPIO方式通过MAX7219驱动8位7段数码管.由于MAX7219支持SPI.QSPI接口,最大支持10MHz的通信速率, ...

  9. 基于STC15W4K32S4单片机仿真《74HC595驱动数码管动态显示》

    1. 编 程 软 件:keil5版本. 2.仿 真 软 件:Proteus8.12 3.单片机选型:STC15W4K32S4 4.学 习 目 标:1.学习74HC595驱动数码管动态显示 5.程 序 ...

  10. 基于STC15W4K32S4单片机仿真《74HC595驱动数码管静态显示》

    1. 编 程 软 件:keil5版本. 2.仿 真 软 件:Proteus8.12 3.单片机选型:STC15W4K32S4 4.学 习 目 标:1.学习74HC595芯片工作方式           ...

最新文章

  1. Microsoft Security Essentials 4.1.522.0 RTM
  2. 要学习机器学习,先从这十大算法开始吧
  3. 函数式编程语言python-函数式编程初探
  4. Git常见错误(附解决办法)
  5. css 语音,用css完成语音助手小动画
  6. 如何实现tm同时监控多个状态的改变_广电机房监控系统【斯必得智慧机房】
  7. c语言程序不用编译即可被计算机识别运行,2011秋华农c语言试卷
  8. 让你的程序只能运行一个实例
  9. SQL Server CONVERT() 函数,Date 函数
  10. oracle主备不同步,主备环境下数据不一致重新部署复制
  11. 面试题总结:可能是全网最好的MySQL重要知识点
  12. oracle官网下载plsql,Oracle、OracleClient、PLSQL下载安装配置(64位)
  13. c语言case后语句,switch语句中case后的标号是什么
  14. 1124 Raffle for Weibo Followers (20 分)
  15. 我写的新闻——Adobe校园行西工大站圆满落幕
  16. 快速记忆之简单词语联想记忆
  17. 我为什么鼓励你读博士?
  18. 一文带你学会使用小程序CMS内容管理
  19. 用Johnson-Trotter算法生成排列!
  20. 电脑如何安装python

热门文章

  1. [NISACTF 2022]
  2. oracle数据库书籍mobi,Oracle Database 12c PL/SQL开发指南(第7版) pdf epub mobi txt 下载...
  3. 如何对C盘进行扩容重新分区?
  4. R语言加载xlsl软件包
  5. Resizable BAR support(MSDN翻译)
  6. 2020如何成功注册google
  7. 阿里云短信服务java发送短信验证码
  8. python3GUI--adb调试测试工具By:PyQt5(附下载地址)
  9. 搜狗浏览器怎么清除浏览记录 搜狗浏览器清除浏览记录教程
  10. m1的docker-compose