Linux 下GPIO扩展 74HC595的驱动设计实现

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <asm/uaccess.h>

#include “io_595.h”

static dev_t hc595_devno;
static struct class *hc595_class;
static struct cdev *hc595_dev;
static uint32_t gpio_status = 0;

static int hc595_open (struct inode *inode, struct file *filep)
{
printk(“hc595_open \n”);
return 0;
}

static void hc595_send_bytes(uint32_t io_bytes)
{
uint8_t i;
gpio_set_value(GPIO_HC595_ST, 0);
for(i=0; i<24; i++)
{
gpio_set_value(GPIO_HC595_SH, 0);
if((io_bytes & 0x00800000) == 0x00800000)
{
printk(“Bit Loc:%d-%x\n”, 23-i, io_bytes & 0x00800000);
gpio_set_value(GPIO_HC595_DS, 1);
}
else
{
gpio_set_value(GPIO_HC595_DS, 0);
}
mdelay(2);
gpio_set_value(GPIO_HC595_SH, 1);
io_bytes = io_bytes << 1;
}
gpio_set_value(GPIO_HC595_ST, 1);
mdelay(2);
gpio_set_value(GPIO_HC595_ST, 0);
gpio_set_value(GPIO_HC595_OE, 0);
}

static ssize_t hc595_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
{
copy_from_user(&gpio_status, buf, 4); //拷贝4个字节
printk(“Write IO_Val:%d\n”, gpio_status);
hc595_send_bytes(gpio_status);
return 1;
}

static struct file_operations hc595_ops=
{
.open = hc595_open,
.write = hc595_write,
};

static int hc595_init(void)
{
int ret;
/*动态分配设备号/
ret = alloc_chrdev_region(&hc595_devno, 0, 1, “hc595_io”);
if(ret)
{
printk(“alloc_chrdev_region fail!\n”);
unregister_chrdev_region(hc595_devno,1);
return ret;
}
else
{
printk(“alloc_chrdev_region success!\n”);
}
/*描述结构初始化/
cdev_init(&hc595_dev, &hc595_ops);
/*描述结构注册/
ret = cdev_add(&hc595_dev, hc595_devno, 1);
if(ret)
{
printk(“cdev add fail.\n”);
unregister_chrdev_region(hc595_devno, 1);
return ret;
}
else
{
printk(“cdev add sucess!\n”);
}
hc595_class = class_create(THIS_MODULE,“hc595_class”);
if(IS_ERR(hc595_class))
{
printk(“Create class fail!\n”);
unregister_chrdev_region(hc595_devno,1);
return -1;
}
else
{
printk(“Create class sucess!\n”);
}
device_create(hc595_class,NULL,hc595_devno,0,“hc595”);
//申请GPIO
gpio_request(GPIO_HC595_ST, “GPIO_HC595_ST”);
gpio_direction_output(GPIO_HC595_ST, 1);
gpio_request(GPIO_HC595_SH, “GPIO_HC595_SH”);
gpio_direction_output(GPIO_HC595_SH, 1);
gpio_request(GPIO_HC595_DS, “GPIO_HC595_DS”);
gpio_direction_output(GPIO_HC595_DS, 1);
gpio_request(GPIO_HC595_OE, “GPIO_HC595_OE”);
gpio_direction_output(GPIO_HC595_OE, 0); //OE设置为低电平,使能状态
//所有端口设置低电平
hc595_send_bytes(0x00000000);
printk(“HC595_init…\n”);
return 0;
}

static void hc595_exit(void)
{
device_destroy(hc595_class,hc595_devno);
class_destroy(hc595_class);
cdev_del(&hc595_dev);
unregister_chrdev_region(hc595_devno,1);
printk(“hc595_exit…\n”);
}

MODULE_LICENSE(“GPL”);
module_init(hc595_init);
module_exit(hc595_exit);

头文件内容只定义了GPIO

#ifndef _IO_595_H
#define _IO_595_H

#define GPIO_HC595_DS GPIOB(3)
#define GPIO_HC595_ST GPIOB(4)
#define GPIO_HC595_SH GPIOB(6)
#define GPIO_HC595_OE GPIOB(13)

#endif

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32单片机利用74HC595驱动数码管是一种常见的方法。以下是详细步骤: 1. 连接硬件:首先,将数码管的共阳极引脚连接到74HC595芯片的输出引脚,并将74HC595的时钟引脚(CLK)连接到STM32单片机的某个GPIO引脚;将74HC595的数据引脚(DATA)连接到STM32单片机的另一个GPIO引脚;将74HC595的锁存引脚(LATCH)连接到STM32单片机的第三个GPIO引脚。 2. 初始化:在STM32单片机上,配置相应的GPIO引脚为输出模式。然后,设置锁存引脚为低电平。 3. 数据发送:以适当的形式将要显示的数字或字符数据存储在一个数组中。然后,使用移位运算将数据逐位发送到74HC595芯片。具体实现时,通过逐位将数据写入数据引脚,并在每次写入后将时钟引脚上升沿触发以将数据移位到74HC595芯片。 4. 确定数据有效:当所有位的数据都被正确移位到74HC595芯片后,将锁存引脚置为高电平。这将导致芯片将存储的数据显示在数码管上。 5. 重复步骤:通过循环结构重复步骤3和4,以连续显示多个字符或数字。 使用74HC595驱动数码管具有优点,如节约IO资源,允许连接更多的数码管,并可以通过级联多个74HC595芯片以驱动更多的数码管。此外,通过移位方式发送数据,可以快速更新显示内容。当然,还要注意74HC595芯片的工作电压和电流要求,以及连接电阻等其他硬件设置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值