嵌入式课程---嵌入式Linux的直流电机驱动开发

文章目录

实验环境准备

实验材料:GEC6818实验箱、电脑、
实验环境:VMware下Linux系统、arm-linux-交叉编译环境,windows系统、secureCRT平台

步骤简要说明:

因为需要用到Linux系统环境,所以在Windows下装了个虚拟机,使用虚拟机的环境来开发驱动,并编写了测试驱动的程序,然后把驱动与测试驱动的两个文件传送到实验箱中,接着在实验箱上测试驱动是否可用

第一步:测试三个系统是否连通

  1. 禁用pc机无线网卡、关闭所有防火墙
  2. 设置pc机的IP地址(192.168.1.160)、子网掩码(255.255.255.0)
  3. 设置虚拟机IP地址,在终端下输入:
ifconfig eth0 192.168.1.170
  1. 设置实验箱IP地址,在secureCRT下,输入:
ifconfig eth0 192.168.1.180
  1. 然后三个系统之间互相ping一下,看是否能ping通,注意,一定要ping通才能做接下来的实验

第二步:编写并编译好驱动程序和测试驱动的程序

编写直流电机驱动程序dc_motor.c

/*---------------------------------------

*功能描述:  直流电机驱动 

*创建者:   粤嵌技术部

*创建时间: 2017,01,01

---------------------------------------

*修改日志:

*修改内容:

*修改人:

*修改时间:

----------------------------------------*/



/*************************************************

*头文件

*************************************************/

#include <linux/kernel.h>

#include <linux/module.h>

#include <linux/miscdevice.h>

#include <linux/fs.h>

#include <linux/types.h>

#include <linux/moduleparam.h>

#include <linux/slab.h>

#include <linux/ioctl.h>

#include <linux/cdev.h>

#include <linux/delay.h>

#include <linux/gpio.h>

#include <mach/gpio.h>

#include <mach/platform.h>

#include <asm/gpio.h>







#define DEVICE_NAME      "dc_motor"            //设备名字      



//电机管脚

static int motor_gpios[] = {

	(PAD_GPIO_C + 24),

	(PAD_GPIO_C + 25),

};



#define MOTOR_NUM		ARRAY_SIZE(motor_gpios) //电机的数量



/*************************************************

*电机初始化

*************************************************/

static void motor_init(void)

{

	gpio_set_value(motor_gpios[0], 0);

	gpio_set_value(motor_gpios[1], 0);

}



/*************************************************

*电机正传

*************************************************/

static void motor_foreward(void)

{

	gpio_set_value(motor_gpios[0], 1);

	gpio_set_value(motor_gpios[1], 0);

}



/*************************************************

*电机反转

*************************************************/

static void motor_rollback(void)

{

	gpio_set_value(motor_gpios[1], 1);

	gpio_set_value(motor_gpios[0], 0);

}



/*************************************************

*电机设备打开

*************************************************/

static int gec6818_motor_open(struct inode *inode, struct file *filp)

{

	printk(DEVICE_NAME ":open\n");

	motor_init();

	return 0;

}



/*************************************************

*电机控制程序

*************************************************/

static long gec6818_motor_ioctl(struct file *filp, unsigned int cmd,

		unsigned long arg)

{

	switch(cmd) {

		case 0:

			if (arg > MOTOR_NUM) {

				return -EINVAL;

			}

			motor_init();

			printk("Motor Stop.\n");

			break;

			

		case 1:

			if (arg > MOTOR_NUM) {

				return -EINVAL;

			}

			motor_rollback();

			printk("Motor Rollback.\n");

			break;

		case 4:

			if (arg > MOTOR_NUM) {

				return -EINVAL;

			}		

			motor_foreward();

			printk("Motor Foreward.\n");

			break;



		default:

			return -EINVAL;

	}



	return 0;

}



/*************************************************

*文件操作集

*************************************************/

static struct file_operations gec6818_motor_dev_fops = {

	.owner			= THIS_MODULE,

	.unlocked_ioctl	= gec6818_motor_ioctl,

	.open = gec6818_motor_open

};



/*************************************************

*杂项设备

*************************************************/

static struct miscdevice gec6818_motor_dev = {

	.minor			= MISC_DYNAMIC_MINOR,

	.name			= DEVICE_NAME,

	.fops			= &gec6818_motor_dev_fops,

};



/********************************************************************

*驱动的初始化函数--->从内核中申请资源(内核、中断、设备号、锁....)

********************************************************************/

static int __init gec6818_motor_dev_init(void)

{

	int ret;

	int i;

	

	for (i = 0; i < MOTOR_NUM; i++) {

		ret = gpio_request(motor_gpios[i], "MOTOR");

		if (ret) {

			printk("%s: request GPIO %d for MOTOR failed, ret = %d\n", DEVICE_NAME,

					motor_gpios[i], ret);

			return ret;

		}

		gpio_direction_output(motor_gpios[i], 0);

	}

	gpio_set_value(motor_gpios[0], 0);

	gpio_set_value(motor_gpios[1], 0);



	ret = misc_register(&gec6818_motor_dev);



	printk(DEVICE_NAME"\tinitialized\n");



	return ret;

}



/*****************************************************************

*驱动退出函数 --->将申请的资源还给内核

*****************************************************************/

static void __exit gec6818_motor_dev_exit(void) 

{

	int i;

	for (i = 0; i < MOTOR_NUM; i++) {

		gpio_free(motor_gpios[i]);

	}



	misc_deregister(&gec6818_motor_dev);

}



module_init(gec6818_motor_dev_init);                //驱动的入口函数会调用一个用户的初始化函数

module_exit(gec6818_motor_dev_exit);                //驱动的出口函数会调用一个用户的退出函数



//驱动的描述信息: #modinfo  *.ko , 驱动的描述信息并不是必需的。

MODULE_AUTHOR("kaoyangou");                         //驱动的作者

MODULE_DESCRIPTION("Dc_Motor of driver");           //驱动的描述

MODULE_LICENSE("GPL");                              //遵循的协议


上一篇:基于RT-Thread的CAN电机驱动板设计 (四)使用PIN设备配置按键中断实现电机启停


下一篇:C的一些标准