基于NanoPi的继电器模块驱动开发

继电器模块

电磁继电器一般由铁芯、线圈、衔铁、触点簧片等组成的。
只要在线圈两端加上一定的电压,线圈中就会流过一定的电流,从而产生电磁效应,衔铁就会在电磁力吸引的作用下克服返回弹簧的拉力吸向铁芯,从而带动衔铁的动触点与静触点(常开触点)吸合。当线圈断电后,电磁的吸力也随之消失,衔铁就会在弹簧的反作用力返回原来的位置,使动触点与原来的静触点(常闭触点)释放。这样吸合、释放,从而达到了在电路中的导通、切断的目的。对于继电器的“常开、常闭”触点,可以这样来区分:继电器线圈未通电时处于断开状态的静触点,称为“常开触点”;处于接通状态的静触点称为“常闭触点”。继电器一般有两股电路,为低压控制电路和高压工作电路。

模块原理图

模块与NanoPi连接图

驱动程序源码

#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/string.h>
#include <linux/uaccess.h>
#include <linux/list.h>

#include <linux/clk.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <plat/gpio-cfg.h>
#include <mach/gpio-samsung.h>

#define DEVICE_NAME "2451_relay"

//nanopi2451
#define J1_GPIO S3C2410_GPG(9)      //模块GPIO脚
#define J2_GPIO S3C2410_GPG(10)     //模块GPIO脚

#define J1_OFF 0x00
#define J1_ON  0x01
#define J2_OFF 0x10
#define J2_ON  0x11

char drv_buf[2];

static int update_relay(void)
{

    switch(drv_buf[0]) {
    case J1_ON:
        gpio_set_value(J1_GPIO, 0);  //输出低电平
        return 0;
    case J1_OFF:
        gpio_set_value(J1_GPIO, 1);  //输出高电平
        return 0;
    case J2_ON:
        gpio_set_value(J2_GPIO, 0);  //输出低电平
        return 0;
    case J2_OFF:
        gpio_set_value(J2_GPIO, 1);  //输出高电平
        return 0;
    default:
        return -EINVAL;
    }
}

static int relay_write(struct file *file, const char * buffer, size_t count, loff_t * ppos)
{
    unsigned long err;          
    err = copy_from_user(drv_buf, buffer, 1);
    update_relay();
    return 1;
}

static struct file_operations dev_fops={
    write:relay_write,
};

static struct miscdevice misc = {
    .minor = MISC_DYNAMIC_MINOR,
    .name = DEVICE_NAME,
    .fops = &dev_fops,
};

static int __init my_relay_init(void)
{
    int ret;

    s3c_gpio_cfgpin(J1_GPIO, S3C_GPIO_SFN(1));//设置输出
    s3c_gpio_cfgpin(J2_GPIO, S3C_GPIO_SFN(1));//设置输出

    ret = misc_register(&misc);
    printk (DEVICE_NAME"\t#J1 J2 initialized\n"); 
    return ret; 
}

static void __exit my_relay_exit(void)
{
    misc_deregister(&misc);
}

module_init(my_relay_init);
module_exit(my_relay_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("TONY www.91arm.com");

测试程序源码

#include     <stdio.h>    
#include     <stdlib.h>     
#include     <unistd.h>     
#include     <sys/types.h>  
#include     <sys/stat.h>   
#include     <fcntl.h>      
#include     <errno.h> 

#define DEV_FILE "/dev/2451_relay"

#define J1_OFF  0x00
#define J1_ON   0x01
#define J2_OFF  0x10
#define J2_ON   0x11

int main()
{
    int fd_dev=-1;
    char dat[2];
    int cmd;
    printf("nanoPi driver Test\n");

    fd_dev = open(DEV_FILE,O_RDWR);
    if(fd_dev<0){
        printf("open device err\n");
        return 0;
    }

    while(1){
        printf("1:J1 OFF 2:J1 ON 3:J2 OFF 4:J2 ON\n");
        printf("Please input:"); 
        scanf("%d",&cmd);
        switch(cmd){
            case 1:     
                dat[0] = J1_OFF;
                break;
            case 2:
                dat[0] = J1_ON;
                break;
            case 3:
                dat[0] = J2_OFF;
                break;
            case 4:
                dat[0] = J2_ON;
                break;
            default:
                break;
        }
        write(fd_dev,dat,1);
    }

    return 0;
}

Copyright © 2016 www.91arm.com 【91创客学堂】