江科大51单片机笔记【15】直流电机驱动(PWM)

写在前言

  此为博主自学江科大51单片机(B站)的笔记,方便后续重温知识

  在后面的章节中,为了防止篇幅过长和易于查找,我把一个小节分成两部分来发,上章节主要是关于本节课的硬件介绍、电路图、原理图等理论知识,主要是为下章节的代码部分打基础。

  我的单片机是24年12月在tb普中买的,型号是STC89C52,在原视频中引脚或接口不对应的我都会改正,保证在我的机子上能运行才发上来的,还有一些文字部分是我的理解,并非照搬,所以可能有理解不到位的现象。

  如有误或交流,敬请指点提问

本节课一共两个代码,LED呼吸灯和直流电机调速

一、直流电机

1.介绍

  • 直流电机是一种将电能转换为机械能的装置。一般的直流电机有两个电极,当电极正接时,电机正转,当电极反接时,电机反转
  • 直流电机主要由永磁体(定子)、线圈(转子)和换向器组成
  • 除直流电机外,常见的电机还有步进电机(机壳装载了一圈电磁铁,对相对两个电磁铁进行一圈脉冲式通电,优点是严格控速精密)、舵机(跟船舵一样,方便控制转向)、无刷电机(转速特别快)、空心杯电机(体积很小)等
  • 左1就是我们开发板里的电机,有两个电极;左1是N20,一个直流电机+减速箱;右1比左2还多带一个编码器(测速),PID算法(常用)控制电机速度

2.驱动电路

有两种方式

  • 大功率器件直接驱动 

不能正反转上面是一个三极管控制开关,下面是一个蓄流二极管,用于保护电路;因为电机(继电器)是感性负载元件,驱动的时候会出现很高的电压(电感的特效)

这个ULN2003里面也是一个大功率元件

  • H桥驱动

能正反转因为我们使第二、四象限的二极管导通其余的截止,就会令电流向右走,如果反过来就可以令电流向左走;因为没有蓄流二极管保护,所以对mos管和晶体管的耐压特效要求比较高

二、PWM

PWM是控制直流电机调速的


1.介绍

  • PWM(Pulse Width Modulation)即脉冲宽度调制,在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速、开关电源等领域
  • PWM重要参数:
  • 频率=1/Ts  占空比=Ton/Ts  精度=占空比变化步距

三、代码实战

1.LED呼吸灯 

先定义一下引脚

然后再定义一个比较快的延时函数,让这个LED灯先亮一段时间,再灭一段时间,这就是PWM的工作原理,通常为了保证周期是稳定的,不随占空比变化而变化,所以亮和灭加起来的时间也要是个固定值

#include <REGX52.H>sbit LED=P2^0;void Delay(unsigned int t)
{while(t--);
}void main()
{while(1){LED=0;Delay(5);LED=1;Delay(95);}
}

接下来就是让亮和灭的值不断变化,从而实现呼吸灯的效果

我们就可以定义一个变量Time,让亮的时间为Time,灭的时间为100-Time,这样就可以实现两个数加起来是固定值,然后我们再对Time进行for循环,不断++

但是这个速度还是比较快,我们让他每次亮灭变换的时间再久一点,定义一个i,在for循环里嵌套再进行一次for循环,这样就可以实现LED一直从暗到亮

但是我们还想实现从暗到亮,再从亮到暗又怎么做呢,就是把之前的外层对Time的for循环反过来再依次--

#include <REGX52.H>sbit LED=P2^0;void Delay(unsigned int t)
{while(t--);
}void main()
{unsigned char Time,i;while(1){for(Time=0;Time<100;Time++){for(i=0;i<20;i++){LED=0;Delay(Time);LED=1;Delay(100-Time);				}}for(Time=100;Time>0;Time--){for(i=0;i<20;i++){LED=0;Delay(Time);LED=1;Delay(100-Time);				}}}
}

这样就可以实现呼吸灯从暗到亮,再从亮到暗

但是会有一个缺点,就是占用了我们的主循环不断翻转IO口,还比较占用CPU

一般都会写到定时器上,或者从硬件上解决

所以在下面的代码中我们用定时器来实现

2.直流电机调速

在这个代码我们就用定时器来实现LED呼吸灯和直流电机调速功能

产生PWM方法

我们通过改变比较值就可以改变占空比 

由于之前的定时器设置有点慢,我们让他快一点

这个PWM驱动电机在一定范围内是越快越好,一般设置在10K-20K范围里,如果频率比较低,电流就会抖动,如果在1K左右,就会产生一些蜂鸣器的声音

这个中断就是每隔100us中断一次

//timer0.c#include <REGX52.H>/*** @brief  定时器0初始化,100us@12.000MHz* @param  无* @retval 无*/
void Timer0_Init(void)
{TMOD &= 0xF0;		//设置定时器模式TMOD |= 0x01;		//设置定时器模式TL0 = 0xA4;		//设置定时初值TH0 = 0xFF;		//设置定时初值TF0 = 0;		//清除TF0标志TR0 = 1;		//定时器0开始计时ET0=1;EA=1;PT0=0;
}/*定时器中断函数模板
void Timer0_Routine() interrupt 1
{static unsigned int T0Count;TL0 = 0xA4;		//设置定时初值TH0 = 0xFF;		//设置定时初值T0Count++;if(T0Count>=1000){T0Count=0;}
}
*/

由上面的图可以知道要定义两个值,计数值和比较值,

我们让计数值从0-100然后清零,实现定时自增

    Counter++;
    Counter%=100;

这样写和if(counter==100){清零}是一个效果

接下来再让计数值和比较值进行比较

可以观察到如果比较值越大,低电平时间越久,也就是越暗

这样我们通过控制比较值Compare就可以控制LED的亮度,还剩下下了主循环,接下来我们就实现按键功能

#include <REGX52.H>
#include " Delay.h"
#include " Key.h"
#include " Nixie.h"
#include " Timer0.h"sbit LED=P2^0;unsigned char Counter,Compare;void main()
{Timer0_Init();Compare=5;while(1){}}void Timer0_Routine() interrupt 1
{TL0 = 0xA4;		//设置定时初值TH0 = 0xFF;		//设置定时初值Counter++;Counter%=100;if(Counter<Compare){LED=0;}else{LED=1;}
}

注意后面取的Key函数,如果是拿的定时器扫描按键的那章写的Key函数,要在定时器中写上这个Key_Loop()

#include <REGX52.H>
#include " Delay.h"
#include " Key.h"
#include " Nixie.h"
#include " Timer0.h"sbit LED=P2^0;unsigned char Counter,Compare;
unsigned char KeyNum,Speed;void main()
{Timer0_Init();Compare=5;while(1){KeyNum=Key();if(KeyNum==1){Speed++;Speed%=4;}Nixie(1,Speed);}}void Timer0_Routine() interrupt 1
{Key_Loop();TL0 = 0xA4;		//设置定时初值TH0 = 0xFF;		//设置定时初值Counter++;Counter%=100;if(Counter<Compare){LED=0;}else{LED=1;}
}

这样就可以实现按下按键1数码管显示++并且过3就清零

接下来将Speed跟Compare比较值对应起来,就可以实现按键调速并显示

这样就可以实现LED的亮度控制

            if(Speed==0){Compare=5;}
            if(Speed==1){Compare=5;}
            if(Speed==2){Compare=50;}
            if(Speed==3){Compare=100;}    

那我们如果想控制电机,就直接把LED的端口改成电机的端口,而又因为我们的LED是给0亮给1灭,而电机是给1转给0灭,所以需要把极性反过来

这里有个小问题,在刚上电的时候,电机会转动,这是硬件的问题,因为单片机在复位的时候,IO口默认高电平,所以电机会转

#include <REGX52.H>
#include " Delay.h"
#include " Key.h"
#include " Nixie.h"
#include " Timer0.h"sbit Motor=P1^0;unsigned char Counter,Compare;
unsigned char KeyNum,Speed;void main()
{Timer0_Init();Compare=5;while(1){KeyNum=Key();if(KeyNum==1){Speed++;Speed%=4;if(Speed==0){Compare=0;}if(Speed==1){Compare=50;}if(Speed==2){Compare=75;}if(Speed==3){Compare=100;}	}Nixie(1,Speed);}}void Timer0_Routine() interrupt 1
{Key_Loop();TL0 = 0xA4;		//设置定时初值TH0 = 0xFF;		//设置定时初值Counter++;Counter%=100;if(Counter<Compare){Motor=1;}else{Motor=0;}
}

这样就实现本节课的代码啦,按下按键调节电机的速度并且显示出来。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】:封装线程

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本期来给大家带来封装线程相关的知识点&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C 语 言 专 栏&#xff1a;C语言&#xff1a;从入门到精通 数据结…

全球领先的光学方案设计公司:倚光科技

在光学技术革新的浪潮中&#xff0c;倚光&#xff08;深圳&#xff09;科技有限公司以创新者的姿态迅速崛起&#xff0c;成为全球光学领域的标杆企业。自 2021 年成立以来&#xff0c;公司始终聚焦纳米光学技术研发与超精密加工&#xff0c;凭借顶尖的技术实力和前瞻性的市场布…

2.2.3 TCP—UDP-QUIC

文章目录 2.2.3 TCP—UDP-QUIC1. TCP如何做到可靠性传输1. ACK机制2. 重传机制3. 序号机制4. 窗口机制5. 流量机制6. 带宽机制 2. tcp和udp如何选择1. tcp和udp格式对比2. ARQ协议&#xff08;Automatic Repeat reQuest&#xff0c;自动重传请求&#xff09;1. ARQ协议的主要类…

【动手实验】TCP 连接的建立与关闭抓包分析

本文是基于知识星球程序员踩坑案例分享中的作业进行的复现和总结&#xff0c;借此加深对 TCP 协议的理解&#xff0c; 原文参见TCP 连接的建立和关闭 —— 强烈建议新手看看。 实验环境 这里使用两台位于同一子网的腾讯云服务器&#xff0c;IP 分别是 node2&#xff08;172.1…

视频理解之Actionclip(论文宏观解读)

配合解读代码解读 1.研究背景 1. 视频行为识别的重要性 视频行为识别是视频理解领域的核心任务之一&#xff0c;旨在通过分析视频内容来识别和分类其中的人物行为或活动。这一任务在多个领域具有重要的应用价值&#xff0c;例如智能监控、人机交互、自动驾驶、医疗健康等。随…

基于LabVIEW的脚本化子VI动态生成

该示例展示了一种利用LabVIEW VI脚本&#xff08;VI Scripting&#xff09;技术&#xff0c;通过程序化方式动态生成并替换子VI的解决方案。核心逻辑为&#xff1a;基于预定义的模板VI&#xff0c;根据用户选择的数学操作&#xff08;加法或乘法&#xff09;&#xff0c;自动生…

Debian系统grub新增启动项

参考链接 给grub添加自定义启动项_linux grub定制 启动项名称自定义-CSDN博客 www.cnblogs.com 1. boot里面的grub.cfg 使用vim打开boot里面的grub.cfg sudo vim /boot/grub/grub.cfg 这时候会看到文件最上方的提示 2. 真正配置grub的文件 从刚才看到的文件提示中&#x…

ctfhub-web-SSRF通过攻略

1.URL Bypass 打开题目 请求的URL中必须包含http://notfound.ctfhub.com&#xff0c;使用来绕过即可 /?urlhttp://notfound.ctfhub.com127.0.0.1/flag.php 成功获得flag 2.数字IP Bypass 开启题目 发现127以及172被过滤了 尝试别的绕过 127.0.0.1–>localhost 127.0…

C语言(23)

字符串函数 11.strstr函数 1.1函数介绍&#xff1a; 头文件&#xff1a;string.h char *strstr ( const char * str1,const char *str2); 作用&#xff1a;在一个字符串&#xff08;str1&#xff09;中寻找另外一个字符串&#xff08;str2&#xff09;是否出现过 如果找到…

uniapp+Vue3 组件之间的传值方法

一、父子传值&#xff08;props / $emit 、ref / $refs&#xff09; 1、props / $emit 父组件通过 props 向子组件传递数据&#xff0c;子组件通过 $emit 触发事件向父组件传递数据。 父组件&#xff1a; // 父组件中<template><view class"container">…

晨控CK-FR08与汇川H5U系列PLC配置EtherNet/IP通讯连接手册

晨控CK-FR08与汇川H5U系列PLC配置EtherNet/IP通讯连接手册 晨控CK-FR08系列作为晨控智能工业级别RFID读写器,支持大部分工业协议如RS232、RS485、以太网。支持工业协议Modbus RTU、Modbus TCP、Profinet、EtherNet/lP、EtherCat以及自由协议TCP/IP等。 本期主题&#xff1a;围…

BLDC直流无刷电机转速电流双闭环调速MATLAB仿真

微♥&#xff1a;“电击小子程高兴的MATLAB小屋”获取巨额优惠 1.模型简介 本仿真模型基于MATLAB/Simulink&#xff08;版本MATLAB 2017Ra&#xff09;软件。建议采用matlab2017 Ra及以上版本打开。&#xff08;若需要其他版本可联系代为转换&#xff09; 2.仿真算法&#x…

Windows 11下Git Bash执行cURL脚本400问题、CMD/PowerShell不能执行多行文本等问题记录及解决方案

问题 在Postman里可成功执行的POST请求&#xff1a; 找到Postman的Code 因为cURL基本上算是行业标准&#xff0c;所以Postman默认选中cURL&#xff0c;支持切换不同的开发语言&#xff1a; 点击上图右上角的复制按钮&#xff0c;得到cURL脚本。 Windows 11家庭版&#xff…

4个 Vue 路由实现的过程

大家好&#xff0c;我是大澈&#xff01;一个喜欢结交朋友、喜欢编程技术和科技前沿的老程序员&#x1f468;&#x1f3fb;‍&#x1f4bb;&#xff0c;关注我&#xff0c;科技未来或许我能帮到你&#xff01; Vue 路由相信朋友们用的都很熟了&#xff0c;但是你知道 Vue 路由…

es-索引详解

在 Elasticsearch 中&#xff0c;**索引&#xff08;Index&#xff09;**是核心概念之一&#xff0c;类似于关系型数据库中的“表”。索引用于存储、组织和检索文档&#xff08;Document&#xff09;。以下是关于 Elasticsearch 索引的详细解析&#xff1a; 1. 索引的基本概念 …

C#实现本地Deepseek模型及其他模型的对话v1.4

前言 系 统&#xff1a;Window11 开发工具&#xff1a;Visual Studio 2022 相关技术&#xff1a;C# 、WPF .Net 8.0 1、C#实现本地AI聊天功能 WPFOllamaSharpe实现本地聊天功能,可以选择使用Deepseek 及其他模型。 新增根据聊天记录回复的功能。 优化了部分ViewModel&#xff…

若依框架-给sys_user表添加新字段并获取当前登录用户的该字段值

目录 添加字段 修改SysUser类 修改SysUserMapper.xml 修改user.js 前端获取字段值 添加字段 若依框架的sys_user表是没有age字段的&#xff0c;但由于业务需求&#xff0c;我需要新添加一个age字段&#xff1a; 修改SysUser类 添加age字段后&#xff0c;要在SysUser类 …

用Qt手搓AI助手,挑战24小时开发DeepSeek Assistant!

一、项目需求分析与技术选型 DeepSeekAssistant是一款基于深度求索&#xff08;DeepSeek&#xff09;API的智能对话助手&#xff0c;核心需求包括&#xff1a; 用户界面友好&#xff1a;支持多轮对话展示数据持久化&#xff1a;历史记录存储与检索异步网络通信&#xff1a;AP…

linux 软件扩展GPU显存

概述 共享内存可以通过 Unified Memory&#xff08;统一内存&#xff09;来实现&#xff0c;它允许 CPU 和 GPU 共享相同的内存地址空间&#xff0c;从而方便数据的传输和访问。 利用该技术可解决家用GPU 机器学习时显存不足的问题 &#xff08;注&#xff1a; 虽然解决了爆显…

Linux——进程初步

学进程前我们需要知道什么&#xff1f; 一、冯诺依曼体系结构 图中就是我们电脑运作时的大致工作流程&#xff0c;其中输入设备、输出设备我们也叫外设。其中&#xff0c;输入设备有比如键盘、鼠标、磁盘、摄像头等。输出设备有显示器、磁盘、打印机等。图中的存储器我们也叫内…