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

2023-12-27 00:38

本文主要是介绍Tcar:智能车之基于L298N电机驱动芯片的驱动模块,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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 10void 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;}}
}


这篇关于Tcar:智能车之基于L298N电机驱动芯片的驱动模块的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/541340

相关文章

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

智能交通(二)——Spinger特刊推荐

特刊征稿 01  期刊名称: Autonomous Intelligent Systems  特刊名称: Understanding the Policy Shift  with the Digital Twins in Smart  Transportation and Mobility 截止时间: 开放提交:2024年1月20日 提交截止日

基于 YOLOv5 的积水检测系统:打造高效智能的智慧城市应用

在城市发展中,积水问题日益严重,特别是在大雨过后,积水往往会影响交通甚至威胁人们的安全。通过现代计算机视觉技术,我们能够智能化地检测和识别积水区域,减少潜在危险。本文将介绍如何使用 YOLOv5 和 PyQt5 搭建一个积水检测系统,结合深度学习和直观的图形界面,为用户提供高效的解决方案。 源码地址: PyQt5+YoloV5 实现积水检测系统 预览: 项目背景

【C++学习笔记 20】C++中的智能指针

智能指针的功能 在上一篇笔记提到了在栈和堆上创建变量的区别,使用new关键字创建变量时,需要搭配delete关键字销毁变量。而智能指针的作用就是调用new分配内存时,不必自己去调用delete,甚至不用调用new。 智能指针实际上就是对原始指针的包装。 unique_ptr 最简单的智能指针,是一种作用域指针,意思是当指针超出该作用域时,会自动调用delete。它名为unique的原因是这个

Jenkins构建Maven聚合工程,指定构建子模块

一、设置单独编译构建子模块 配置: 1、Root POM指向父pom.xml 2、Goals and options指定构建模块的参数: mvn -pl project1/project1-son -am clean package 单独构建project1-son项目以及它所依赖的其它项目。 说明: mvn clean package -pl 父级模块名/子模块名 -am参数

寻迹模块TCRT5000的应用原理和功能实现(基于STM32)

目录 概述 1 认识TCRT5000 1.1 模块介绍 1.2 电气特性 2 系统应用 2.1 系统架构 2.2 STM32Cube创建工程 3 功能实现 3.1 代码实现 3.2 源代码文件 4 功能测试 4.1 检测黑线状态 4.2 未检测黑线状态 概述 本文主要介绍TCRT5000模块的使用原理,包括该模块的硬件实现方式,电路实现原理,还使用STM32类