測試環境: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;
}