简单的PWM电机调速--基于51单片机
中断允许寄存器,详情可以看STC51单片机芯片手册第160页
TMOD、TCON详情可以看STC51单片机芯片手册第187页
51单片机中的定时器有三个,(C52比C51多了一个定时器3,但这些都统称为51单片机)
本次以Timer0为例进行介绍
定时器的作用:
1:用于计时系统,可实现软件计时,或者使程序每隔一段固定的时间完成一项操作
2:替代长时间delay,提高CPU的运行效率和处理速度
因为delay延时函数会占用代码的运行空间、影响代码运行速度
通过查看芯片手册我们知道Timer0有四种工作模式,通过配置寄存器TMOD来选择模式
模式0:13位定时器/计数器
模式1:16位定时器/计数器
模式2:8位自动重装模式
模式3;两个8位计数器
而寄存器TCON作用是控制定时器的启、停,标志定时器溢出和中断情况
TCON(可位寻址)用于设置定时器的控制状态
TMOD(不可位寻址)用于设置定时器的模式
这两个寄存器都分别有8位,每一位都有相应的功能

定时器0的中断触发方式,是由寄存器中TCON中的第六位TF0控制。当定时器计数溢出时,就会给TF0一个标志位,单片机检测到这个标志位就会触发一次定时器中断,执行中断函数,执行完之后就会重新给标志位清零
对于51单片机定时器的详细介绍跳转连接
介绍TMOD和TCON的博客

了解PWM可以点击此处
通过调节PMW的占空比来实现对电机的速度控制,PWM的周期非常的小、其周期信号从宏观来看、电压与时间所围成面积等效于一个正弦信号,因此也可以用PWM来制作呼吸灯。
51单片机的定时器每1us计数值增加1
TH=(65536-time/(12/ft))/256
其中,time就是要延时的时间(单位:us),ft是晶振频率。这个式子又可以简化成TH=(65536-time*ft/12)/256
TL=(65536-time*ft/12)%256
首先初始化定时器,这里选择51单片机的Timer0定时器
51定时器的计数值是分成高四位和低四位分别存放在寄存器TH和TL当中,因此需要分别设置TH0和TL0的值
特别注意
TMOD寄存器是不可位寻址的(即不能对TMOD的中的8位单独赋值),只能一次性给8位全部赋值。
void Timer0_Init()//这里以定时器0为例
{
/*
TMOD的低四位控制定时器0
0位:M0
1位:M1
2位:C/T:置0为定时器模式,置1为计数器模式
3位:GATE
*/
/* 设置定时器模式1,计数模式(16位定时器,最大值65535)*/
TMOD &=~0xFF;//所有位全部置0
TMOD |=0x01;//高四位保持不变,低0位置1
/*设置定时器0.01ms中断一次*/
TH0 = 0XFF;//定时器0高位的初始值;(65536-10)/256
TL0 = 0XF7;//定时器0低位的初始值;(65536-10)%256
EA = 1;//使能所有中断中断
ET0 = 1;//使能定时器0中断
TR0 = 1;//允许定时器0开始从1开始计数,启动定时器
}
现在已经初始化好了51单片机定时器0,现在开始设置定时器中断函数
51单片机中具有一种特性,每次进入定时器中断都会将之前在初始化定时器函数中设置的初始值清0,所以每次进入定时器中断都需要在中断函数中重新赋给定时器初始值
uint Counter,Compare;//定义两个变量,Counter用于计数(即每进入一次中断Counter+1)
//Compare用于设置PWM波占空比
void Timer0_Routine() interrupt 1
{
TR0=0; //赋初值时,关闭定时器
TH0=0xff; //(65536-10)/256;//赋初值定时
TL0=0xf7; //(65536-10)%256;//0.01ms
Counter++;
if(Counter>100)
{
Counter=0; //1khz,每触发一次Counter+1,每到加到100清零
//所以一个pwm周期时间为100x0.01ms=1ms
}
TR0=1; //打开定时器
}
现在定时器部分已经配置好了,现在开始配置一下电机,直流电机有两个接口IN1和IN2(这里使用TT马达为例)
其中一个接口给高电平另一个给低电平就能实现电机旋转。
/*
Compare为设置电机PWM的占空比
direction设置电机的正转和反转
*/
void dianji(uchar Compare,uchar direction) //定义一个电机
{ /*确保占空比在0%-100%之间*/
if(Compare>100)
{
Compare=100;
}
if(Compare<0)
{
Compare=0;
}
/*确定电机的旋转方向*/
switch(direction) //case 0正转 case 1反转
{
case 0:
{
if(Compare>Counter) //将设定的占空比和计数值进行比较
{IN1=1;IN2=0;}
else
{IN1=0;IN2=0;}
}
break;
case 1:
{
if(Compare>Counter)
{IN1=0;IN2=1;}
else
{IN1=0;IN2=0;}
}
break;
}
}
这些程序只是简单的调速,要制作出一辆简易循迹小车还需要学习更多东西
说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总
深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal
我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or
如何学习ruby的正则表达式?(对于假人) 最佳答案 http://www.rubular.com/在Ruby中使用正则表达式时是一个很棒的工具,因为它可以立即将结果可视化。 关于ruby-我如何学习ruby的正则表达式?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1881231/
深度学习12.CNN经典网络VGG16一、简介1.VGG来源2.VGG分类3.不同模型的参数数量4.3x3卷积核的好处5.关于学习率调度6.批归一化二、VGG16层分析1.层划分2.参数展开过程图解3.参数传递示例4.VGG16各层参数数量三、代码分析1.VGG16模型定义2.训练3.测试一、简介1.VGG来源VGG(VisualGeometryGroup)是一个视觉几何组在2014年提出的深度卷积神经网络架构。VGG在2014年ImageNet图像分类竞赛亚军,定位竞赛冠军;VGG网络采用连续的小卷积核(3x3)和池化层构建深度神经网络,网络深度可以达到16层或19层,其中VGG16和VGG
文章目录1、自相关函数ACF2、偏自相关函数PACF3、ARIMA(p,d,q)的阶数判断4、代码实现1、引入所需依赖2、数据读取与处理3、一阶差分与绘图4、ACF5、PACF1、自相关函数ACF自相关函数反映了同一序列在不同时序的取值之间的相关性。公式:ACF(k)=ρk=Cov(yt,yt−k)Var(yt)ACF(k)=\rho_{k}=\frac{Cov(y_{t},y_{t-k})}{Var(y_{t})}ACF(k)=ρk=Var(yt)Cov(yt,yt−k)其中分子用于求协方差矩阵,分母用于计算样本方差。求出的ACF值为[-1,1]。但对于一个平稳的AR模型,求出其滞
写在之前Shader变体、Shader属性定义技巧、自定义材质面板,这三个知识点任何一个单拿出来都是一套知识体系,不能一概而论,本文章目的在于将学习和实际工作中遇见的问题进行总结,类似于网络笔记之用,方便后续回顾查看,如有以偏概全、不祥不尽之处,还望海涵。1、Shader变体先看一段代码......Properties{ [KeywordEnum(on,off)]USL_USE_COL("IsUseColorMixTex?",int)=0 [Toggle(IS_RED_ON)]_IsRed("IsRed?",int)=0}......//中间省略,后续会有完整代码 #pragmamulti_c
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它