ARM9无线遥控视频实时监控小车(一)--------小车的电机控制模块

发布者:快乐航程最新更新时间:2024-08-02 来源: cnblogs关键字:ARM9  无线遥控  电机控制模块 手机看文章 扫描二维码
随时随地手机看文章

项目决定初期的想法主要出自于网上安卓手机的遥控下车

这个项目也是自己第一次做,肯定会话很多的冤枉钱

项目的总体花费为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<100     }

101     else

102     {    

103         temp &= ~(0x01<104     }

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;

[1] [2]
关键字:ARM9  无线遥控  电机控制模块 引用地址:ARM9无线遥控视频实时监控小车(一)--------小车的电机控制模块

上一篇:给ARM9(S3C2440)添加驱动的三种方法
下一篇:ARM9无线遥控视频实时监控小车(二)--------摄像头舵机控制模块

推荐阅读最新更新时间:2024-11-02 11:19

arm9之MMU_Init()
#include def.h #include option.h #include 2410addr.h #include 2410lib.h #include 2410slib.h #include mmu.h // 1) Only the section table is used. // 2) The cachable/non-cachable area can be changed by MMT_DEFAULT value. // The section size is 1MB. void MMU_Init(void) { int i,j; //========================== IMPO
[单片机]
基于ARM9系统的远程图像无线监控的设计
对图像监控系统,用户常常提出这样的功能需求:希望能够监控距离较远的对象。这些对象有可能分布在郊区、深山,荒原或者其他无人值守的场合;另外,希望能够获取比较清晰的监控图像,但对图像传输的实时性要求并不高,很明显,用传统的PC机加图像采集卡的方式很难满足这样的需求。 在嵌入式领域,ARM9系列微处理器在高性能和低功耗方面提供了最佳的性能,因此选用ARM9嵌入式处理器S3C2440设计实现了一个远程图像光线监控系统通过这个系统,可以远在千里之外控制一个摄像机进行图像采集并回传。如果这个摄像机有一个485接口的云台,还可以通过互联网远程控制摄像机的取景角度、镜头拉伸、聚焦等功能. 除了获取图像数据.系统还提供了多路开关控制和
[单片机]
基于<font color='red'>ARM9</font>系统的远程图像无线<font color='red'>监控</font>的设计
S3C2410(ARM9)的启动方式
1、Nand Flash启动 为了从Nand Flash启动,S3C2410配置了一个叫做Steppingstone的4KB内部SRAM缓冲器,当系统被配置为从Nand Flash启动时(配置由硬件工程师在电路板设置),Nandflash控制器会自动的将Nand Flash前4KB代码将会被自动装入内部 RAM(Steppingstone)中,并把0x0地址设置为内部RAM的起始地址(存储器映射),然后CPU开始从内部RAM的0x0地址启动,这个过程不需要程序的干涉。通常nandflash前4KB的代码会将nandflash中的CPU启动初始化代码拷贝到SDRAM中,然后跳到SDRAM中开始执行。所以程序员需要做的就是将最核心
[单片机]
s3c2440(ARM9)通用寄存器地址
89c51的通用寄存器组是对应内存的,即在内存中分配地址,那么ARM9的呢? 来源: http://zhidao.baidu.com/link?url=Nf9NDaITEiA4Gc9q6Y4dP3yt xLJPwBjvRhizxtP0hUu6sQaN qUFqPnS7KEfvfjpIJBlzFKFz q-rBNYXSGx1-va s3c2440a 通用寄存器地址:例如R0,R1,R2之类的通用寄存器对应内存的地址??? 这么说,在C编程中,就不存在所谓的R1、R2之类的通用寄存器了?? R0,R1,R2是 寄存器 ,在cpu内部,用于计算和存储访问、存放临时数据、以及一些cpu或程序运行的状态,是不直接对应内存的,所以也就没有
[单片机]
ARM9的bootloader---vivi
vivi是韩国mizi 公司开发的bootloader, 适用于ARM9处理器。Vivi有两种工作模式:启动加载模式和下载模式。启动加载模式可以在一段时间后(这个时间可更改)自行启动linux内核,这时vivi的默认模式。在下载模式下,vivi为用户提供一个命令行接口,通过接口可以使用vivi提供的一些命令,如下:   命令   功能   Load   把二进制文件载入Flash或RAM   Part   操作MTD分区信息。显示、增加、删除、复位、保存MTD分区   Param   设置参数   Boot   启动系统   Flash   管理Flash,如删除
[单片机]
基于嵌入式ARM9 S3C2440A 的USB设计与实现
引 言 USB(Universal Serial Bus)是通用串行总线的缩写,因其具有方便易用,动态分配带宽,容错性优越和高性价比等特点,现已成为计算机的主流接口。 随着嵌入式系统的广泛应用,各种小型终端需要开发出与外界联系的USB接口。目前,常用的技术有两种。基于单片机的USB接口,特点是需要外置芯片,电路复杂,留下的 CPU资源不多;基于ARM的USB接口,特点是资源丰富,但ARM系列产品较多,如果选型不当,还需要搭接较多的外围电路,且不能很好地发挥CPU性能。 该设计采用三星公司ARM9核的S3C2440A芯片作为CPU,因为该芯片内部集成了控制USB的所有部件,外围电路简单,易于实现。 1 S3C2440
[单片机]
基于嵌入式<font color='red'>ARM9</font> S3C2440A 的USB设计与实现
基于ARM9的心电模拟发生系统设计
随着社会的发展,人们的医疗保健意识越来越强,所以医生的培训也就成为非常重要的环节。心电除颤技术作为医生培训的一个主要方面,若操作规范,动作熟练,往往在紧急关头可以救人于危难之间,在培训的时候,如果能够真实地模拟急救除颤的场景,将会起到良好的学习效果。因此,在急救、有创性临床操作训练上,医学模拟教学日益显示出其成本低、重复性高、教学效率高以及符合医学伦理要求等优势。   除颤模拟发生系统可以任意选择34种状态(包括成人和儿童两大类)时也可以连接医用监护仪,使除颤模拟更加逼真。学员可以进行不同能量的除颤练习,同时这也便于老师检验学员的学习效果。   该系统是根据心电图的有关原理以及监护仪的信号合成原理研制的,严格按照医学的相关规
[工业控制]
基于<font color='red'>ARM9</font>的心电模拟发生系统设计
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved