您的位置:首页 > 其它

Tcar:智能车之基于L298N电机驱动芯片的驱动模块

2017-03-27 23:17 453 查看
2、电机驱动模块 - L298N电机驱动芯片

   // env/motor.zip

   两个直流电机,控制前轮的用于转向

                 控制后轮的用于前进后退

   编程,让用户方便的控制小车的运动

   2.1 电机的驱动

       硬件的接法:

           电机上需要的瞬间电流可能是安培级的

           而CPU上的管脚输出的电流是毫安级的

                 

       直流电机 步进电机 伺服电机

       

       L298N芯片 有15个引脚,可以驱动两台直流电机

           ENABLE A

           INPUT 1/2

           ENABLE B

           INPUT 3/4

       软件控制直流电机,就是控制L298N芯片

       如何控制L298N?

          M1正转: 

                  ENABLEA 高

                  INPUT1  高

                  INPUT2  低



       控制L298N 就是控制CPU上对应的管脚

    2.2 应用程序

       gui_client: 

           5个按钮

           点击按钮时给server 发不同的命令

              

       开发板上的server

           接收到命令

           根据不同的命令  

               open

               ioctl(...) 

           具体到小车 udp server 8000

                      30/31/32/33/34
// tcar_src.tar.gz/motor/app(应用) driver(驱动)
// 驱动代码基于S5PV210开发板编程的,非S5P6818

/* motor_drv.c - 基于S5PV210开发板连接的L298N芯片驱动 */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <mach/gpio.h>
#include <asm/io.h>
#include <linux/timer.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>

#include "motor_cmd.h"

#define TCAR_ENA    S5PV210_GPH3(2)
#define TCAR_IN1    S5PV210_GPH2(2)
#define TCAR_IN2    S5PV210_GPH3(1)
#define TCAR_ENB    S5PV210_GPH2(0)
#define TCAR_IN3    S5PV210_GPH2(1)
#define TCAR_IN4    S5PV210_GPH3(0)

typedef struct _tcar_gpios
{
unsigned int gpio_no;
const char *name;
}tcar_gpios_t;

tcar_gpios_t gpio_pins[] ={
{
.gpio_no = TCAR_ENA,
.name   = "GPH3_2"
},
{
.gpio_no = TCAR_IN1,
.name   = "GPH2_2"
},
{
.gpio_no = TCAR_IN2,
.name   = "GPH3_1"
},
{
.gpio_no = TCAR_ENB,
.name   = "GPH2_0"
},
{
.gpio_no = TCAR_IN3,
.name   = "GPH2_1"
},
{
.gpio_no = TCAR_IN4,
.name   = "GPH3_0"
},
};

struct timer_list tcar_timer;

void tcar_gpio_init(void)
{
int pins_num;
int i  = 0;
pins_num = ARRAY_SIZE(gpio_pins);

for(; i<pins_num; i++)
{
gpio_request(gpio_pins[i].gpio_no, gpio_pins[i].name);
gpio_direction_output(gpio_pins[i].gpio_no, 0);
}
}

static void tcar_forward(void)
{
gpio_direction_output(gpio_pins[0].gpio_no,1);
gpio_direction_output(gpio_pins[1].gpio_no,1);
gpio_direction_output(gpio_pins[2].gpio_no,0);
}
static void tcar_backward(void)
{
gpio_direction_output(gpio_pins[0].gpio_no,1);
gpio_direction_output(gpio_pins[1].gpio_no,0);
gpio_direction_output(gpio_pins[2].gpio_no,1);
}
#define TCAR_TIMER 10

void tcar_timer_handler(unsigned long data)
{
gpio_direction_output(gpio_pins[3].gpio_no,1);
gpio_direction_output(gpio_pins[4].gpio_no,0);
gpio_direction_output(gpio_pins[5].gpio_no,0);
}
static void tcar_left(void)
{
gpio_direction_output(gpio_pins[3].gpio_no,1);
gpio_direction_output(gpio_pins[4].gpio_no,1);
gpio_direction_output(gpio_pins[5].gpio_no,0);

tcar_timer.expires = jiffies + TCAR_TIMER;
tcar_timer.function = tcar_timer_handler;
tcar_timer.data = 0;
add_timer(&tcar_timer);
}
static void tcar_right(void)
{
gpio_direction_output(gpio_pins[3].gpio_no,1);
gpio_direction_output(gpio_pins[4].gpio_no,0);
gpio_direction_output(gpio_pins[5].gpio_no,1);

tcar_timer.expires = jiffies + TCAR_TIMER;
tcar_timer.function = tcar_timer_handler;
tcar_timer.data = 0;
add_timer(&tcar_timer);
}
static void tcar_stop(void)
{
gpio_direction_output(gpio_pins[0].gpio_no,1);
gpio_direction_output(gpio_pins[1].gpio_no,0);
gpio_direction_output(gpio_pins[2].gpio_no,0);

gpio_direction_output(gpio_pins[3].gpio_no,1);
gpio_direction_output(gpio_pins[4].gpio_no,0);
gpio_direction_output(gpio_pins[5].gpio_no,0);

}
static int tcar_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long val)
{
switch (cmd)
{
case TCAR_FORWARD:
tcar_forward();
break;
case TCAR_BACKWARD:
tcar_backward();
break;
case TCAR_LEFT:
tcar_left();
break;
case TCAR_RIGHT:
tcar_right();
break;
case TCAR_STOP:
tcar_stop();
break;
default:
printk("invaild arg!\n");
break;
}
return 0;
}

static struct file_operations tcar_fops =
{
.owner = THIS_MODULE,
.ioctl = tcar_ioctl,
};
static struct miscdevice tcar_miscdev =
{
.minor = MISC_DYNAMIC_MINOR,
.name = "tcar",
.fops = &tcar_fops,
};
static int tcar_init(void)
{
/*申请使用的管脚*/
tcar_gpio_init();
misc_register(&tcar_miscdev);

/*初始化定时器*/
init_timer(&tcar_timer);
return 0;
}
static void tcar_exit(void)
{
int i = 0;
int pins_num = ARRAY_SIZE(gpio_pins);
del_timer(&tcar_timer);
misc_deregister(&tcar_miscdev);
for(; i<pins_num; i++)
{
gpio_free(gpio_pins[i].gpio_no);
}
}
module_init(tcar_init);
module_exit(tcar_exit);
MODULE_LICENSE("GPL");
/* udp_client.c */
#include "tcar.h"
#include "motor_cmd.h"

int main()
{
int sd = socket(PF_INET, SOCK_DGRAM, 0);

struct sockaddr_in addr;
addr.sin_family = PF_INET;
addr.sin_port  = htons(PORT);
addr.sin_addr.s_addr = inet_addr("192.168.1.6");

int cmd = MOTOR_FORWARD;
sendto(sd, &cmd, sizeof(cmd), 0, (struct sockaddr *)&addr, sizeof(addr));
getchar();

cmd = MOTOR_STOP;
sendto(sd, &cmd, sizeof(cmd), 0, (struct sockaddr *)&addr, sizeof(addr));
getchar();

cmd = MOTOR_BACKWARD;
sendto(sd, &cmd, sizeof(cmd), 0, (struct sockaddr *)&addr, sizeof(addr));
getchar();

cmd = MOTOR_STOP;
sendto(sd, &cmd, sizeof(cmd), 0, (struct sockaddr *)&addr, sizeof(addr));
getchar();

cmd = MOTOR_LEFT;
sendto(sd, &cmd, sizeof(cmd), 0, (struct sockaddr *)&addr, sizeof(addr));
getchar();

cmd = MOTOR_RIGHT;
sendto(sd, &cmd, sizeof(cmd), 0, (struct sockaddr *)&addr, sizeof(addr));
getchar();

close(sd);
}

/* udp_server.c */
#include "tcar.h"
#include "motor_cmd.h"

int main()
{
int fd  = 0;
static int to_down_up = 1500;
static int to_right_left = 1500;
int unit = 200;
int sd =  socket(PF_INET, SOCK_DGRAM, 0);

struct sockaddr_in addr;
addr.sin_family = PF_INET;
addr.sin_port   = htons(PORT);
addr.sin_addr.s_addr = inet_addr("192.168.1.6");

bind(sd, (const struct sockaddr *)&addr, sizeof(addr));

while(1)
{
int cmd = 0;
struct sockaddr_in fromaddr;
int len = sizeof(fromaddr);
recvfrom(sd, &cmd, sizeof(cmd), 0, (struct sockaddr *)&fromaddr, &len);
switch(cmd)
{
case VIDEO_UP:
to_down_up += unit;
if(to_down_up >2500)
{
to_down_up = 2500;
}
fd = open("/dev/mg995", O_RDWR);
ioctl(fd, IDEX0, to_down_up);
close(fd);
break;
case VIDEO_DOWN:
to_down_up -= unit;
if(to_down_up < 500)
{
to_down_up = 500;
}
fd = open("/dev/mg995", O_RDWR);
ioctl(fd, IDEX0, to_down_up);
close(fd);
break;
case VIDEO_LEFT:
to_right_left += unit;
if(to_right_left >2500)
{
to_right_left = 2500;
}
fd = open("/dev/mg995", O_RDWR);
ioctl(fd, IDEX1, to_right_left);
close(fd);
break;
case VIDEO_RIGHT:
to_right_left -= unit;
if(to_right_left < 500)
{
to_right_left = 500;
}
fd = open("/dev/mg995", O_RDWR);
ioctl(fd, IDEX1, to_right_left);
close(fd);
break;
case MOTOR_FORWARD:
fd = open("/dev/tcar", O_RDWR);
ioctl(fd, TCAR_FORWARD);
close(fd);
break;
case MOTOR_BACKWARD:
fd = open("/dev/tcar", O_RDWR);
ioctl(fd, TCAR_BACKWARD);
close(fd);
break;
case MOTOR_LEFT:
fd = open("/dev/tcar", O_RDWR);
ioctl(fd, TCAR_LEFT);
close(fd);
break;
case MOTOR_RIGHT:
fd = open("/dev/tcar", O_RDWR);
ioctl(fd, TCAR_RIGHT);
close(fd);
break;
case MOTOR_STOP:
fd = open("/dev/tcar", O_RDWR);
ioctl(fd, TCAR_STOP);
close(fd);
break;
default:
break;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  嵌入式软件 芯片