【技术支持】ARM9无线遥控视频实时监控小车(一)--------小车的电机控制模块
2012-03-30 21:50
621 查看
项目决定初期的想法主要出自于网上安卓手机的遥控下车
这个项目也是自己第一次做,肯定会话很多的冤枉钱
项目的总体花费为1000元左右
下图是这几天完成的一些内容,主要是小车运行和云台运动的实现
之后完成的模块将慢慢实现与展示
首先是怎么用ARM9的开发板实现轮子的伺服,小车的购买主要是来自淘宝,小车的是伺服主要是通过双H桥直流电机驱动板,它的使用方式就不拿出来说了,都是参考别人的 http://blog.sina.com.cn/s/blog_5e4725590100d2oq.html这是我使用的直流驱动板买家写的博客,里面说的非常之详细。其他的电机驱动板都是一个原理。
我使用的开发板的只有GPJ引脚是可以现成使用的,其他的都已经被封装使用了,电机驱动板只要通过GPJ的四个引脚分别置高低电平分别接I1\T2\I3\I4(这四个端口启动驱动板的时候就是高电平,所以是低电平有效),由于开发板的定时器有限,我之后还要用timer产生PWM波控制舵机,而且又不想扩展另外一块单片机来控制,就索性不控制电机的速度了。将小车的所有硬件都搭建完毕之后是测试电机的使用。第一步当然是编写GPJ的驱动,代码如下所示(驱动的编写就不在给予介绍)其实网上可以收到很多
下面是编写驱动c文件的makefile文件
记得将KSOURCE ?=/home/fox/utu-Linux2.6.24_for_utu2440_2009-07-18/ 命令改为自己的内核编译目录
接下来就是测试代码(其实就是控制代码了)
先声明上面的测试程序我是在项目整合中拷贝过来的,虚拟机已经关闭就没有经过编译,希望有错的下面留言,本人必将改之,不过一般来说不会出太大的或太多的错误。
这个项目也是自己第一次做,肯定会话很多的冤枉钱
项目的总体花费为1000元左右
下图是这几天完成的一些内容,主要是小车运行和云台运动的实现
之后完成的模块将慢慢实现与展示
首先是怎么用ARM9的开发板实现轮子的伺服,小车的购买主要是来自淘宝,小车的是伺服主要是通过双H桥直流电机驱动板,它的使用方式就不拿出来说了,都是参考别人的 http://blog.sina.com.cn/s/blog_5e4725590100d2oq.html这是我使用的直流驱动板买家写的博客,里面说的非常之详细。其他的电机驱动板都是一个原理。
我使用的开发板的只有GPJ引脚是可以现成使用的,其他的都已经被封装使用了,电机驱动板只要通过GPJ的四个引脚分别置高低电平分别接I1\T2\I3\I4(这四个端口启动驱动板的时候就是高电平,所以是低电平有效),由于开发板的定时器有限,我之后还要用timer产生PWM波控制舵机,而且又不想扩展另外一块单片机来控制,就索性不控制电机的速度了。将小车的所有硬件都搭建完毕之后是测试电机的使用。第一步当然是编写GPJ的驱动,代码如下所示(驱动的编写就不在给予介绍)其实网上可以收到很多
#include<linux/module.h> #include<linux/init.h> #include<linux/fs.h> #include<asm/uaccess.h> #include<linux/device.h> #include<asm/io.h> 7 MODULE_AUTHOR("FOX,GMAIL:huli_131@hotmail.com); MODULE_DESCRIPTION("Driver test gpj"); MODULE_LICENSE("GPL"); #define DEVICE_NAME "gpj" 12 #define GPJCON (unsigned long)(0x560000D0) #define GPJDAT (unsigned long)(0x560000D4) #define GPJUP (unsigned long)(0x560000D8) 16 static int major=0; static int minor=0; static int counter=0; static int gpjdp=0; 21 static unsigned long _io_gpjcon; static unsigned long _io_gpjdat; static unsigned long _io_gpjup; unsigned long temp; 26 27 static struct class *dev_class;//方便驱动创建节点 static int gpj_open(struct inode *,struct file *); static ssize_t gpj_read(struct file *,char *,size_t,loff_t *); static ssize_t gpj_write(struct file *, const char *,size_t,loff_t *); 33 static int gpj_ioctl(struct inode *,struct file *,unsigned int,unsigned long); 35 struct file_operations gpj_ops={ .open = gpj_open, .read = gpj_read, .write = gpj_write, .ioctl = gpj_ioctl, }; 42 static int gpj_open(struct inode * pinode,struct file * filep) { if(counter) return -EBUSY; 47 counter++; 49 _io_gpjcon = (unsigned long)ioremap(GPJCON,4); _io_gpjdat = (unsigned long)ioremap(GPJDAT,4); _io_gpjup = (unsigned long)ioremap(GPJUP,4); 53 /*----------------------------0~3 控制电机设置为输入输出模式-------------------------------*/ 55 temp= *(volatile unsigned long*)_io_gpjcon; temp &= ~(0xFF); temp |=0X55; *(volatile unsigned long*)_io_gpjcon = temp ; 60 temp= *(volatile unsigned long*)_io_gpjdat; //将4个引脚的输出初始化为低电平 temp &= ~(0xF); *(volatile unsigned long*)_io_gpjdat = temp ; 64 temp= *(volatile unsigned long*)_io_gpjup; //开启下拉电阻的模式 temp |= 0xf; *(volatile unsigned long*)_io_gpjup = temp ; 68 /*------------------------------------------结束-------------------------------------------*/ 70 return 0; } static ssize_t gpj_read(struct file * pinode,char * buf,size_t len,loff_t * off) { return sizeof(int); } static ssize_t gpj_write(struct file * pinode, const char * buf,size_t len,loff_t * off) { if(copy_from_user(&gpjdp,buf,sizeof(int))) return -EFAULT; 81 return sizeof(int); } 84 static int gpj_ioctl(struct inode * nodep,struct file * filep,unsigned int cmd,unsigned long arg) { 87 /////////////////////////////////////////0~5引脚高低电平的控制///////////////////////////// //cmd : true false //arg : 0~3 if(arg<0 | arg>4) { printk("arg error"); return -1; } temp = *(volatile unsigned long*)_io_gpjdat; if(cmd) { temp |= (0x01<<arg); //置高电平 } else { temp &= ~(0x01<<arg); //置低电平 } *(volatile unsigned long*)_io_gpjdat = temp; return 0; } 108 109 static int gpj_init(void) { printk("init gpj driver:\n"); major=register_chrdev(0,DEVICE_NAME,&gpj_ops); 114 if(major<0) { printk("Register failure\n"); } else { //printk("Register Success %d - %d\n",major,minor); dev_class=class_create(THIS_MODULE,DEVICE_NAME); 123 if(dev_class==NULL) { printk("device create fail:mknod /dev/%s %d %d",DEVICE_NAME,major,minor); } else { // device_create(dev_class,NULL,MKDEV(major,minor),"%s",DEVICE_NAME); printk("/dev/%s register success\n",DEVICE_NAME); 133 } 135 } 137 return 0; 139 } static void gpj_exit(void) { printk("exit gpj driver:\n"); 144 if(dev_class) { device_destroy(dev_class,MKDEV(major,minor)); class_destroy(dev_class); 149 } 151 unregister_chrdev(major,DEVICE_NAME); } 154 module_init(gpj_init); module_exit(gpj_exit);
下面是编写驱动c文件的makefile文件
#version 2.0 DEBUG ?=n KSOURCE ?=/home/fox/utu-Linux2.6.24_for_utu2440_2009-07-18/ KBUILD_VERBOSE:=1 5 %.x :%.c arm-linux-gcc -o $@ $< 8 obj-m:=gpj.o 10 default: make -C $(KSOURCE) LANG=C KBUILD_VERBOSE=${KBUILD_VERBOSE} SUBDIRS=`pwd` modules .PHONY: cscope: cscope -b -k -R .PHONY: clean: make -C $(KSOURCE) LANG=C KBUILD_VERBOSE=${KBUILD_VERBOSE} SUBDIRS=`pwd` modules rm -f *.x *~ rm -rf *.o *.ko
记得将KSOURCE ?=/home/fox/utu-Linux2.6.24_for_utu2440_2009-07-18/ 命令改为自己的内核编译目录
接下来就是测试代码(其实就是控制代码了)
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/ioctl.h> 5 void car_advance(); void car_sternway(); void car_turn_left(); void car_turn_right(); void car_brake(); 11 int main(int argc, char **argv) { int control_num; if(argc!=2){printf("cmd error\n");return 1;} fd=open(argv[1],O_RDWR); //fd = open("/dev/goj", O_RDWR); if(fd < 0) { printf("Open PWM Device Faild!\n"); exit(1); } printf("please enter a control number:\n"); while(1) 26 { //输入参数 scanf("%d", &control_num); printf("control_num = %d\n", control_num); //IO控制 switch(control_num) { case 0: car_advance(); break; case 1: car_sternway(); break; case 2: car_turn_left(); break; case 3: car_turn_right(); break; case 4: car_brake(); break; default: break; } } //关闭设备 close(fd); return 0; } 57 /*---------------------------------说 明----------------------------------------*/ // * @ 接口对应 // * @ Gpj0:I1 // * @ Gpj1:I2 // * @ Gpj2:I3 // * @ Gpj3:I4 /*---------------------------------前 进----------------------------------------*/ void car_advance() { ioctl(fd,true, 0); ioctl(fd,false, 1); ioctl(fd,true, 2); ioctl(fd,false, 3); } 72 /*---------------------------------后 退----------------------------------------*/ void car_sternway() { ioctl(fd,true, 1); ioctl(fd,false, 0); ioctl(fd,true, 3); ioctl(fd,false, 2); } 81 /*---------------------------------左 转----------------------------------------*/ void car_turn_left() { ioctl(fd,true, 0); ioctl(fd,false, 1); ioctl(fd,true, 3); ioctl(fd,false, 2); } 90 /*---------------------------------右 转-----------------------------------------*/ void car_turn_right() { ioctl(fd,true, 1); ioctl(fd,false, 0); ioctl(fd,true, 2); ioctl(fd,false, 3); } 99 /*---------------------------------刹 车-----------------------------------------*/ void car_brake() { ioctl(fd,false, 0); ioctl(fd,false, 1); ioctl(fd,false, 2); ioctl(fd,false, 3); }
先声明上面的测试程序我是在项目整合中拷贝过来的,虚拟机已经关闭就没有经过编译,希望有错的下面留言,本人必将改之,不过一般来说不会出太大的或太多的错误。
相关文章推荐
- 【技术支持】ARM9无线遥控视频实时监控小车(二)--------摄像头舵机控制模块
- 基于pcDuino的WiFi实时视频监控智能小车——硬件部分(二)
- 海康威视:实时视频透雾技术在监控中的应用
- IP视频监控系统中云台控制模块的设计与实现 (转)
- 用Red5搭建支持WEB播放的实时监控视频
- 基于pcDuino的WiFi实时视频监控智能小车-——前言
- 基于Z301P摄像头 H.264OK6410的远程视频web监控 项目笔记5(小车驱动)GPIO控制
- 基于嵌入式技术的视频监控系统的设计
- web浏览器无插件播放实时音视频技术---SIPML5参数配置(四)
- visual studio 2017 installer 安装包制作过程出现的问题---无法注册模块 HRESULT -2147024769 请与您的技术支持人员联系
- iOS使用ffmpeg播放rstp实时监控视频数据流
- WebRTC实时音视频技术的整体架构介绍
- 转 iOS使用ffmpeg播放rstp实时监控视频数据流
- 基于视频压缩的实时监控系统-A1:产品设计与规划
- 基于视频压缩的实时监控系统-A3:Makefile和main.h解析
- WebRTC实时音视频技术的整体架构介绍
- Linux中使用Pyinotify模块实时监控文件系统更改
- iOS使用ffmpeg播放rstp实时监控视频数据流
- 背景建模技术(四):视频分析(VideoAnalysis)模块
- 市面上所有号称"虚拟机","防火墙"的实时监控杀毒软件无一不是使用的IFSHOOK技术.但是同时也有一些朋友不断写MAIL给我打听如何实现读写的监控.下面给出用VTOOLSD写的代码.也就是所有实时杀毒软件的奥秘.同时,很多拦截文件操作的软件,例如对目录加