项目决定初期的想法主要出自于网上安卓手机的遥控下车
这个项目也是自己第一次做,肯定会话很多的冤枉钱
项目的总体花费为1000元左右
下图是这几天完成的一些内容,主要是小车运行和云台运动的实现
之后完成的模块将慢慢实现与展示
首先是怎么用ARM9的开发板实现轮子的伺服,小车的购买主要是来自淘宝,小车的是伺服主要是通过双H桥直流电机驱动板,它的使用方式就不拿出来说了,都是参考别人的 http://blog.sina.com.cn/s/blog_5e4725590100d2oq.html这是我使用的直流驱动板买家写的博客,里面说的非常之详细。其他的电机驱动板都是一个原理。
我使用的开发板的只有GPJ引脚是可以现成使用的,其他的都已经被封装使用了,电机驱动板只要通过GPJ的四个引脚分别置高低电平分别接I1T2I3I4(这四个端口启动驱动板的时候就是高电平,所以是低电平有效),由于开发板的定时器有限,我之后还要用timer产生PWM波控制舵机,而且又不想扩展另外一块单片机来控制,就索性不控制电机的速度了。将小车的所有硬件都搭建完毕之后是测试电机的使用。第一步当然是编写GPJ的驱动,代码如下所示(驱动的编写就不在给予介绍)其实网上可以收到很多
1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 8 MODULE_AUTHOR('FOX,GMAIL:huli_131@hotmail.com); 9 MODULE_DESCRIPTION('Driver test gpj'); 10 MODULE_LICENSE('GPL'); 11 #define DEVICE_NAME 'gpj' 12 13 #define GPJCON (unsigned long)(0x560000D0) 14 #define GPJDAT (unsigned long)(0x560000D4) 15 #define GPJUP (unsigned long)(0x560000D8) 16 17 static int major=0; 18 static int minor=0; 19 static int counter=0; 20 static int gpjdp=0; 21 22 static unsigned long _io_gpjcon; 23 static unsigned long _io_gpjdat; 24 static unsigned long _io_gpjup; 25 unsigned long temp; 26 27 28 static struct class *dev_class;//方便驱动创建节点 29 30 static int gpj_open(struct inode *,struct file *); 31 static ssize_t gpj_read(struct file *,char *,size_t,loff_t *); 32 static ssize_t gpj_write(struct file *, const char *,size_t,loff_t *); 33 34 static int gpj_ioctl(struct inode *,struct file *,unsigned int,unsigned long); 35 36 struct file_operations gpj_ops={ 37 .open = gpj_open, 38 .read = gpj_read, 39 .write = gpj_write, 40 .ioctl = gpj_ioctl, 41 }; 42 43 static int gpj_open(struct inode * pinode,struct file * filep) 44 { 45 if(counter) 46 return -EBUSY; 47 48 counter++; 49 50 _io_gpjcon = (unsigned long)ioremap(GPJCON,4); 51 _io_gpjdat = (unsigned long)ioremap(GPJDAT,4); 52 _io_gpjup = (unsigned long)ioremap(GPJUP,4); 53 54 /*----------------------------0~3 控制电机设置为输入输出模式-------------------------------*/ 55 56 temp= *(volatile unsigned long*)_io_gpjcon; 57 temp &= ~(0xFF); 58 temp |=0X55; 59 *(volatile unsigned long*)_io_gpjcon = temp ; 60 61 temp= *(volatile unsigned long*)_io_gpjdat; //将4个引脚的输出初始化为低电平 62 temp &= ~(0xF); 63 *(volatile unsigned long*)_io_gpjdat = temp ; 64 65 temp= *(volatile unsigned long*)_io_gpjup; //开启下拉电阻的模式 66 temp |= 0xf; 67 *(volatile unsigned long*)_io_gpjup = temp ; 68 69 /*------------------------------------------结束-------------------------------------------*/ 70 71 return 0; 72 } 73 static ssize_t gpj_read(struct file * pinode,char * buf,size_t len,loff_t * off) 74 { 75 return sizeof(int); 76 } 77 static ssize_t gpj_write(struct file * pinode, const char * buf,size_t len,loff_t * off) 78 { 79 if(copy_from_user(&gpjdp,buf,sizeof(int))) 80 return -EFAULT; 81 82 return sizeof(int); 83 } 84 85 static int gpj_ioctl(struct inode * nodep,struct file * filep,unsigned int cmd,unsigned long arg) 86 { 87 88 /////////////////////////////////////////0~5引脚高低电平的控制///////////////////////////// 89 //cmd : true false 90 //arg : 0~3 91 if(arg<0 | arg>4) 92 { 93 printk('arg error'); 94 return -1; 95 } 96 temp = *(volatile unsigned long*)_io_gpjdat; 97 if(cmd) 98 { 99 temp |= (0x01< 101 else 102 { 103 temp &= ~(0x01< 105 *(volatile unsigned long*)_io_gpjdat = temp; 106 return 0; 107 } 108 109 110 static int gpj_init(void) 111 { 112 printk('init gpj driver:n'); 113 major=register_chrdev(0,DEVICE_NAME,&gpj_ops); 114 115 if(major<0) 116 { 117 printk('Register failuren'); 118 } 119 else 120 { 121 //printk('Register Success %d - %dn',major,minor); 122 dev_class=class_create(THIS_MODULE,DEVICE_NAME); 123 124 if(dev_class==NULL) 125 { 126 printk('device create fail:mknod /dev/%s %d %d',DEVICE_NAME,major,minor); 127 } 128 else 129 { 130 // 131 device_create(dev_class,NULL,MKDEV(major,minor),'%s',DEVICE_NAME); 132 printk('/dev/%s register successn',DEVICE_NAME); 133 134 } 135 136 } 137 138 return 0; 139 140 } 141 static void gpj_exit(void) 142 { 143 printk('exit gpj driver:n'); 144 145 if(dev_class) 146 { 147 device_destroy(dev_class,MKDEV(major,minor)); 148 class_destroy(dev_class); 149 150 } 151 152 unregister_chrdev(major,DEVICE_NAME); 153 } 154 155 module_init(gpj_init); 156 module_exit(gpj_exit); 下面是编写驱动c文件的makefile文件 1 #version 2.0 2 DEBUG ?=n 3 KSOURCE ?=/home/fox/utu-Linux2.6.24_for_utu2440_2009-07-18/ 4 KBUILD_VERBOSE:=1 5 6 %.x :%.c 7 arm-linux-gcc -o $@ $< 8 9 obj-m:=gpj.o 10 11 default: 12 make -C $(KSOURCE) KBUILD_VERBOSE=${KBUILD_VERBOSE} SUBDIRS=`pwd` modules 13 .PHONY: 14 cscope: 15 cscope -b -k -R 16 .PHONY: 17 clean: 18 make -C $(KSOURCE) KBUILD_VERBOSE=${KBUILD_VERBOSE} SUBDIRS=`pwd` modules 19 rm -f *.x *~ 20 rm -rf *.o *.ko 记得将KSOURCE ?=/home/fox/utu-Linux2.6.24_for_utu2440_2009-07-18/ 命令改为自己的内核编译目录 接下来就是测试代码(其实就是控制代码了) 1 #include 2 #include 3 #include 4 #include 5 6 void car_advance(); 7 void car_sternway(); 8 void car_turn_left(); 9 void car_turn_right(); 10 void car_brake(); 11 12 int main(int argc, char **argv) 13 { 14 int control_num; 15 if(argc!=2){printf('cmd errorn');return 1;} 16 fd=open(argv[1],O_RDWR); 17 //fd = open('/dev/goj', O_RDWR); 18 19 if(fd < 0) 20 { 21 printf('Open PWM Device Faild!n'); 22 exit(1); 23 } 24 printf('please enter a control number:n'); 25 while(1) 26 27 { 28 //输入参数 29 scanf('%d', &control_num); 30 printf('control_num = %dn', control_num); 31 //IO控制 32 switch(control_num) 33 { 34 case 0: 35 car_advance(); 36 break; 37 case 1: 38 car_sternway(); 39 break; 40 case 2: 41 car_turn_left(); 42 break; 43 case 3: 44 car_turn_right(); 45 break;
上一篇:给ARM9(S3C2440)添加驱动的三种方法
下一篇:ARM9无线遥控视频实时监控小车(二)--------摄像头舵机控制模块
推荐阅读最新更新时间:2024-11-02 11:19
设计资源 培训 开发板 精华推荐
- 基于 NCD9830 8 位、8 通道 ADC 的 NCD9830EVB 评估板
- DC2026A-KIT,Linduino 一款隔离式 Arduino 兼容演示板,带有 LTC2607/LTC2422 (DC934A) 演示板
- DEV-12660,基于 VS1053 音频编解码器的 SparkFun MP3 Player Shield
- LT3066IMSE LED 驱动器和电流源的典型应用电路
- AD5306 四路电压输出、8 位数模转换器的典型应用
- LTC4257CS8-1 演示板,以太网供电接口控制器,Vsig = 48V,Vout = 3.3V
- 使用 ROHM Semiconductor 的 BU4241 的参考设计
- LTC3604EUD 演示板、2.5A、15V 单片式同步降压型稳压器
- 涂鸦训练营 万能红外遥控器
- TB2923AHQ 51W x 4ch BTL 音频电源典型应用