基于s3c6410的74hc595驱动

本文介绍了一个基于Linux的HC595驱动模块实现细节,包括GPIO配置、字符设备注册、 IOCTL操作处理等关键部分,并提供了完整的源代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

/*

接口说明:

SET_MODE: 用来设设置595 级联,每增加一个 595 8,初始值为16(支持两个 595) TURN_OFF: 具体关闭那个继电器

TURN_ON: 具体打开那个继电器

TURN_ALL_OFF: 关闭所有继电器,第三个参数无效

TURN_ALL_ON: 打开所有继电器,第三个参数无效

*/

#include <linux/module.h>

 #include<linux/kernel.h>

#include <linux/fs.h>

#include <linux/init.h>

#include <linux/delay.h>

#include <linux/cdev.h>

#include <linux/device.h>

#include <asm/uaccess.h>

#include <mach/regs-gpio.h>

#include <mach/s3c6410.h>

#include <plat/gpio-cfg.h>

#include <asm/gpio.h>

#include <mach/gpio-bank-n.h>

#include <linux/pci.h>

#include <mach/map.h>

#define HC595_EN S3C64XX_GPN(10)

#define HC595_SRCLR S3C64XX_GPN(6)

#define HC595_SRCLK S3C64XX_GPN(5)

#define HC595_SER S3C64XX_GPN(2)

#define TURN_OFF  0

#define TURN_ON   1

#define TURN_ALL_OFF   3

#define TURN_ALL_ON   4

#define SET_MODE      5

staticint mode;

static int dev_id;

static struct cdev   hc595_cdev; //字符设备

static struct class    *hc595_class;

static struct device   *hc595_device;

static volatile long *p_GPNCON = NULL;

//static volatile long *p_GPNDATA = NULL;

static void gpio_init(void)

{

        /*GPN25610 配置为输出状态*/

*p_GPNCON&= ~((3<<2*2) | (3<<2*5) | (3<<2*6) | (3<<2*10));

*p_GPNCON |=(1<<2*2) | (1<<2*5) | (1<<2*6) | (1<<2*10);
}


staticint hc595_open(struct inode * inode, struct file * file)

{

printk("fromkernel: open successfully!\n");

gpio_init();

mode = 16;

return 0;

}

staticint write_to_hc595(int hc595_data)

{

int i;

 

gpio_init();

gpio_set_value(HC595_SRCLR,1);/*禁止清空寄存器*/

for(i=0;i<mode; i++)

{

if(((hc595_data)& (1<<(mode -1 -i))) == (1<<(mode -1 -i)))

{

gpio_set_value(HC595_SER,1);/*准备串行数据*/ /*创造上升沿时序*/gpio_set_value(HC595_SRCLK, 0);

udelay(5);

gpio_set_value(HC595_SRCLK,1);

udelay(5);

printk(KERN_ALERT"hight:i=%d\n", (mode -1 -i));

}

else

{

gpio_set_value(HC595_SER,0);/*准备串行数据*/

udelay(5);
/*
创造上升沿时序*/

gpio_set_value(HC595_SRCLK,0);

                           udelay(5);

gpio_set_value(HC595_SRCLK,1);

udelay(5);

printk(KERN_ALERT"level:i=%d\n", (mode -1 -i));

                 }

}

gpio_set_value(HC595_EN,0);/*产生并行输出上升时序*/

udelay(5);

gpio_set_value(HC595_EN,1);/*产生并行输出上升时序*/

udelay(5);

return0;

}

staticlong hc595_ioctl( struct file *file,unsigned int cmd, unsigned long arg)

{

//int err = 0;

static intold_val = 0;

        if(arg<0 || arg>16)

{

printk(KERN_ALERT"the num you enter is invalue!\n");

return-1;

}

printk(KERN_ALERT"from kern: cmd=%d num=%d\n",cmd, arg);

switch(cmd)

{

caseTURN_ON:

{

printk("hello:TURN_ON\n");

old_val|= (1<<arg);/*设置相应位为'1'*/

write_to_hc595(old_val);

break;

}

caseTURN_OFF:
    {

printk("hello:TURN_OFF\n");

old_val&= ~(1<<arg);/*设置相应位为'0'*/

write_to_hc595(old_val);

break;

}

caseTURN_ALL_OFF:

{

printk("hello:TURN_ALL_OFF\n");

old_val= 0;

write_to_hc595(old_val);

break;

}

caseTURN_ALL_ON:

{

printk("hello:TURN_ALL_ON\n");

old_val= 0xffff;

write_to_hc595(old_val);

break;

}

caseSET_MODE:

{

mode= arg;

        }

default:

{

printk(KERN_ALERT"cmd is invalue!\n");

break;

}

 

}

return 0;

 }

staticint hc595_release(struct inode *inode, struct file *file)

{

 

return 0;

}

staticstruct file_operations hc595_fops=

{

.owner =THIS_MODULE,

.open =hc595_open,

.unlocked_ioctl= hc595_ioctl,

.release =hc595_release,

};

staticint register_cdev(dev_t dev_id)

{

int ret;

cdev_init(&hc595_cdev,&hc595_fops);

hc595_cdev.owner= THIS_MODULE;

ret =cdev_add(&hc595_cdev, dev_id, 1);

return ret;

}

static int hc595_init(void)

{

int ret =alloc_chrdev_region(&dev_id, 0, 1, "hc595_drv");

if(ret < 0)

{

printk(KERN_INFO"alloc_chrdev_region failed!\n");

return-1;

}

 

ret =register_cdev(dev_id);

if(ret < 0)

{

printk(KERN_INFO"register_cdev failed!\n");

return-1;

}

 

hc595_class =class_create(THIS_MODULE, "hc595_class");

hc595_device =device_create(hc595_class, NULL, dev_id, NULL, "hc595_device");

p_GPNCON= (volatile unsigned long*)ioremap(0X7F008830, 8);


printk(KERN_ALERT"insmod successfully!\n"); return 0;

}

 

static void hc595_exit(void)

{

cdev_del(&hc595_cdev);

unregister_chrdev_region(dev_id,1);

device_destroy(hc595_class,dev_id);

class_destroy(hc595_class);

iounmap(p_GPNCON);

printk(KERN_INFO"rmmod succeful!!\n");

}

 

module_init(hc595_init);

module_exit(hc595_exit);

 

MODULE_LICENSE("GPL");

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值