嘉兴手机网站建设,合肥网站推广 公司,彩票网站建设成本,网上的彩票网站是怎么做的#x1f680;write in front#x1f680; #x1f50e;大家好#xff0c;我是黄桃罐头#xff0c;希望你看完之后#xff0c;能对你有所帮助#xff0c;不足请指正#xff01;共同学习交流 #x1f381;欢迎各位→点赞#x1f44d; 收藏⭐️ 留言#x1f4dd;… write in front 大家好我是黄桃罐头希望你看完之后能对你有所帮助不足请指正共同学习交流 欢迎各位→点赞 收藏⭐️ 留言 本系列哔哩哔哩江科大51单片机的视频为主以及自己的总结梳理 前言
本文是根据哔哩哔哩网站上“江协科技51单片机”视频的学习笔记在这里会记录下江协科技51单片机开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了江协科技51单片机教学视频和链接中的内容。
引用
51单片机-直流电机和PWM-呼吸灯和直流电机调速_单片机20khzpwm调速程序-CSDN博客
51单片机十五直流电机驱动PWM_直流电机驱动程序-CSDN博客
【嵌入式 · 单片机】一文带你搞懂电机驱动模块_桥式驱动单片机-CSDN博客
51单片机---直流电机PWM含源码、小白可入_51单片机_King~30-GitCode 开源社区
51单片机学习笔记-13直流电机_单片机跟直流电机分别供电-CSDN博客
江协科技 51单片机 直流电机驱动PWM 学习笔记_单片机电机驱动电路-CSDN博客
十五51单片机——呼吸灯与直流电机调速PWM_51单片机pwm控制直流电机-CSDN博客 正文
0. 概述
在淘宝上购买了江协科技51单片机开发板套件普中科技STC51单片机A2型号就上在上一篇博文里说的自己计划学习下江协科技51单片机开发教程通过STC51单片机这种MCU这种贴近于裸机的开发来增加对于系统硬件层面知识的了解和掌握。
术语和缩略语
缩写全称说明PWMPulse Width Modulation脉冲宽度调制
1. 直流电机介绍
直流电机介绍
直流电机是一种将电能转换为机械能的装置。一般的直流电机有两个电极当电极正节的时电机正传当电极反接时电机反转。直流电机主要由永磁体定子线圈动子和换向器组成除直流电机外常见的电机还有步进电机舵机无刷电机空心杯电机等。
步进电机的介绍
除了直流电机之外还有步进电机步进电机的结构中外壳一整圈都分布着磁铁中间有个转子转子也是永磁体通过对不同角度的磁铁进行通电从而产生不同方向的磁力改变转子的角度最终吸引转子朝着特定的方向转动 其好处就是转子转动的速度完全是由我们代码写入的通电时间决定的
舵机可以输出固定的角度常用与小车的转向电机
无刷电机一般在四轴飞行器中会用到其转速非常快适合为飞机起飞提供强劲的动力功率比较大动力比较足 直流电机是一种功率比较大的负载直接接在单片机的IO口上肯定是不能直接驱动的而且也可能会损坏单片机的IO口所以需要再IO和直流电机负载之间加上驱动电路
常见的驱动电路有两种 第一种是大功率器件直接驱动。这种驱动的特点是它驱动电机只能朝一个方向转因为它不具有调换电机正反方向的功能第二种是H桥驱动H桥驱动方式是电机驱动里面非常有名的一种驱动方式这种方式可以控制电机正反转所以如果我们需要驱动电机正反转那么就选H桥驱动电路 大功率器件驱动电路需要通过的电流较大需要功率比较大的器件通常使用达林顿三极管或者MOS三极管并且电路中需要加一个续流二极管。续流二极管的作用是保护电路的。为什么需要这个续流二极管哪 因为电机这种负载都是感性负载原件驱动的时候需要注意它电感的特性它可能会感应出很大的电压那为什么会这样哪这里来分析一下 当IO控制口输出低电平三极管导通的时候电流通过直流电机驱动直流电机转动 当IO控制口输出高电平驱动电路断开由于直流电机是感性负载原件具有电感的特性在电路断开的瞬间电感具有保持电流不能突变的特性在电路断开的瞬间电机中中的电感想要保持电流不发生突变但是电路中的开关已经断开阻止了电路中电流的位置电感为了对抗这种阻力就会感应出很大的电压来克服这种阻力来维持电流最终就是电感感应出的电压和三极管开关之间的对抗电机在电路断开的瞬间感应出的高电压可能就会击穿三极管开关。而如果我们加上了续流二极管当电极驱动电路断开的瞬间电机感性器件感应出来的电流就会通过二极管形成回路从而保护电路中不会感应出高电压。 1.1 ULN2003 驱动电路 ULN2003就是一种常见的功率驱动集成电路器件它的示意图如上所示 ULN2003在每对输入口1B~7B和输出口1C~7C之间是一个非门当输入口输入高电平的的时候输出口输出低电平例如当ULN2003 1C口输出低电平时直流电机的正极接外部的Vcc负极接在ULN2003口的输出口1C上此时电机就可以转动。ULN2003的输入口输入低电平时输出口输出高电平此时ULN2003输出的高电平实际上是没有驱动能力的它输出的高电平状态输出口能够通过的电流很小。所以ULN2003集成电路器件主要使用的就是它输入口输入高电平信号时输出口变为低电平外接负载的一个电极接在ULN2003的输出口上负载的另一端接在外部的Vcc上当ULN2003输出口输出低电平时负载上就有电压产生负载开始工作当ULN2003输出口输出高电平时负载上没有电压压降产生就停止工作。 1.2H桥驱动
因为整体的形状像是H所以这个电路被称为H桥 如果使Q1和Q4两个三极管导通而Q3和Q2两个三极管断开那么电流就是从左上角流向右下角如上图所示这样电机就会朝着一个方向转动如果反过来Q3和Q2两个三极管导通Q1和Q4两个三极管断开则电流就是从右上角流向左下角如下图所示这样电机就会朝着另一个方向转动通过这种方式控制电机的正反转因为电流方向既可以向右又可以向左 因为电机的电流放行既可以往左又可以往右电机也就没有办法加续流二极管这就要求我们的晶体管具有很高的耐压特性能够抗的住电机感应出来的高电压这对器件的要求还是比较高的。 但在实际设计电路中我们更经常使用集成电路驱动器件因为这些集成器件是固定的我们可以选择很多的电机驱动芯片可以自己搜索一下有了这种芯片之后我们自己就不用自己设计这些复杂的电路只需要按照芯片手册按照它的要求哪里接电机哪里连输出这样就可以很轻松的控制电机如果你对这些电路知识不是很了解的话那也推荐你去搜索一下电机驱动的芯片电机驱动的芯片还是非常多的。
2. PWM介绍
有了电机驱动电路之后我们在来关心下一个问题电机调速。如果给电机通上电电机就会全速运转如果电机没有通电电机就会停下来那么如何让电机保持一个中间的速度哪这就需要用到PWMPulse Width Modulation进行调速。 什么是PWM PWM(脉冲宽度调制)在具有惯性的系统中可以通过对一系列脉冲进行调制来等效的获得所需要的模拟参量常应用于电机控速开关电源等领域。 注意PWM脉冲宽度调制提到了“在具有惯性的系统中” 什么事具有惯性的系统哪例如电机转动是具有惯性的当我们短时间断掉电机的电流的时候电机因为具有惯性它不会立即停还会继续转动如果我们给电机转1ms停1ms转1ms停1ms电机就会因为惯性转动如果想要电机转动的更快可以让电机转5ms然后停1ms转5ms然后停1ms这样电机就保持一个更快的速度转动。
LED也是具有惯性的系统当LED点亮之后给LED断电LED灯也不是立马熄灭的它有一个余晖虽然这个时间不是很长但它也不是立马熄灭的。
2.1 PWM只适用于惯性系统
PWM只能用于惯性系统不能用于无惯性系统那么是什么是无惯性系统哪例如用PWM给单片机供电因为单片机不是惯性系统给单片机断电之后单片机立即就停止运行了。
在PWM波形中有几个重要的参数分别是频率、占空比以及精度 频率是指一个PWM波形周期的倒数一个周期即为高低电平的总和占空比即高电平占据整个周期的比值占空比越大高电平时间越长其转速越高精度即占空比变化的步距占空比变化的步距越小速度改变的每次就越小其精度就越高 频率越高越平滑如果频率过低可能就会出现电机的抖动。
占空比一个百分比占空比越大高电平时间越长转速越快。
精度就是占空比变化的步距精度越高每次调节的精度就越高。
通常会保持PWM的一个周期的时间是一样的当然也可以不用保持每个周期的时间是一样的但是一般情况下我们习惯保持PWM的一个周期的时间是一样的。 3. PWM程序电机调速程序
3.1 实验LED呼吸灯PWM调节的原理
第一个实验我们做LED呼吸灯的LED呼吸灯的实验也就是使用PWD亮度调节的原理通过调整每个周期内LED点亮的占比来调整LED的亮度最后实现LED灯亮度不断变化形成呼吸灯的效果。
第一个实验单独点亮LED灯在循环里不操作LED灯LED灯一直点亮可以看到LED灯的亮度是最亮的。
#include REGX52.H
#include INTRINS.Hsbit LEDP2^0;void Delay(unsigned int t)
{while(t--);
}void main()
{unsigned char Time;unsigned char i;LED 0; //点亮LED灯while(1){}
}第二个实验在main函数的While循环里不断的点亮和关闭LED灯可以看到实验的效果是LED的亮度变暗。
#include REGX52.H
#include INTRINS.Hsbit LEDP2^0;void Delay(unsigned int t)
{while(t--);
}void main()
{unsigned char Time;unsigned char i;LED 0; //点亮LED灯while(1){LED 0; //点亮LED灯 LED 1; //关闭LED灯}
}第三个对比实验进一步增大main函数循环中LED灯熄灭的时间实验的效果是随着LED灯熄灭的时间占比增加观察实验开发板的结果是LED亮度进一步变暗。
#include REGX52.H
#include INTRINS.Hsbit LEDP2^0;void Delay(unsigned int t)
{while(t--);
}void main()
{unsigned char Time;unsigned char i;LED 0; //点亮LED灯while(1){LED 0; //点亮LED灯 LED 1; //关闭LED灯LED 1;LED 1; LED 1;LED 1; LED 1;LED 1; LED 1;LED 1; }
}为了方便控制LED灯点亮和熄灭的时间我们写了一个‘Delay()’延时函数使用空循环的方式来控制延时的时间长短。保持每个周期的LED灯点亮和熄灭的总时间相等我们使用数值100’来控制LED灯点亮和熄灭的一个周期延时的总时间。最后的LED灯呼吸灯的源码如下
mani.c
#include REGX52.H
#include INTRINS.Hsbit LEDP2^0;void Delay(unsigned int t)
{while(t--);
}void main()
{unsigned char Time;unsigned char i;LED 0;while(1){for(Time0; Time100; Time){for(i0; i10; i) //在每个亮度保持一段时间{LED 0;Delay(Time);LED 1;Delay(100-Time);}}for(Time100; Time0; Time--){for(i0; i10; i) //在每个亮度保持一段时间{LED 0;Delay(Time);LED 1;Delay(100-Time);}}}
}在这个实验里我们在程序的主循环里通过Delay()延时时间长短的的方法来控制LED亮灭的模拟PWM这种方式的优点非常简单这种方式有缺点也是非常显而易见的它需要占用我们的主循环来不断的延时来翻转IO口那在这一段时间内呼吸灯的整个过程中主循环是没法干其他事情的。
通常我们会将PWM给写到定时器里面去而现在稍微高级一点的单片机像STC的12系列15系列都会具有硬件的PWM或者STM32单片机也会就有硬件的PWM因为不断反转IO口是一种比较简单比较占用CPU的操作所以通常我们会用硬件来实现PWM而且硬件实现通常会寄生到定时器里面去定时器既可以定时还可以兼具PWM的功能像一些最新的单片机它的定时器都会有输出PWM的功能。
但是我们的STC89C52是没有的所以我们就用定时器中断来实现这个功能如果你了解了单片机定时器中断实现PWM的功能那以后你再去结束硬件的PWM模块的话你会更加方便的理解。
3.2 实验PWM直流电机调速 使用定时器中断中的计数器值和比较值进行比较来控制输出高电平还是低电平来控制PWD脉冲宽度调制中高电平的占空比来调节直流电机的转速: 在定时器中断里增加计数器的值并且比较计数器的值和用户设置的比较值当计数器的值小于用户设置比较值时输出高电平当计数器的值大于等于比较值时输出低电平。定时器中断计数器的值自增到大于等于100的时候计数器的值重新开始从0开始计数。这样保证了一个PWM调制的每个周期的时间长度是一样的。 源码如下主要给出了main.c的源码和timer0.c的源码其它的源码文件在之前的实验里已经作为模块写出。如果想获得完成的源码建议现在江协科技提供的示例程序源码。
timer0.c
#include REGX52.H
#include timer0.h/*** brief 定时器0初始化函数, 100微秒11.0592MHz* param 无* retval 无*/
void Timer0_Init()
{//AUXR 0x7F; //定时器时钟12T模式TMOD 0xF0; //设置定时器模式TMOD | 0x01; //设置定时器模式TL0 0xA4; //设置定时初值TH0 0xFF; //设置定时初值TF0 0; //清除TF0标志TR0 1; //定时器0开始计时//中断部分寄存器ET0 1; //允许定时器T0中断EA 1; //允许中断PT0 0; //定时器T0中断优先级
}/*** brief 定时器0中断处理函数模版* param 无* retval 无*/
//void Timer0_Routine(void) interrupt 1
//{
// static unsigned int count 0;
//
// count;
// //P2_0 0;
// if(count 500) //定时器T0每1ms中断一次进入1000次经过了1s
// {
// P2_0 ~P2_0;
// count 0;
// }
//
// //定时器溢出之后需要重新装载
// TH0 (65535 - 1000) / 256; //12MHz晶振12分频
// TL0 (65535 - 1000) % 256 1; //
//}
main.c
#include REGX52.H
#include INTRINS.H
#include time0.h
#include Nixie.h
#include key.h
#include delay.hsbit MotoP1^3;
unsigned char Compare 0;
unsigned char KeyNum;void main()
{unsigned char Speed 0;Timer0_Init(); //定时器初始化Nixie(1,0);while(1){KeyNum Key();if(KeyNum){if(KeyNum 1){Compare 50;Speed 1;}else if(KeyNum 2){Compare 75;Speed 2;}else if(KeyNum 3){Nixie(1,3);Compare 100;Speed 3;}else if(KeyNum 4){Compare 0;Speed 0;}}Nixie(1,Speed);}
}/*** brief 定时器0中断处理函数模版* param 无* retval 无*/
void Timer0_Routine(void) interrupt 1
{static unsigned int count 0;count;if(count PWM_Threshold){Moto 1; //ULN2003输出低电平电机转动}else{Moto 0; //ULN2003输出高电平电机停止}if(count 100)count 0;//定时器溢出之后需要重新装载TH0 0xFF; //100微秒11.0592MHzTL0 0xA4; //定时器装载周期为100微秒
}
4. PWM直流电机调速实验结果
PWM直流电机调速实验结果如下 使用逻辑分析仪抓取到的ULN2003输出的PWM波形 5. 实验问题记录
5.1 问题1插上直流电机负载并且PWM调速之后单片机运行异常 问题1 插上直流电机负载并且PWM调速之后单片机运行异常。 在没有插上51单片机之前开发板运行正常独立按键检测正常但是在插上直流电机开启PWM调速之后单片机运行异常独立按键检测异常LED灯闪烁异常使用逻辑分析仪抓取了一下波形发现有周期性的高电平产生为什么会这样哪现在我的知识能力还不能分析定位原因我猜测可能是我的PC USB口供电能力不足也不应该呀因为USB直接驱动直流电机旋转不加PWM调速的时候是没问题的PWM输出占空比的方波调速接上直流电机为什么会造成单片机运行异常哪 问题元凶发现
对比江协科技提供的电机调速的源码文件才发现我写的PWM电机调速源码源码之所以不能正常工作的原因是定时器的溢出周期太长即PWM的周期
定时器Timer0的定时器溢出周期也就是PWM调速的周期值写成了 1ms 定时器超时一次然后每100次定时器超时作为一个PWM周期这样我写的PWM电机调速程序的PWM周期就变成了 100ms频率为 1000/100ms10Hz这样的PWM频率太低了电机当然就不能正产平稳的运转了这也就是我刚开始的时候听到直流电机的运转声音不平稳卡顿的原因。 并且因为我的PWM调速频率为10Hz电机频繁的启停电机作为感性负载原件它的电感是比较大的当电机频繁启停的时候电机就感应出了很大的感应电压对单片机的运行造成了干扰造成独立按键被干扰检测异常参考江协科技的电机PWM调速示例源码其中定时器Timer0的溢出周期为 100us定时器timer0每溢出100次为一个PWM周期计算出PWM频率1000*1000us/(100us*100)100Hz这样的PWM调速频率就能够满足直流电机的平稳运行了。
这个错误页进一步的提醒我注意PWM调制的三个关键参数 PWM频率PWM占空比PWM精度步距 PWM的频率越高负载运行的越平稳如果频率过低可能就会出现电机的抖动。
并且因为电机的频繁抖动频繁启停电机作为感性器件感应出来的电压波动还可能会对单片机的执行造成干扰造成按键检测异常误检测。 5.2 PWM驱动电机的频率选择
PWM驱动电机的频率在一定范围内越快越好越快越稳定但也不能过快过快的的话就会增加开关的损耗时间并且也会增加系统资源的负载中断太多了驱动电机的时候PWM我们通常设置在10K~20KHz这个范围。
如果这个PWM频率太低的话电机就会抖动如果在1KHz的时候电机可能会出现鸣叫。但是51单片机的主频比较低没有办法设置到那么高的频率。