当前位置: 首页 > news >正文

C语言模块化编程思维以及直流电机控制(第四天)

在这里插入图片描述


👨‍💻个人主页:@开发者-削好皮的Pineapple!

👨‍💻 hello 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅!

👨‍💻 本文由 削好皮的Pineapple! 原创

👨‍💻 收录于专栏:C语言到基于STM32 的智能矿探小车


请添加图片描述

请添加图片描述

文章目录

    • 前言
    • 🎶一、模块化编程思维
    • 🎶二、直流电机
      • 2.1 电机驱动模块
    • 🎶三、小车运动控制代码实现
      • 3.1 小车控制函数(`car.c`/`car.h`)
      • 3.2 程序下载与运行设置
      • 3.3 速度控制
        • 结束语🥇


前言

今天是实习培训的新一天,学习聚焦于模块化编程思维以及直流电机控制相关知识,包括电机驱动模块的使用、小车运动控制代码的实现以及PWM技术在速度调节中的应用,为后续智能矿探小车的开发进一步夯实基础。


🎶一、模块化编程思维


模块化编程是按照不同功能将程序拆分为对应的源文件(.c)和头文件(.h),以提高代码的可维护性和复用性。

  • 源文件(.c):用于保存函数接口的具体实现。
    例如led.c
    void led_init(void)
    {// 初始化LED的具体代码
    }
    void led_ctrl(...)
    {// 控制LED的具体代码
    }
    
#include "led.h"
#include "stm32f4xx.h"void LED_Init(void)
{// 使能GPIOF和GPIOE外设时钟RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_GPIOE, ENABLE);GPIO_InitTypeDef GPIO_InitStruct;// 配置GPIOF的LED引脚(D1、D2)GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;GPIO_Init(GPIOF, &GPIO_InitStruct);// 配置GPIOE的LED引脚(D3、D4)GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14;GPIO_Init(GPIOE, &GPIO_InitStruct);// 默认关闭所有LEDGPIO_SetBits(GPIOF, GPIO_Pin_9 | GPIO_Pin_10);GPIO_SetBits(GPIOE, GPIO_Pin_13 | GPIO_Pin_14);
}void LED_Control(LEDNUM led_num, LEDSTA state)
{switch(led_num){case LED_D1:if(state == LED_ON)GPIO_ResetBits(GPIOF, GPIO_Pin_9);elseGPIO_SetBits(GPIOF, GPIO_Pin_9);break;case LED_D2:if(state == LED_ON)GPIO_ResetBits(GPIOF, GPIO_Pin_10);elseGPIO_SetBits(GPIOF, GPIO_Pin_10);break;case LED_D3:if(state == LED_ON)GPIO_ResetBits(GPIOE, GPIO_Pin_13);elseGPIO_SetBits(GPIOE, GPIO_Pin_13);break;case LED_D4:if(state == LED_ON)GPIO_ResetBits(GPIOE, GPIO_Pin_14);elseGPIO_SetBits(GPIOE, GPIO_Pin_14);break;}
}
  • 头文件(.h):用于保存函数声明、构造类型定义、全局变量声明等,且需添加防止重复包含的预处理指令。
    例如led.h
    #ifndef _LED_H  // 如果未定义_LED_H
    #define _LED_H  // 定义_LED_H,防止头文件重复包含// 函数声明
    void led_init(void);
    void led_ctrl(...);// 全局变量声明
    // 构造类型定义#endif
    
#ifndef _LED_H
#define _LED_H#include <stdint.h>  // 添加此头文件以使用uint8_ttypedef enum {LED_D1,LED_D2,LED_D3,LED_D4
} LEDNUM;typedef enum {LED_OFF,LED_ON
} LEDSTA;void LED_Init(void);
void LED_Control(LEDNUM led_num, LEDSTA state);#endif
  • 常见模块示例
    • delay.c/delay.h:实现延时功能,如void delay_ms(uint16_t nms);(毫秒级延时)、void delay_us(uint16_t us);(微秒级延时)。

🎶二、直流电机


2.1 电机驱动模块

  • 接线说明

    • 两个绿色端子:直接连接直流电机。
      在这里插入图片描述

    • 6个排针:

      • VCC:接5V或3.3V(5V驱动时小车力度大,状态改变较难;3.3V驱动时力度小,状态改变相对容易)。
      • GND:接GND(注意正负极不可接反)。
      • 控制引脚:B-1AB-1B用于控制一个电机,A-1AA-1B用于控制另一个电机,具体对应哪个电机需看实物绿色端子的连接。以下是本次实训所用驱动电路板。
        在这里插入图片描述
        引脚依次是:B-1A、B-1B、GND、VCC、A-1A、A-1B
  • 电机转动原理:直流电机由两个引脚驱动,当两个引脚电平状态不同时电机转动。

    • 假设B-1A为高电平、B-1B为低电平时,电机向前转动;则B-1A为低电平、B-1B为高电平时,电机向后转动。
    • B-1AB-1B均为低电平或均为高电平时,电机停止转动。
  • 可用GPIO引脚:在CAMERA处有部分GPIO引脚可用于连接控制,如2脚(GND)、4脚(PD6)、6脚、8脚、10脚…1脚(3V3)、3脚(PB7)、5脚、7脚、9脚…根据原理图(GEC-M4原理图2016-07-29.pdf)可得:
    在这里插入图片描述


🎶三、小车运动控制代码实现


3.1 小车控制函数(car.c/car.h

  • 小车初始化函数
 void car_Init(void)
{//1.时钟使能RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOD , ENABLE);//2.初始化GPIO ---> 推挽输出模式 GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;GPIO_Init(GPIOD, &GPIO_InitStruct);// 配置GPIOE的LED引脚GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7| GPIO_Pin_6;GPIO_Init(GPIOB, &GPIO_InitStruct);//3.默认状态:小车停止GPIO_SetBits(GPIOD, GPIO_Pin_6 | GPIO_Pin_7);//左GPIO_SetBits(GPIOB, GPIO_Pin_6 | GPIO_Pin_7);//右
}
  • 基本运动控制函数
    • 前进:
 int speed = 100;
void car_up(void)		
{//左轮电机前转GPIO_ResetBits(GPIOD, GPIO_Pin_6 );//A-1BGPIO_SetBits(GPIOD, GPIO_Pin_7 );//	A-1A//右轮电机前转GPIO_ResetBits(GPIOB, GPIO_Pin_6 );//B-1AGPIO_SetBits(GPIOB, GPIO_Pin_7 );//B-1Bdelay_ms(speed);GPIO_SetBits(GPIOB, GPIO_Pin_6 | GPIO_Pin_7);//右delay_ms(100-speed);	
}
  • 后退:
void car_back(void)
{//左轮电机后转GPIO_ResetBits(GPIOD, GPIO_Pin_7 );GPIO_SetBits(GPIOD, GPIO_Pin_6 );			//右轮电机后转GPIO_ResetBits(GPIOB, GPIO_Pin_7 );GPIO_SetBits(GPIOB, GPIO_Pin_6 );			
}
  • 左转:
    void car_left(void)
{//左轮不转 (后转)GPIO_SetBits(GPIOD, GPIO_Pin_6 | GPIO_Pin_7);//右轮前进GPIO_ResetBits(GPIOB, GPIO_Pin_6 );GPIO_SetBits(GPIOB, GPIO_Pin_7 );
}
- 右转:
void car_right(void)
{//右轮不转 (后转)GPIO_SetBits(GPIOB, GPIO_Pin_6 | GPIO_Pin_7);//左轮前进GPIO_ResetBits(GPIOD, GPIO_Pin_6 );GPIO_SetBits(GPIOD, GPIO_Pin_7 );
}
  • 停止:
void car_stop(void)
{//右轮和左轮子都不转GPIO_SetBits(GPIOD, GPIO_Pin_6 | GPIO_Pin_7);GPIO_SetBits(GPIOB, GPIO_Pin_6 | GPIO_Pin_7);
}

3.2 程序下载与运行设置

  • 下载程序时BOOT0接3V3,BOOT1接GND,按下复位键,CPU执行引导程序,程序可下载到开发板。
  • 下载完成后BOOT0接GND,BOOT1接GND,重新上电或按复位键,程序重新运行。

3.3 速度控制

  • 简单速度调节(上面已经实现):通过控制电机转动与停止的时间比例来调节速度。

    int speed = 100;
    void car_up(void)
    {// 左轮电机前转// 右轮电机前转(右轮速度调节)B-1A = 1;B-1B = 0;  // 右轮转动delay_ms(speed);B-1B = 1;  // 右轮停止转动delay_ms(100 - speed);
    }
    
  • PWM(脉冲宽度调制):通过调节有效电平时间与整个周期的比例(占空比)来精确控制电机转速、蜂鸣器鸣叫等。

    • 占空比 = 有效电平时间 / 整个周期。
    • 例如:有效电平时间50ms,周期100ms,占空比为50%。
    • 注意:使用PWM调节的周期不能太长。
  • 主函数示例

    int main()
    {while(1){car_up();  // 小车前进}
    }
    
  • 练习目标:调节小车轮子速度,使小车前进1m左右。
    在这里插入图片描述
    在这里插入图片描述

请添加图片描述

结束语🥇

🔥 订阅专栏持续学习:C语言到基于STM32的智能矿探小车
💬 欢迎点赞、收藏、留言讨论,一起攻克嵌入式开发!

http://www.dtcms.com/a/271488.html

相关文章:

  • 深度学习——损失函数
  • 【使用Flask基于PaddleOCR3.0开发一个接口 调用时报错RuntimeError: std::exception】
  • JVM调优实战指南:让Java程序性能飞升的奥秘
  • PanTS: The Pancreatic Tumor Segmentation Dataset
  • 使用anaconda创建基础环境
  • 数据分析框架和方法
  • 数据分析-名词
  • pip 安装加速指南:配置国内镜像源(中国科技大学、清华、阿里云等)
  • Java武林:虚拟机之道 第七章:秘籍解析 - JVM调优参数
  • 经验分享-没有xcode也可以上传App Store Connect
  • S7-1500——(一)从入门到精通1、基于TIA 博途解析PLC程序结构(一)
  • c语言中的数组II
  • 景观桥 涵洞 城门等遮挡物对汽车安全性的影响数学建模和计算方法,需要收集那些数据
  • 周立功汽车软件ZXDoc深度解析:新能源汽车开发新基建的破局之道
  • java 语法类新特性总结
  • 【王树森推荐系统】排序05:排序模型的特征
  • 计蒜客T3473丑数、Leetcode2401最长优雅子数组、Leetcode167两数之和、Leetcode581最短无序连续子数组
  • 深度帖:浏览器的事件循环与JS异步
  • 【教程】基于GNN的药物相互作用网络中的链接预测
  • 数据一致性解决方案总结
  • Linux驱动04 --- 网络编程TCP客户端
  • 暑假读书笔记第五天
  • 深入剖析Elasticsearch倒排索引,Query DSL查询使用场景分析
  • lwip+8720+裸机+先上电在插网线 ping不同
  • HashMap的get、put流程源码分析
  • jenkins+固定agent节点+maven+sonarqube+docker
  • uniapp小程序无感刷新token
  • 数据结构之位图和布隆过滤器
  • ReactNative【实战系列教程】我的小红书 5 -- 文章详情(含轮播图 ImageSlider,点亮红心动画 Heart,嵌套评论等)
  • 【三维重建】一、设备分类