资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,第,11,章 步进电机驱动的设计,本章重点,Linux,设备驱动程序的结构。,步进电机驱动的设计。,步进电机驱动程序的调试。,本章内容,11.1,步进电机概述,11.2,嵌入式,Linux,步进电机的驱动,11.3,步进电机驱动的设计,11.1,步进电机概述,在步进电机的设计中硬件设计和软件编程,2,大部分。在硬件设计方面,需要根据其功能设计驱动电路原理图、进行,PCB,的制作、电路板制作,购买元器件和焊接。硬件环境的搭建是软件调试的基础,是本设计的重要组成部分之一。基于操作系统的驱动程序的设计,首先就要搭建软件平台环境,需要有交叉编译器的安装、,Bootloader,的配置和移植、内核的移植、根文件系统的制作几个步骤,然后进行驱动程序的设计和编译调试。通常将硬件驱动程序编写成一种可加载的内核模块并进行开发和配置,这样用户就可以将硬件驱动程序作为一种独立的系统进行升级而不必对内核进行改动。,11.1,步进电机概述,步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件。在非超载的情况下,电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响,即给电机加一个脉冲信号,电机则转过一个步距角。这一线性关系的存在,加上步进电机只有周期性的误差而无累积误差等特点。使得在速度、位置等控制领域用步进电机来控制变的非常的简单。,虽然步进电机已被广泛地应用,但步进电机并不能像普通的直流电机,交流电机在常规下使用。它必须由双环形脉冲信号、功率驱动电路等组成控制系统方可使用。因此用好步进电机却非易事,它涉及到机械、电机、电子及计算机等许多专业知识。,11.1,步进电机概述,EELIOD,系统的步进电机使用的是四相步进电机,采用的电机控制芯片是,Allegro,公司的,UCN4202A,,它包含低功率,CMOS,逻辑控制部分和达林顿管输出驱动极,最大输出电流为,1.5A,使用单相或双相,半步激励方式,内设续流二极管和过热保护电路。,UCN4202A,的控制功能包括,PWM,波输入,电机转动方向,输出使能和复位功能。,OE,端使用,GPIO53,控制,为高时,电机没有输出;为低时,UCN4202A,开始工作。,DIC,端为方向端,为低时为正向,为高时为反向。,UCN4202A,的逻辑控制有,ABCD,四个相位,在正向时,单相激励的顺序是,A-B-C-D,,两相激励的顺序是,AB-BC-CD-DA,,而半步激励的顺序是,A-AB-B-BC-C-CD-D-DA,。当为反向时,同理就是从,D,相开始。以下是步进电机的电路连接图,11.2,嵌入式,Linux,步进电机的驱动,11.2.1,步进电机设备驱动程序设计流程,基于操作系统的驱动程序调用过程如图,11.2,所示。,11.2,嵌入式,Linux,步进电机的驱动,编写模块程序的时候,必须提供两个函数,一个是,int init_module(void),,供,insmod,在加载此模块的时候自动调用,负责进行设备驱动程序的初始化工作。,init_module,函数返回,0,以表示初始化成功,返回负数表示失败。另一个函数是,void cleanup_module(void),,在模块被卸载时调用,负责进行设备驱动程序的清除工作。,在成功的向系统注册了设备驱动程序后(调用,register_chrdev,成功后),就可以用,mknod,命令来把设备映射为一个特别文件,其它程序使用这个设备的时候,只要对此特别文件进行操作就行了。,在内核升级到,2.4,版本后,系统提供了两个新的函数,devfs_register,和,devfs_unregister,,用于设备的注册与卸载。,11.2,嵌入式,Linux,步进电机的驱动,当设备驱动程序以模块形式加载时,模块在调用,insmod,命令时被加载,此时的入口地址是,init_module,函数,在该函数中完成设备的注册。接着根据用户的实际需要,对相应设备进行读、写等操作,同样在执行命令,rmmod,时调用函数,cleanup_module,,完成设备的卸载。,字符设备驱动程序设计的主要过程如下:,1,结构体设计,2,步进电机驱动读、写函数的设计,3,步进电机驱动程序的注册,4,步进电机驱动程序的卸载,5,步进电机驱动程序设计,11.2,嵌入式,Linux,步进电机的驱动,11.2.2,步进电机驱动程序需求分析,步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件。在非超负载的情况下电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数而不受负载变化的影响。所以在驱动程序中只需要考虑这两个方面的影响。,本系统的步进电机的四相由硬件地址,0 x28000006,的,bit0-bit3,控制,bit0,对应,MOTOR_A,bit1,对应,MOTOR_B,bit2,对应,MOTOR_C,bit3,对应,MOTOR_D,。本节所描述的驱动是针对整,MOTOR,整步模式下的步进电机,整步模式下的步距角,180,。在整步模式下的脉冲分配信号如表,11.1,所示。,11.2,嵌入式,Linux,步进电机的驱动,所以在程序中需要通过编制脉冲分配表控制步进电机。并且通过修改脉冲分配表可以实现步进电机方向的控制。,系统的步进电机仅仅是一个输出的通道只能顺序的进行控制的操作因此作为一个字符设备来进行驱动。对于字符设备的操作而言驱动程序需要提供相关的几个操作分别为,open,、,read,、,write,、,ioctl,等相关的函数入口点。在驱动程序的实现过程中需要定义这些文件相关的操作,填充进入,file_operations,结构中。,与普通文件相比,设备文件的操作要复杂得多。不可能简单的通过,read,、,write,等操作来实现。并且由于对于步进电机驱动程序没有相关的输入与输出更关注的是对硬件的控制因此在驱动程序对于,write,操作和,read,操作仅需返回,0.,而对于硬件的控制只需要在驱动程序中实现,ioctl,函数,并在其中添加相应的,case,即可。通过,cmd,区分操作,通过,arg,传递参数和结果。,11.3,步进电机驱动的设计,1,、编写驱动程序和应用程序,操作步骤:,(,1,)在,/home,新建目录,motor,rootlocalhost home#mkdir motor,(,2,)进入刚建的,motor,目录然后新建,driver,目录和,app,目录。,rootlocalhost home#cd motor,rootlocalhost motor#mkdir driver,rootlocalhost motor#mkdir app,(,3,)进入刚建的,driver,目录然后编写驱动源代码。,rootlocalhost motor#cd driver,rootlocalhost driver#vi electromotor.c,程序代码如下:,#include,#include,11.3,步进电机驱动的设计,#include,#include,#include,#include,#include,#include,#include,#include,#include,#include,#define ELECTROMOTOR_MAJOR 140,#define ELECTROMOTOR_6(ELECTROMOTOR_1+6),#define ELECTROMOTOR_7(ELECTROMOTOR_1+7),#define electromotor_sle(*(volatile unsigned long*)ELECTROMOTOR_GPACON)#define electromotor_sle_data(*(volatile unsigned long*)ELECTROMOTOR_GPADATA)devfs_handle_t devfs_electromotor;,11.3,步进电机驱动的设计,unsigned long ELECTROMOTOR_1;,unsigned long ELECTROMOTOR_GPACON;,unsigned long ELECTROMOTOR_GPADATA;,/unsigned long electromotor_write_addr;,intelectromotor_open(struct inode*,struct file*);,intelectromotor_release(struct inode*,struct file*);,int electromotor_ioctl(struct inode*,struct file*,unsigned int,unsigned long);,ssize_t electromotor_read(struct file*,char*,size_t);,ssize_t electromotor_write(struct file*,char*,size_t);,static struct file_operations electromotor_fops=,open:electromotor_open,read:electromotor_read,write:electromotor_write,/,ioctl:electromotor_ioctl,release:electromotor_release,;,11.3,步进电机驱动的设计,int electromotor_open(struct inode*inode,struct file*filp),/*select NGCS2*/,electromotor_sle|=0 x2000;,electromotor_sle_data,printk(open okn);,return 0;,ssize_t electromotor_read(struct file*fp,char*buf,size_t size),/put_user(key,buf);,return 1;,11.3,步进电机驱动的设计,ssize_t electromotor_write(struct file*fp,char*buf,size_t size),char key;,if(get_user(key,buf),return-EFAULT;,(*(volatile unsigned char*)ELECTROMOTOR_6)=key;,return 1;,int electromotor_release(struct inode*inode,struct file*filp),electromotor_sle,electromotor_sle_data|=0 x2000;,printk(release okn);,return 0;,11.3,步进电机驱动的设计,int _init electromotor_init(void),printk(*electromotor_init*n);ELECTROMOTOR_GPACON=ioremap(0 x56000000,4);,ELECTROMOTOR_GPADATA=ioremap(0 x56000004,4);,ELECTROMOTOR_1=ioremap(0 x10000000,8);,devfs_electromotor=,devfs_register(NULL,electromotor,DEVFS_FL_DEFAULT,ELECTROMOTOR_MAJOR,0,S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP,return 0;,11.3,步进电机驱动的设计,static void _exit electromotor_exit(void),devfs_unregister(devfs_electromotor);,module_init(elect
展开阅读全文