📄 gpio_motor.c
字号:
/*********************************
版 权:
文 件 名:gpio_motor.c
作 者:狄兰兰
创建日期:20090207
版 本:02.00.00
功能描述:云台电机驱动程序 完成云台上、下、左、右
左上、右上、左下、右下八个方向的转动和预置位
修改历程:1、20090207 创建
*********************************/
#include <linux/module.h>
#include <linux/config.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/fcntl.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/workqueue.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/io.h>
#include "gpio_motor.h"
static void __iomem *gpio0_map_addr;
static void __iomem *gpio1_map_addr;
unsigned int GPIO0_BASE_MMAP;
unsigned int GPIO1_BASE_MMAP;
#define GPIO0_BASE 0x101e4000
#define GPIO1_BASE 0x101e5000
#define GPIO0_DIR (GPIO0_BASE_MMAP + 0x400)
#define GPIO1_DIR (GPIO1_BASE_MMAP + 0x400)
#define GPIO0_DATA_UPDOWN (GPIO0_BASE_MMAP + 0x3C)
#define GPIO0_DATA_LEFTRIGHT (GPIO0_BASE_MMAP + 0x3C0)
#define GPIO1_DATA_LEFT (GPIO1_BASE_MMAP + 0x40)
#define GPIO1_DATA_RIGHT (GPIO1_BASE_MMAP + 0x80)
#define GPIO1_DATA_UP (GPIO1_BASE_MMAP + 0x100)
#define GPIO1_DATA_DOWN (GPIO1_BASE_MMAP + 0x200)
#define HW_REG(reg) *((volatile unsigned int *)(reg))
#define SPEED 10
static unsigned int left_count = 400; //相对于最右转过的次数
static unsigned int up_count = 140; //相对于最下转过的次数
/*
* horizontal direction ,left position is limited or not flag
* return value: 1:limited , 0:not limited
*/
static unsigned char motor_left_limited(void)
{
unsigned char regvalue;
regvalue = HW_REG(GPIO1_DIR);
regvalue &= 0xef;
HW_REG(GPIO1_DIR) = regvalue;
if(HW_REG(GPIO1_DATA_LEFT) == 0)
{
return 1;
}
else
{
return 0;
}
}
/*
* horizontal direction ,right position is limited or not flag
* return value: 1:limited , 0:not limited
*/
static unsigned char motor_right_limited(void)
{
unsigned char regvalue;
regvalue = HW_REG(GPIO1_DIR);
regvalue &= 0xdf;
HW_REG(GPIO1_DIR) = regvalue;
if(HW_REG(GPIO1_DATA_RIGHT) == 0)
{
return 1;
}
else
{
return 0;
}
}
/*
* vertical direction ,up position is limited or not flag
* return value: 1:limited , 0:not limited
*/
static unsigned char motor_up_limited(void)
{
unsigned char regvalue;
regvalue = HW_REG(GPIO1_DIR);
regvalue &= 0xbf;
HW_REG(GPIO1_DIR) = regvalue;
if(HW_REG(GPIO1_DATA_UP) == 0)
{
return 1;
}
else
{
return 0;
}
}
/*
* vertical direction ,down position is limited or not flag
* return value: 1:limited , 0:not limited
*/
static unsigned char motor_down_limited(void)
{
unsigned char regvalue;
regvalue = HW_REG(GPIO1_DIR);
regvalue &= 0x7f;
HW_REG(GPIO1_DIR) = regvalue;
if(HW_REG(GPIO1_DATA_DOWN) == 0)
{
return 1;
}
else
{
return 0;
}
}
/*
* vertical direction ,the first step
*/
static void motor_ud_step1(void)
{
unsigned char regvalue;
regvalue = HW_REG(GPIO0_DIR);
regvalue |= 0x0f;
HW_REG(GPIO0_DIR) = regvalue;
HW_REG(GPIO0_DATA_UPDOWN) = 0x01;
}
/*
* vertical direction ,the second step
*/
static void motor_ud_step2(void)
{
unsigned char regvalue;
regvalue = HW_REG(GPIO0_DIR);
regvalue |= 0x0f;
HW_REG(GPIO0_DIR) = regvalue;
HW_REG(GPIO0_DATA_UPDOWN) = 0x03;
}
/*
* vertical direction ,the third step
*/
static void motor_ud_step3(void)
{
unsigned char regvalue;
regvalue = HW_REG(GPIO0_DIR);
regvalue |= 0x0f;
HW_REG(GPIO0_DIR) = regvalue;
HW_REG(GPIO0_DATA_UPDOWN) = 0x02;
}
/*
* vertical direction ,the fourth step
*/
static void motor_ud_step4(void)
{
unsigned char regvalue;
regvalue = HW_REG(GPIO0_DIR);
regvalue |= 0x0f;
HW_REG(GPIO0_DIR) = regvalue;
HW_REG(GPIO0_DATA_UPDOWN) = 0x06;
}
/*
* vertical direction ,the fifth step
*/
static void motor_ud_step5(void)
{
unsigned char regvalue;
regvalue = HW_REG(GPIO0_DIR);
regvalue |= 0x0f;
HW_REG(GPIO0_DIR) = regvalue;
HW_REG(GPIO0_DATA_UPDOWN) = 0x04;
}
/*
* vertical direction ,the sixth step
*/
static void motor_ud_step6(void)
{
unsigned char regvalue;
regvalue = HW_REG(GPIO0_DIR);
regvalue |= 0x0f;
HW_REG(GPIO0_DIR) = regvalue;
HW_REG(GPIO0_DATA_UPDOWN) = 0x0c;
}
/*
* vertical direction ,the seventh step
*/
static void motor_ud_step7(void)
{
unsigned char regvalue;
regvalue = HW_REG(GPIO0_DIR);
regvalue |= 0x0f;
HW_REG(GPIO0_DIR) = regvalue;
HW_REG(GPIO0_DATA_UPDOWN) = 0x08;
}
/*
* vertical direction ,the eighth step
*/
static void motor_ud_step8(void)
{
unsigned char regvalue;
regvalue = HW_REG(GPIO0_DIR);
regvalue |= 0x0f;
HW_REG(GPIO0_DIR) = regvalue;
HW_REG(GPIO0_DATA_UPDOWN) = 0x09;
}
/*
* horizontal direction ,the first step
*/
static void motor_lr_step1(void)
{
unsigned char regvalue;
regvalue = HW_REG(GPIO0_DIR);
regvalue |= 0xf0;
HW_REG(GPIO0_DIR) = regvalue;
HW_REG(GPIO0_DATA_LEFTRIGHT) = 0x10;
}
/*
* horizontal direction ,the second step
*/
static void motor_lr_step2(void)
{
unsigned char regvalue;
regvalue = HW_REG(GPIO0_DIR);
regvalue |= 0xf0;
HW_REG(GPIO0_DIR) = regvalue;
HW_REG(GPIO0_DATA_LEFTRIGHT) = 0x30;
}
/*
* horizontal direction ,the third step
*/
static void motor_lr_step3(void)
{
unsigned char regvalue;
regvalue = HW_REG(GPIO0_DIR);
regvalue |= 0xf0;
HW_REG(GPIO0_DIR) = regvalue;
HW_REG(GPIO0_DATA_LEFTRIGHT) = 0x20;
}
/*
* horizontal direction ,the fourth step
*/
static void motor_lr_step4(void)
{
unsigned char regvalue;
regvalue = HW_REG(GPIO0_DIR);
regvalue |= 0xf0;
HW_REG(GPIO0_DIR) = regvalue;
HW_REG(GPIO0_DATA_LEFTRIGHT) = 0x60;
}
/*
* horizontal direction ,the fifth step
*/
static void motor_lr_step5(void)
{
unsigned char regvalue;
regvalue = HW_REG(GPIO0_DIR);
regvalue |= 0xf0;
HW_REG(GPIO0_DIR) = regvalue;
HW_REG(GPIO0_DATA_LEFTRIGHT) = 0x40;
}
/*
* horizontal direction ,the sixth step
*/
static void motor_lr_step6(void)
{
unsigned char regvalue;
regvalue = HW_REG(GPIO0_DIR);
regvalue |= 0xf0;
HW_REG(GPIO0_DIR) = regvalue;
HW_REG(GPIO0_DATA_LEFTRIGHT) = 0xc0;
}
/*
* horizontal direction ,the seventh step
*/
static void motor_lr_step7(void)
{
unsigned char regvalue;
regvalue = HW_REG(GPIO0_DIR);
regvalue |= 0xf0;
HW_REG(GPIO0_DIR) = regvalue;
HW_REG(GPIO0_DATA_LEFTRIGHT) = 0x80;
}
/*
* horizontal direction ,the eighth step
*/
static void motor_lr_step8(void)
{
unsigned char regvalue;
regvalue = HW_REG(GPIO0_DIR);
regvalue |= 0xf0;
HW_REG(GPIO0_DIR) = regvalue;
HW_REG(GPIO0_DATA_LEFTRIGHT) = 0x90;
}
/*
* delays for a specified number of milliseconds rountine.
* @param msec: number of milliseconds to pause for
*/
void time_delay_ms(unsigned char msec)
{
int i,j;
for(i=0;i<msec * 246;i++)
{
for(j=0;j<100;j++)
{;}
}
}
/*
* vertical direction rotate up
* param count: the angle of any rotation ( count*(5.625/8) )
* return 0:successfully rotated
* return 1:cannot rotate
*/
static int motor_rotate_up(unsigned char count)
{
unsigned char i;
for(i = 0;i < count;i ++)
{
if(motor_up_limited())
{
up_count = 0;
return 1;
}
motor_ud_step1();
time_delay_ms(SPEED);
if(motor_up_limited())
{
up_count = 0;
return 1;
}
motor_ud_step2();
time_delay_ms(SPEED);
if(motor_up_limited())
{
up_count = 0;
return 1;
}
motor_ud_step3();
time_delay_ms(SPEED);
if(motor_up_limited())
{
up_count = 0;
return 1;
}
motor_ud_step4();
time_delay_ms(SPEED);
if(motor_up_limited())
{
up_count = 0;
return 1;
}
motor_ud_step5();
time_delay_ms(SPEED);
if(motor_up_limited())
{
up_count = 0;
return 1;
}
motor_ud_step6();
time_delay_ms(SPEED);
if(motor_up_limited())
{
up_count = 0;
return 1;
}
motor_ud_step7();
time_delay_ms(SPEED);
if(motor_up_limited())
{
up_count = 0;
return 1;
}
motor_ud_step8();
time_delay_ms(SPEED);
up_count --;
}
return 0;
}
/*
* vertical direction rotate down
* param count: the angle of any rotation ( count*(5.625/8) )
* return 0:successfully rotated
* return 1:cannot rotate
*/
static int motor_rotate_down(unsigned char count)
{
unsigned char i;
for(i = 0;i < count;i ++)
{
if(motor_down_limited())
{
return 1;
}
motor_ud_step8();
time_delay_ms(SPEED);
if(motor_down_limited())
{
return 1;
}
motor_ud_step7();
time_delay_ms(SPEED);
if(motor_down_limited())
{
return 1;
}
motor_ud_step6();
time_delay_ms(SPEED);
if(motor_down_limited())
{
return 1;
}
motor_ud_step5();
time_delay_ms(SPEED);
if(motor_down_limited())
{
return 1;
}
motor_ud_step4();
time_delay_ms(SPEED);
if(motor_down_limited())
{
return 1;
}
motor_ud_step3();
time_delay_ms(SPEED);
if(motor_down_limited())
{
return 1;
}
motor_ud_step2();
time_delay_ms(SPEED);
if(motor_down_limited())
{
return 1;
}
motor_ud_step1();
time_delay_ms(SPEED);
up_count ++;
}
return 0;
}
/*
* horizontial direction rotate left
* @param count: the angle of any rotation ( count*(5.625/8) )
* return 0:successfully rotated
* return 1:cannot rotate
*/
static int motor_rotate_left(unsigned char count)
{
unsigned char i;
for(i = 0;i < count;i ++)
{
if(motor_left_limited())
{
left_count = 0;
return 1;
}
motor_lr_step1();
time_delay_ms(SPEED);
if(motor_left_limited())
{
left_count = 0;
return 1;
}
motor_lr_step2();
time_delay_ms(SPEED);
if(motor_left_limited())
{
left_count = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -