测试环境: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;
}