专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

直流电机脉宽调速

作者:佚名   来源:本站原创   点击数:  更新时间:2014年04月28日   【字体:

测试环境MPLAB IDE v8.73
测试芯片:PIC16F877A
所需器件


PIC16F877A单片机最小系统
 


L298N电机驱动模块


4P杜邦线


最终的主要的电路实物连接图


最终测试图



电路连接图:
 对应程序一的电路原理图

程序一:简单实现两个电机的正反转,未加调速。
#include <pic.h>       //调用头文件,可以去PICC软件下去查找PIC16F87XA单片机的头文件
__CONFIG(XT&WDTDIS&LVPDIS);    //定义配置字,晶振类型:XT,关闭开门狗,禁止低电压编程
/*宏定义区*/
#define IN1 RB7//Left Motor
#define IN2 RB6//Left Motor
#define IN3 RB5//Right Motor
#define IN4 RB4//Right Motor
/*相关函数声明部分*/
void delay_ms(unsigned int ms);//声明延时函数
void IO_Config(void);//声明IO配置函数
void Motor_Go_Forward(void);//声明前进函数
void Motor_Go_Back(void);//声明后退函数
void Motor_Turn_Left(void);//声明左转函数
void Motor_Turn_Right(void);//声明右转函数
//-----------------------------------------
//Name: 系统主函数  
//Created By: xd
//Email: 58969288@qq.com
//Date: 2014-04-05
//-----------------------------------------
void main(void)
{
     IO_Config();//调用IO配置函数
     while(1)
    {
        Motor_Go_Forward();//小车前进
        Motor_Go_Back();//小车后退
        Motor_Turn_Right();//小车右转
        Motor_Turn_Left();//小车左转
    }
}
//-----------------------------------------
//Name: 延时函数
//Description:to delay time  
//Created By: xd
//Email: 58969288@qq.com
//Date: 2014-04-05
void delay_ms(unsigned int ms)
{
 while(--ms);
}
//-----------------------------------------
//Name: IO配置函数 
//Created By: xd
//Email: 58969288@qq.com
//Date: 2014-04-05
//-----------------------------------------
void IO_Config(void){
 TRISA = 0B11111111;  //RA0-RA7设置为输入
 TRISB = 0B00001111;  //RB0-RB3设置为输入,RB4-RB7设置为输出
 TRISC = 0B00000000;  //RC0-RC7设置为输出
 TRISD = 0B00000000;  //RD0-RD7设置为输出
 PORTB = 0B00000000;  //RB初始化输出或输入低电平 
 PORTC = 0B00000000;  //RC初始化输出低电平
 PORTD = 0B00000000;  //RD初始化输出低电平
 
}
//-----------------------------------------
//Name: 前进函数 
//Description:Left Motor↑ Right Motor↓ 
//Created By: xd
//Email: 58969288@qq.com
//Date: 20104-04-05
//-----------------------------------------
void Motor_Go_Forward(void){
 IN1 = 0;
 IN2 = 1;
 IN3 = 0;
 IN4 = 1; 
}
//-----------------------------------------
//Name: 后退函数 
//Description:Left Motor↓ Right Motor↓ 
//Created By: xd
//Email: 58969288@qq.com
//Date: 2014-04-05
//-----------------------------------------
void Motor_Go_Back(void){
 IN1 = 1;
 IN2 = 0;
 IN3 = 1;
 IN4 = 0; 
}
//-----------------------------------------
//Name: 右转函数
//Description:Left Motor↑ Right Motor↓  
//Created By: xd
//Email: 58969288@qq.com
//Date: 2014-04-05
//-----------------------------------------
void Motor_Turn_Right(void){
 IN1 = 1;
 IN2 = 0;
 IN3 = 0;
 IN4 = 1; 
}
//-----------------------------------------
//Name: 左转函数 
//Description:Left Motor↓ Right Motor↑ 
//Created By: xd
//Email: 58969288@qq.com
//Date: 2014-04-05
//-----------------------------------------
void Motor_Turn_Left(void){
 IN1 = 0;
 IN2 = 1;
 IN3 = 1;
 IN4 = 0; 
}
 
程序二:可以实现直流电机的调速,这里在上面的原理基础上,将L298N模块的ENA和ENB连接的短接冒拔下来,将ENA接在RC1上,ENB接在RC2上。
#include <pic.h>//调用头文件
__CONFIG(XT & WDTDIS & LVPDIS);//定义配置字,晶振类型:XT,关闭开门狗,禁止低电压编程
/*宏定义区*/
#define IN1 RB7//Left Motor,L298N模块的IN1
#define IN2 RB6//Left Motor,L298N模块的IN1
#define IN3 RB5//Right Motor,L298N模块的IN1
#define IN4 RB4//Right Motor,L298N模块的IN1
 
/*相关函数声明部分*/
void IO_Config(void);//声明IO配置函数
void PWM_Init(void);//声明PWM初始化函数
void Motor_Speed_Config(unsigned char PWM1,unsigned char PWM2);//声明电机速度调节函数
//-----------------------------------------
//Name: 系统主函数  
//Created By: xd
//Email: 58969288@qq.com
//Date: 2014-04-05
//-----------------------------------------
void main(void)            //主函数,单片机开机后就是从这个函数开始运行
{
IO_Config();//调用IO端口配置函数
PWM_Init();//调用PWM初始化函数
while(1)               //死循环,单片机初始化后,将一直运行这个死循环
{
//占空比为0%      --传的实参为0
//占空比为20%    --传的实参为20
//占空比为40%    --传的实参为40
//占空比为60%    --传的实参为60
//占空比为80%    --传的实参为80
//占空比为100%  --传的实参为100
 
//当调用void Motor_Speed_Config(unsigned char PWM1,unsigned char PWM2)
//时传入的两个参数如果相等的话,左右电机将获得相同占空比的PWM信号,此时小
//可以前进或者后退;当传入的两个参数不相等的话,那么左右电机将获得不同占空比
//的PWM,获得的速度也就会不一样,这样就会实现小车的左转或右转的效果,当
//占空比设置为0时,小车的左右电机停止转动,可以实现小车停车效果
Motor_Speed_Config(100,100);
}
}
//-----------------------------------------
//Name: PWM初始化函数  
//Created By: xd
//Email: 58969288@qq.com
//Date: 2014-04-05
//-----------------------------------------
void PWM_Init(void){
//PWM周期 = (PR2 + 1) * 4 * Tosc * (TMR2预分频值)
//PWM频率 = 1/【PWM周期】
//其中Tosc这里为4MHz,TMR2预分频值下面设置的为1
CCP1CON = 0B00001100; //设置CCP1为PWM模式,PWM占空比bit1:0,bit0:0;
CCP2CON = 0B00001100; //设置CCP2为PWM模式,PWM占空比bit1:0,bit0:0;
PR2 = 99;//频频:10.000KHZ周期:0.0001s
 
/*T2CKPS1:T2CKPS0:TMR2时钟预分频选择位*/
/*0 0 = 预分频值为1*/
/*0 1 = 预分频值为4*/
/*1 x = 预分频值为16*/
T2CKPS1 = 0;
T2CKPS0 = 0;//前分频为1:1
TMR2IF = 0;//清零PIR1寄存器中的TMR2IF中断标志位
TMR2ON = 1;//启动TIMER2
//PWM占空比 = (CCPRxL:CCPxCON<5:4>) * Tosc * (TMR2预分频值)   
CCPR1L = 0;//占空比初始值为0
CCPR2L = 0;//占空比初始值为0
//这里具体说明下占空比的计算方法:例如要设置占空比为80%,这里PWM
//周期设置为0.0001s,0.0001 * 80% = x * 1/4MHz * 1
//计算得到x = 320,因为CCP1CON = 0B00001100或者CCP2CON = 0B00001100;
//这么设置的,那么PWM占空比的bit1:0,bit0:0;CCPR1L或CCPR2L为其bit9-bit2,
//所以写入CCPR1L或CCPR2L中的值为320除以4等于80,即输出占空比为80%的PWM信号
//就往CCPR1L或CCPR2L中写入80,这样在RC1或RC2引脚上就可以输出相应占空比的
//的PWM信号,设置PWM频率为10KHz,有个好处就是,这里计算占空比很容易,设置
 
//占空比的数值和写入CCPR1L或CCPR2L中的值一样
/*T2CKPS1:T2CKPS0:TMR2时钟预分频选择位*/
/*0 0 = 预分频值为1*/
/*0 1 = 预分频值为4*/
 /*1 x = 预分频值为16*/
 T2CKPS1 = 0;
 T2CKPS0 = 0;//前分频为1:1
 TMR2IF = 0;//清零PIR1寄存器中的TMR2IF中断标志位
 TMR2ON = 1;//启动TIMER2
}
//-----------------------------------------
//Name: IO配置函数 
//Created By: xd
//Email: 58969288@qq.com
//Date: 2014-04-05
//-----------------------------------------
void IO_Config(void){
TRISA = 0B11111111;       //RA0-RA7设置为输入
TRISB = 0B00001111;    //RB0-RB3设置为输入,RB4-RB7设置为输出
TRISC = 0B00000000;    //RC0-RC7设置为输出
TRISD = 0B00000000;    //RD0-RD7设置为输出
PORTB = 0B00000000;  //RB初始化输出或输入低电平 
PORTC = 0B00000000;  //RC初始化输出低电平
PORTD = 0B00000000;  //RD初始化输出低电平
}
//-----------------------------------------
//Name: 电机速度调节函数 
//Description: 
//Created By: xd
//Email: 58969288@qq.com
//Date: 2014-04-05
//-----------------------------------------
void Motor_Speed_Config(unsigned char PWM1,unsigned char PWM2){
CCPR1L = PWM1;
IN1 = 0;
IN2 = 1;
CCPR2L = PWM2;
IN3 = 0;
IN4 = 1; 
}
 
关闭窗口

相关文章