1、使用串口GPP8,GPP12口控制电机运转引脚(1-1:停止;1-0:正转;0-1:反转)
驱动代码:
#include <linux/module.h>
//kernel.h以便使用printk()等函数
#include <linux/kernel.h>
//fs.h包含常用的数据结构,如struct file等
#include <linux/fs.h>
//uaccess.h 包含copy_to_user(),copy_from_user()等函数
#include <linux/uaccess.h>
//io.h 包含inl(),outl(),readl(),writel()等IO口操作函数
#include <linux/io.h>
#include <linux/miscdevice.h>
#include <linux/pci.h>
//init.h来指定你的初始化和清理函数,例如:module_init(init_function)、module_exit(cleanup_function)
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/gpio.h>
//irq.h中断与并发请求事件
#include <asm/irq.h>
//下面这些头文件是IO口在内核的虚拟映射地址,涉及IO口的操作所必须包含
//#include <mach/gpio.h>
#include <mach/regs-gpio.h>
#include <plat/gpio-cfg.h>
#include <mach/hardware.h>
#include <mach/map.h>
#define DEVICE_NAME "motor"
#define MOTOR_MAJOR 240 /*主设备号*/
enum ENUM_MOTOR_MOVE_TYPE
{
ENUM_MOTOR_STOP,
ENUM_MOTOR_FORWARD,
ENUM_MOTOR_BACK
};
int motor_open(struct inode *inode,struct file *file)
{
s3c_gpio_cfgpin(S3C64XX_GPP(8),S3C_GPIO_OUTPUT);
s3c_gpio_cfgpin(S3C64XX_GPP(12),S3C_GPIO_OUTPUT);
return 0;
}
static long motor_ioctl ( struct file *file, unsigned int temp, unsigned long cmd)
{
printk("<0>" "cmd:%d\r\n", cmd);
printk("<0>" "back:%d\r\n", ENUM_MOTOR_BACK);
switch(cmd) {
case ENUM_MOTOR_STOP:
{
gpio_set_value(S3C64XX_GPP(8),0);
gpio_set_value(S3C64XX_GPP(12),0);
}
break;
case ENUM_MOTOR_FORWARD:
{
gpio_set_value(S3C64XX_GPP(8),1);
gpio_set_value(S3C64XX_GPP(12),0);
}
break;
case ENUM_MOTOR_BACK:
{
gpio_set_value(S3C64XX_GPP(8),0);
gpio_set_value(S3C64XX_GPP(12),1);
}
break;
default:
break;
}
return 0;
}
int motor_release(struct inode *inode,struct file *file)
{
return 0;
}
struct file_operations motor_fops = {
.owner = THIS_MODULE,
.open = motor_open,
.unlocked_ioctl = motor_ioctl,
.release = motor_release,
};
int __init motor_init(void)
{
int rc;
rc = register_chrdev(MOTOR_MAJOR, DEVICE_NAME,&motor_fops);
if (rc < 0)
{
return -1;
}
return 0;
}
void __exit motor_exit(void)
{
unregister_chrdev(MOTOR_MAJOR, DEVICE_NAME);
}
MODULE_LICENSE("GPL");
module_init(motor_init);
module_exit(motor_exit);
应用程序代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
enum ENUM_MOTOR_MOVE_TYPE
{
ENUM_MOTOR_STOP,
ENUM_MOTOR_FORWARD,
ENUM_MOTOR_BACK
};
int main (int argc, char **argv)
{
int fd;
char buf[10]={0,1};
int motorMove = ENUM_MOTOR_STOP;
fd = open("/dev/motor", 2, 0777);
if (fd < 0)
{
printf ("Open /dev/motor file error\n");
return -1;
}
motorMove = strtoul(argv[1], 0, 0);
printf("move:%d\r\n", motorMove);
ioctl(fd, 0, motorMove);
close (fd);
return 0;
}
遇到的问题:
1、最开始时在驱动代码motor_ioctl ()函数中使用第二个参数作为控制电机转动方向的参数时,当值为2时,总是不能调用motor_ioctl 函数。后面使用motor_ioctl ()函数的第三个参数作为控制电机转动方向的参数,则问题就解决了。具体原因暂时没有查看。