【51单片机学习】:使用PWM调节电机速度

简单的PWM电机调速–基于51单片机

  • (一)51单片机需要用到的寄存器
  • (二)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波的产生及调速原理

    了解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定时器的计数值是分成高四位和低四位分别存放在寄存器THTL当中,因此需要分别设置TH0TL0的值
    特别注意
    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;		//打开定时器
    }
    

    现在定时器部分已经配置好了,现在开始配置一下电机,直流电机有两个接口IN1IN2(这里使用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;
    				 }
    }
    

    这些程序只是简单的调速,要制作出一辆简易循迹小车还需要学习更多东西

    物联沃分享整理
    物联沃-IOTWORD物联网 » 【51单片机学习】:使用PWM调节电机速度

    发表评论