【精品博文】嵌入式监控系统喷水模块的设计
嵌入式监控系统中很重要的一个环节就是当有人闯入和有火灾生时候,需要进行报警并喷水,今天我给大家写一个模块的设计。
设计中将四个LED灯与S3C2410处理器的四个管脚相连接,由于GPIO是复用管脚,所以首先进行相应寄存器的配置,也就是首先配置控制寄存器GPFCON,配置为output.然后就是对灯的相应控制,这个是对数据寄存器GPFDAT,如果写0,led灯亮。否则灯灭。
软件是通过ioctl进行相应的控制。
原理图:
红外模块驱动流程图
详细代码设计
#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/ioctl.h>
#include <asm/uaccess.h>
#include <asm/hardware.h>
#include <asm/arch/regs-gpio.h>
#include <asm-arm/irq.h>
#include <asm-arm/arch-s3c2410/irqs.h>
#include <linux/interrupt.h>
#include <asm/io.h>
MODULE_LICENSE("GPL");
#define GPFCON *(volatile unsigned int *)S3C2410_GPFCON
//#define GPBDAT *(volatile unsigned int *)S3C2410_GPBDAT
static int led_major=0;
static int led_open(struct inode *inode ,struct file *file)
{
GPFCON &=(~(3<<6));
//printk("GPFCON is %x\n",GPFCON);
return 0;
}
static ssize_t led_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
{
int flags=0;
int ret;
// writel(0,S3C2410_GPFDAT);
ret = readl(S3C2410_GPFDAT);
//printk("!!!!!!!!!flags is %x\n",ret&(1<<3));
if((ret & (1<<3)) == 8)
{
//printk("in flags =1 ??????\n");
flags=1;
copy_to_user(buffer, &flags, sizeof(flags)); }
else
copy_to_user(buffer,(char *)&flags,sizeof(flags));
return sizeof(flags);
}
static int led_release(struct inode *inode,struct file *file)
{
return 0;
}
static void led_setup_cdev(struct cdev *dev,int minor,struct file_operations *fops)
{
int err;
int devno=MKDEV(led_major,minor);
cdev_init(dev,fops);
dev->owner=THIS_MODULE;
dev->ops=fops;
err=cdev_add(dev,devno,1);
if(err)
printk(KERN_INFO"Error %d adding led %d\n",err,minor);
}
static struct file_operations led_remap_ops={
.owner=THIS_MODULE,
.open=led_open,
.release=led_release,
.read = led_read,
};
static struct cdev SimpleDevs;
static int led_init(void)
{
int result;
//int ret;
dev_t dev=MKDEV(led_major,0);
if(led_major)
result=register_chrdev_region(dev,1,"led");
else
{
result=alloc_chrdev_region(&dev,0,1,"led"); led_major=MAJOR(dev);
}
if(result<0)
{
printk(KERN_WARNING"led:unable to get major %d\n",led_major);
return result;
}
if(led_major==0)
led_major=result; printk(KERN_INFO"led register ok!!!!!!!!!!\n");
//ret = request_irq(IRQ_EINT19, button_irq, SA_INTERRUPT, "led", NULL);
led_setup_cdev(&SimpleDevs,0,&led_remap_ops);
return 0;
}
static void led_exit(void)
{
cdev_del(&SimpleDevs);
unregister_chrdev_region(MKDEV(led_major,0),2);
printk("led device uninstalled\n");
}
module_init(led_init);
module_exit(led_exit);
2.测试模块程序设计
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <sys/ioctl.h>
int main(void)
{
int fd,i,j;
int flags=0;
j=0;
fd=open("/dev/led",O_RDWR); //打开设备驱动程序
//进行打开操作的判断
if(fd<0)
{
printf("led open failed\n");
exit(0);
}
while(1)
{
read(fd,&flags,1);
printf("flags is %d\n",flags);
sleep(1);
}
close(fd);//关闭设备
return 0;
}