51单片机学习笔记-13直流电机

news2024/11/8 19:43:11

13 直流电机

[toc]

注:笔记主要参考B站江科大自化协教学视频“51单片机入门教程-2020版 程序全程纯手打 从零开始入门”。
注:工程及代码文件放在了本人的Github仓库。


13.1 直流电机与PWM波

13.1.1 直流电机
直流电机是一种将电能转换为机械能的装置。一般的直流电机有两个电极,当电极正接时,电机正转,当电极反接时,电机反转。直流电机主要由永磁体(定子)、线圈(转子)和换向器组成。除直流电机外,常见的电机还有步进电机、舵机、无刷电机、空心杯电机等。

图13-1 直流电机实物图
图13-2 直流电机原理图及驱动方式

根据上述原理图可以看出,由于单片机的IO口没有驱动能力,所以还是依靠外接的ULN2003D芯片进行驱动。从OUT1~OUT4任选两个端口即可完成驱动。对于直流电机,主要有两种供电方式:

  1. 大功率器件直接驱动:只能单向驱动。图中,续流二极管的作用是防止三极管截止时,直流电机中的电容击穿三极管。
  2. H桥驱动:可以双向驱动。
  3. 当然,开发板上采用的驱动芯片ULN2003D,在之前的“9蜂鸣器”一节已经介绍过。

13.1.2 PWM介绍
UP主最开始自己接了电位器(滑动变阻器)来控制直流电机转速,而电源供电端保持电压不变。最后发现,只有当电阻非常小的时候直流电机才开始转。但是直流电机需要的电流大,很容易就使得变阻器发热甚至烧毁。所以此方法并不好,还是要控制电源端的变化,也就是下面的PWM。
PWM(Pulse Width Modulation)即脉冲宽度调制,在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速、开关电源等领域。PWM重要参数:

  • 频率 = 1/TS。频率越高,平均电压波形的谐波含量就越低。但后续使用生成PWM时,定时器重装频率过快会使主函数执行效率大幅下降。一般设置10~20kHz。
  • 占空比 = TON/TS
  • 精度 = 占空比变化步距

在软件层面,可以使用纯软件延时的方式完成PWM波,常用于“呼吸灯”等需要占空比频繁变化的场合;而对于电机调速这样的场合,期望程序在不调节时保持当前的占空比不变,这种场合下更常用的方法是使用定时器产生PWM波

  1. 对定时器进行计数,计数周期就是PWM波的周期。
  2. 在PWM波发生函数中,设定一个比较阈值,用于控制占空比。
  3. 显然,定时器的精度就是PWM波的精度。
图13-3 使用定时器产生PWM波原理

13.2 实验:LED呼吸灯

需求:全体LED以1秒为周期进行“呼吸式”亮度变化。

注:本实验建议纯软件延时完成PWM调节。即,只有一个主函数。

代码展示:
- mian.c

#include <REGX52.H>

sbit LED0 = P2^0;
unsigned int PWM_Period = 100;
unsigned int PWM_Duty = 99;

// 延时函数一定要有,但单次延时应在10us以下
void Delay(unsigned int cycles){
	while(cycles--);
}

void main(){
  unsigned char i;
  P2 = 0xff; //LED初始全部熄灭
  while(1){
    for(PWM_Duty=0;PWM_Duty<PWM_Period;PWM_Duty++){
      for(i=0;i<10;i++){
        LED0 = 0;
        Delay(PWM_Duty);
        LED0 = 1;
        Delay(PWM_Period-PWM_Duty);
      }
    }
    for(PWM_Duty=PWM_Period-1;PWM_Duty>0;PWM_Duty--){
      for(i=0;i<10;i++){
        LED0 = 0;
        Delay(PWM_Duty);
        LED0 = 1;
        Delay(PWM_Period-PWM_Duty);
      }
    }
  }
}

编程感想:

  1. 关于延时函数:TMD天坑啊!思路其实很简单,但是一定要注意呼吸灯的PWM频率一定要非常快!!量级在1KHz以上(由于PWM周期为100,所以意味着延时函数在10us以下)才会有一个很好的效果。否则就会发现灯亮一下又闪,大晚上一直盯着灯看眼都快瞎了……😖

13.3 实验:直流电机调速

需求:设置直流电机转速等级:Stop、40%、50%、75%、100%。

每按下一次按键Key1,直流电机速度等级就上升一级(上升到最高归零)。
LCD第一行显示“DC motor:”;LCD第二行显示“xxx% Power”,如果为0就闪烁显示“Stop!”。
注:综合考虑程序效率和硬件效果,可设置定时器中断周期100us,PWM周期为100个定时器中断。

图13-4 “直流电机调速”代码调用

代码展示:
-main.c

#include <REGX52.H>
#include "LCD1602.h"
#include "PushKey.h"
#include "Timer0.h"

#define motor P1_0
unsigned int PWM_Peri = 100;
unsigned int PWM_Duty = 0;
unsigned char speed_motor[5] = {0,40,50,75,100};

void main(){
  unsigned char key_num=0;//按键的编号
  unsigned char speed_index=0;//转速等级索引
  //LCD1602初始化
  LCD1602_Init();
  LCD1602_DispString(1,1,"DC motor:");
  LCD1602_DispString(2,1,"Stop!");
  //初始化定时器
  Timer0_Init();
  
  while(1){
    key_num = PushKey_GetKey();
    if(key_num==1){
      speed_index++;
      speed_index%=5;
      //调整PWM占空比(转速)
      PWM_Duty = speed_motor[speed_index];  
    }
    //LCD更新显示转速等级
    switch(speed_index){
      case 0:LCD1602_DispString(2,1,"Stop!     ");break;
      case 1:LCD1602_DispString(2,1," 40% Power");break;
      case 2:LCD1602_DispString(2,1," 50% Power");break;
      case 3:LCD1602_DispString(2,1," 75% Power");break;
      case 4:LCD1602_DispString(2,1,"100% Power");break;
      default:;
    }
  }
}

// 定义定时器T0中断后要执行的动作
void Timer0_Routine() interrupt 1{
  static unsigned int count1_T0,count2_T0; //中断次数
  TH0 = 0xFF; TL0 = 0xA4; // 恢复溢出周期,近似100us
  //对于PWM所需的中断
  count1_T0++; //更新中断次数
  if(count1_T0>PWM_Peri){
    count1_T0 = 0;    
  }else{
    if(count1_T0<PWM_Duty){motor=1;}//电机运行
    else                  {motor=0;}//电机不运行
  }
  //按键检测所需的中断
  count2_T0++; //更新中断次数
  if(count2_T0>20){
    count2_T0 = 0;
    PushKey_Loop();
  }
}

LCD1602.hLCD1602.c与第12节的实验代码相同。PushKey.hTimer0.h与13.2“温度报警器”的代码相同。

编程感想:

  1. 只要直流电机连着,就没法下载程序。必须要拔掉直流电机下载好之后,断电插上直流电机,插电。推测是因为USB所需电流激增,导致电脑主板进行端口保护,就不再进行串口通信??
  2. 直流电机和LCD显示屏冲突:USB电源的电流一般不超过1000MA(一般限流在750mA),当电流大时,电压下降得厉害,不能启动LCD1602。 所以可以使用其他驱动电流小的元件(如数码管),来显示当前的速度等级。
  3. 关于直流电机:注意电机引脚拉高时启动,因为达林顿晶体管阵列是非门。另外当PWM占空比过低时,也会导致直流电机平均启动电压过小而不转。
  4. 下面是使用LED来指示转速的代码:
//LCD更新显示转速等级
switch(speed_index){
    case 0:P2 = 0xff;break;
    case 1:P2 = 0xfc;break;
    case 2:P2 = 0xf0;break;
    case 3:P2 = 0xc0;break;
    case 4:P2 = 0x00;break;
    default:;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/185469.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Docker -- 部署Mysql主从服务

以下是配置一主两从的Mysql服务的具体流程。 文章目录创建用于挂载的目录修改cnf配置拉取mysql服务镜像自定义docker网络启动容器主库配置查看主库状态创建从库备份用户从库配置修改Master信息启动slave服务查看slave服务状态是否正常创建用于挂载的目录 保证数据的持久化&…

Databend 内幕大揭秘第二弹 - Data Source

本篇是 minibend 系列的第二期&#xff0c;将会介绍 Data Source 部分的设计与实现&#xff0c;当然&#xff0c;由于是刚开始涉及到编程的部分&#xff0c;也会提到包括 类型系统 和 错误处理 之类的一些额外内容。 前排指路视频和 PPT 地址 视频&#xff08;哔哩哔哩&#xf…

23种设计模式之趣味学习篇

23种设计模式之趣味学习篇1. 设计模式概述1.1 什么是设计模式1.2 设计模式的好处2. 设计原则分类3. 详解3.1 单一职责原则3.2 开闭原则3.3 里氏代换原则3.4 依赖倒转原则3.5 接口隔离原则3.6 合成复用原则3.7 迪米特法则4. Awakening1. 设计模式概述 我们的软件开发技术也包括一…

【1669. 合并两个链表】

来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 描述&#xff1a; 给你两个链表 list1 和 list2 &#xff0c;它们包含的元素分别为 n 个和 m 个。 请你将 list1 中下标从 a 到 b 的全部节点都删除&#xff0c;并将list2 接在被删除节点的位置。 下图中蓝色边和节点…

【算法竞赛学习】csoj:寒假第二场

文章目录前言红包接龙最后一班勇者兔兔兔爱消除吃席兔知识拓展std::greater | 堆优化参考iota函数参考并查集参考sort自定义函数参考树形dp参考使用auto时控制分隔符前言 由于本人菜鸡&#xff0c;所以大多都是使用出题人的代码和思路 如有侵权&#xff0c;麻烦联系up删帖&…

pytorch_sparse教程

pytorch_sparse教程 Coalesce torch_sparse.coalesce(index, value, m, n, op"add") -> (torch.LongTensor, torch.Tensor) 逐行排序index并删除重复项。通过将重复项映射到一起来删除重复项。对于映射&#xff0c;可以使用任何一种torch_scatter操作。 参数 i…

来回修改的投标文件怎么做版本管理?1个工具搞定!

投标是公司市场活动中非常重要的事情&#xff0c;每次投标文件的编写像打仗一样&#xff0c;要修改很多次&#xff0c;不保存每个版本就只能在需要的时候后悔&#xff0c;多个文件、多人编写、多种方案要再最后的几个小时才能定&#xff0c;每次都是弄得鸡飞狗跳的&#xff0c;…

Python卷积神经网络CNN

Python卷积神经网络CNN 提示&#xff1a;前言 Python卷积神经网络CNN 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录Python卷积神经网络CNN前言一、导入包二、介绍三、卷积过滤四、权重五、展示特征图六、用 ReLU…

一文快速入门哈希表

目录一、基本概念1.1 哈希冲突二、整数哈希2.1 哈希函数的设计2.2 解决哈希冲突2.2.1 开放寻址法2.2.2 拉链法三、字符串哈希3.1 应用&#xff1a;重复的DNA序列References一、基本概念 哈希表又称散列表&#xff0c;一种以「key-value」形式存储数据的数据结构。所谓以「key-…

RA4M2开发(1)----使用串口进行打印

为什么使用Cube进行FreeRTOS配置 本篇文章主要介绍如何使用e2studio对瑞萨RA4M2开发板进行串口打印配置。 硬件准备 首先需要准备一个开发板&#xff0c;这里我准备的是芯片型号R7FAM2AD3CFP的开发板&#xff1a; 新建工程 工程模板 保存工程路径 芯片配置 本文中使用R7F…

【GlobalMapper精品教程】043:图片自动矢量化

本文讲解Globalmapper自动矢量化教程,配套案例数据。 参考教程:ArcGIS实验教程——实验三十三:ArcScan自动矢量化完整案例教程 文章目录 一、加载实验数据二、启动矢量化工具三、矢量化栅格四、矢量化结果五、注意事项一、加载实验数据 打开配套实验数据包中的data043.rar…

参数检验与非参数检验

综述 假设检验 参数检验 T检验 T检验是通过比较不同数据的均值&#xff0c;研究两组数据之间是否存在显著差异。 单总体检验&#xff1a;单总体t检验是检验一个样本平均数与一个已知的总体平均数的差异是否显著。当总体分布是正态分布&#xff0c;如总体标准差未知且样本容量小…

算法——垃圾回收算法——标记清除

标记清除简介算法过程1.标记阶段2.清除阶段3.缺点3.1内存碎片化简介 标记清除算法简介。 文章中使用的动画网站地址&#xff1a; 限 pc: 标记清除动画 &#xff1a;http://www.donghuasuanfa.com/platform/portal?pcmark-sweep 算法一览表&#xff1a;https://blog.csdn.net…

23种设计模式之面向对象的设计原则

23种设计模式之面向对象的设计原则1. 设计模式概述1.1 什么是设计模式1.2 设计模式的好处2. 设计原则分类3. 详解3.1 单一职责原则3.2 开闭原则3.3 里氏代换原则3.4 依赖倒转原则3.5 接口隔离原则3.6 合成复用原则3.7 迪米特法则4. Awakening1. 设计模式概述 我们的软件开发技术…

18《Protein Actions Principles and Modeling》-《蛋白质作用原理和建模》中文分享

《Protein Actions Principles and Modeling》-《蛋白质作用原理和建模》 本人能力有限&#xff0c;如果错误欢迎批评指正。 第四章&#xff1a;Protein Binding Leads to Biological Actions &#xff08;蛋白质的结合会产生生物作用&#xff09; -偶联结合是调控、信号传…

【Java基础】-【Spring Boot】-【Spring】

文章目录Spring BootSpring Boot的启动流程Spring Boot项目是如何导入包的&#xff1f;Spring Boot自动装配的过程Spring Boot注解Spring的核心Spring AOP既然有没有接口都可以用CGLIB&#xff0c;为什么Spring还要使用JDK动态代理&#xff1f;AOP的应用场景Spring AOP不能对哪…

图论(7)负环和差分约束

一、概念 给定一张有向图&#xff0c;如果存在一个环&#xff0c;环上各边权值之和是负数&#xff0c;则称这个环为负环。 判断方式&#xff1a;bellman-ford算法和spfa算法。抽屉原理 这里只介绍spfa。设立cnt数组表示从1到x的最短路径包含的边数&#xff0c;如果cnt[i]大于…

JZ65 不用加减乘除做加法

【答案解析】&#xff1a;十进制相加思想&#xff1a; 1507 &#xff0c; 先计算不考虑进位的相加结果 12 &#xff08;因为 57 的不考虑进位的结果是 2 &#xff0c;遇 10 进位嘛&#xff09;&#xff0c;然后计算进位 57 进位是 10 &#xff0c;则 10 与 12 再次相加&#xf…

2023年山东最新交安安全员考试题库及答案

百分百题库提供交安安全员考试试题、交安安全员考试真题、交安安全员证考试题库等&#xff0c;提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助你考试轻松过关。 35.建设行政主管部门或者其他有关部门可以将施工现场的监督检查委托给建设工程&#xff08;&#xff09;…

Visual Studio 17.5: 有关 C++ 的新特性预览

Visual Studio 17.5 在 C 代码编辑方面带来了一些新的改进&#xff0c;这些改进包括&#xff1a;C 代码中的大括号对着色&#xff0c;拼写检查&#xff0c;多合一搜索&#xff0c;重新设计的成员列表以及宏展开改进等。上述这些改进都融入到了 Visual Studio 的最新预览版本 17…