周立功IMX287开发套件之数码管驱动(linux下74HC595多级串联驱动,数码管驱动)

疫情待在家里很无聊,发现吃土的开发板。好久好久没干linux相关开发了,还是在安美数字的时候干的linux网络应用和部分内核开发,现在忘得差不多了,试着捡起来吧。

 

硬件:如上图短接帽接法

软件:驱动下面直接贴出来(直接同时驱动四个断码比较水),应用层直接write就行

如果要四位显示不同数据需要改驱动和应用层,驱动增加数码管位使能,应用层需要一个单独进程一直跑显示,另一个传数据。我太懒了,就不写了!


#include
#include
#include
#include                                                  
#include                                                 
#include "mach/../../mx28_pins.h"
#include
#include "mach/mx28.h"
#include
#include
#include                                     
#include                          
#include                          
#include                   
#include              
#include


#include
#include
#include
#include
#include
#include

#define GPIO_74HC595_DATA_PIN        MXS_PIN_TO_GPIO(PINID_SSP3_MOSI)
#define GPIO_74HC595_STCP_PIN        MXS_PIN_TO_GPIO(PINID_SAIF0_LRCLK)
#define GPIO_74HC595_SHCP_PIN        MXS_PIN_TO_GPIO(PINID_SSP3_SCK)


int nxp74hc595_open(struct inode *, struct file *);
int nxp74hc595_release(struct inode *, struct file *);

ssize_t nxp74hc595_read(struct file *, char *, size_t, loff_t *);
ssize_t nxp74hc595_write(struct file *, const char *, size_t, loff_t *);


int dev_major = 666; 
int dev_minor = 0; 


char data[2]={0xFF,0x0f};//data[1]选择段码位 data[0]段码内容

static struct class *firstdrv_class;
static struct device *firstdrv_class_dev;
struct cdev *nxp74hc595_cdev; 


//将文件操作与分配的设备号相连
struct file_operations nxp74hc595_fops = 
{
    owner    : THIS_MODULE, 
    open    : nxp74hc595_open,
    release    : nxp74hc595_release,
    write    : nxp74hc595_write,
};

//初始化io引脚
static int __init gpio_74hc595_drv_init(void)
{

    int iRet;

    gpio_free(GPIO_74HC595_DATA_PIN);
    gpio_free(GPIO_74HC595_STCP_PIN);
    gpio_free(GPIO_74HC595_SHCP_PIN);


    iRet = gpio_request(GPIO_74HC595_DATA_PIN, "74HC595_DATA");
    if (iRet != 0) {
        printk("request 74HC595_DATA failed \n");
        return -EBUSY;
    }

    iRet = gpio_request(GPIO_74HC595_SHCP_PIN, "74HC595_SHCP");
    if (iRet != 0) {
        printk("request 74HC595_SHCP failed \n");
        return -EBUSY;
    }


    iRet = gpio_request(GPIO_74HC595_STCP_PIN, "74HC595_STCP");
    if (iRet != 0) {
        printk("request 74HC595_STCP failed \n");
        return -EBUSY;
    }

    gpio_direction_output(GPIO_74HC595_DATA_PIN,0);
    gpio_direction_output(GPIO_74HC595_STCP_PIN,0);
    gpio_direction_output(GPIO_74HC595_SHCP_PIN,0);

    printk("init all 74HC595 ctl gpio succ \n");
    return 0;

}


//向74HC595写入数据
void Write_74HC595(unsigned char ChipNum,unsigned char *DataBuf)
{
    unsigned char i = 0;
    unsigned char DataBufTmp = 0;
    
    gpio_set_value(GPIO_74HC595_STCP_PIN,0);//STCP
    for(; ChipNum>0; ChipNum--){
        DataBufTmp = *DataBuf;
        for(i=0; i<8; i++){
            gpio_set_value(GPIO_74HC595_SHCP_PIN,0);//SHCP
            if (DataBufTmp & 0x80){
                gpio_set_value(GPIO_74HC595_DATA_PIN,1);
            }else{
                gpio_set_value(GPIO_74HC595_DATA_PIN,0);
            }
            udelay(5);
            gpio_set_value(GPIO_74HC595_SHCP_PIN,1);
            udelay(5);        
            DataBufTmp = DataBufTmp << 1;
        }
        DataBuf++;
    }

    gpio_set_value(GPIO_74HC595_STCP_PIN,1);
    udelay(10);
    gpio_set_value(GPIO_74HC595_STCP_PIN,0);
}


static void __exit nxp74hc595_exit(void) 
{

    char data[2]={0xFF,0x0f};

    dev_t devno = MKDEV(dev_major, dev_minor); 
    cdev_del(nxp74hc595_cdev); 
    kfree(nxp74hc595_cdev); 

    unregister_chrdev_region(devno, 1); 
    device_unregister(firstdrv_class_dev);
    class_destroy(firstdrv_class);


    Write_74HC595(2,data);
    gpio_free(GPIO_74HC595_DATA_PIN);
    gpio_free(GPIO_74HC595_STCP_PIN);
    gpio_free(GPIO_74HC595_SHCP_PIN);
    printk("NXP74hc595 unregister success\n");

}

static int __init nxp74hc595_init(void) 
{

    int ret, err;
    dev_t devno;


    ret=alloc_chrdev_region(&devno, dev_minor, 2, "NXP74hc595");
    dev_major=MAJOR(devno);

    if(ret<0){
    printk("my74hc595 register failure\n");
        return ret;
    }else{
        printk("74hc595 register success\n");
    }

    nxp74hc595_cdev = kmalloc(sizeof(struct cdev), GFP_KERNEL);

    cdev_init(nxp74hc595_cdev, &nxp74hc595_fops);


    nxp74hc595_cdev->owner = THIS_MODULE;         
    err = cdev_add(nxp74hc595_cdev, devno, 1);     

    if(err<0){
        printk("add device failure\n"); 
    }


    firstdrv_class = class_create(THIS_MODULE, "74HC595");
    firstdrv_class_dev = device_create(firstdrv_class, NULL, MKDEV(dev_major, 0), NULL,"NXP74HC595-%d", 1);

    gpio_74hc595_drv_init();
    Write_74HC595(2,data);


    printk("register 74HC595 dev OK\n");
    return 0;
}


int nxp74hc595_open(struct inode *inode, struct file *filp)
{
    printk("open my74hc595 dev OK\n");
    return 0;
}

int nxp74hc595_release(struct inode *inode, struct file *filp)
{
    Write_74HC595(2,data);
    gpio_free(GPIO_74HC595_DATA_PIN);
    gpio_free(GPIO_74HC595_STCP_PIN);
    gpio_free(GPIO_74HC595_SHCP_PIN);
    printk("close NXP74HC595 dev OK\n");
    return 0;
}


ssize_t nxp74hc595_write(struct file *filp, const char *buf, size_t len, loff_t *off)
{
    char dataa[2]    = {0};

    if(copy_from_user(dataa, buf, 2)){
        return -EFAULT;
    }
    printk("dataa[0] = %d , dataa[1] = %d\n",dataa[0],dataa[1]);


    switch(dataa[0]){
        case 1:data[0] = ~0x06;break;
        case 2:data[0] = ~0x5b;break;
        case 3:data[0] = ~0x4f;break;
        case 4:data[0] = ~0x66;break;
        case 5:data[0] = ~0x6d;break;
        case 6:data[0] = ~0x7d;break;
        case 7:data[0] = ~0x07;break;
        case 8:data[0] = ~0x7f;break;
        case 9:data[0] = ~0x6f;break;
    }


    
    printk("data[0] = %d  \n",data[0]);
    Write_74HC595(2,data);

    printk("write nxp74hc595 dev OK\n");
    return sizeof(int); 
}


MODULE_LICENSE("GPL"); 
module_init(nxp74hc595_init); 
module_exit(nxp74hc595_exit);
 

你可能感兴趣的:(linux驱动,IMX287)