/*
用S51单片机控制驱动芯片L298驱动1路直流电机程序(C语言)
*/
#include
#define uint unsigned int
#define uchar unsigned char
#define MAX_TIMER_COUNT 0xffff //
#define TIMER_PERIOD_VALUE 0xfc18 //PWM周期,1ms
#define KEY_0 0x01 //键值
#define KEY_1 0x02
#define KEY_2 0x04
#define KEY_3 0x08
#define ForWard 0 //正向
#define Reverse 1 //反向
#define True 1
#define False 0
// 电机驱动引脚定义
sbit MA=P1^4; //
sbit MB=P1^5;
sbit MC=P1^6;
sbit MD=P1^7;
sbit LED = P0^0; //测试LED
sbit EN1_PWM = P3^5; //PWM使能输出脚
uchar STH0 = 0; //T0计数缓存
uchar STL0 = 0;
uchar STH1 = 0; //T1计数缓存
uchar STL1 = 0;
bit Breaked = False; //刹车停止标志
bit Running = False; //运行标志
bit Direction = ForWard; //方向标志
uint MaxPeriodCNT = MAX_TIMER_COUNT - TIMER_PERIOD_VALUE; //PWM周
期,1ms
//static int spcount = 0; //步进电机转速参数计数
/*********************************************************
发送数据子函数
*********************************************************/
/*void txdata(uchar dat)
{
SBUF = dat; //发送数据
while (!TI);//等待数据发送完中断
TI = 0; //清中断标志
}*/
void delay(unsigned int N)
{
int i;
for(i=0;i
}
void setMotorA_ForWard() //设为正向
{
MA = 1;
MB = 0;
Breaked = False;
Direction = ForWard; //正向标志
}
void setMotorA_Reverse() //设为反向
{
MA = 0;
MB = 1;
Breaked = False;
Direction = Reverse; //反向
}
void setMotorA_FastBreak() //快速停转
{
MA = 0;
MB = 0;
Breaked = True; //已刹车(停止)
Running = False; //电机运行停止
}
void setMotorA_FreeStop() //自由停转
{
TR0=0 ; //关定时器0
TR1=0 ; //关定时器1
EN1_PWM = 0;
Running = False; //电机运行停止
}
void setMotorA_Speed(uchar duty) //uint duty为占比值乘100后的整数
{
uint THiVot ; //
uint TLoVot ; //
uint tmp = MAX_TIMER_COUNT - MaxPeriodCNT * (double)(duty / 100.0);
THiVot = TIMER_PERIOD_VALUE; //这里计算PWM占空比对应的高电平 if (tmp > THiVot) //高电平时间计数要比周期值计数值大 {
TLoVot = tmp; //这里计算PWM占空比对应的高电平 }
//setMotorA_FreeStop();
//高电时间
STH0 = THiVot/256;
STL0 = THiVot%256;
//低电时间
STH1 = TLoVot/256;
STL1 = TLoVot%256;
TR0=1;
}
void setMotorA_Start() //启动直流电机
{
if (Breaked) //已快速制动(刹车)
{
setMotorA_Reverse();
}
Breaked = False;
TR1=0 ; //关定时器1
TH0 = STH0;
TL0 = STL0; //重新加载定时器0初值
TR0=1;
TR0=1 ; //开定时器0
Running = True; //已运行
}
void system_init(void )
{
TMOD=0x11;
EA=1; //全局中断开
ET0=1; //ET0 : T0的溢出中断允许位。ET0=1,允许T0中断;ET0=0禁止T0中断。
ET1=1; //ET1 : 定时/计数器T1的溢出中断允许位。ET1=1,允许T1中断;ET1=0,禁止T1中断。
setMotorA_FreeStop(); //开机停转
}
/*********************************************************/
// 定时器0中断服务程序.作为PWM周期定时
/*********************************************************/
void timer0() interrupt 1
{
//TR0 = 0 ; //关定时器0
TH0 = STH0; //把新的脉宽值给定时器1
TL0 = STL0; //把新的脉宽值给定时器1
//TR0 = 1 ; //开定时器0
EN1_PWM = 1; //PWM输出高电平
TH1 = STH1; //把新的脉宽值给定时器1
TL1 = STL1; //把新的脉宽值给定时器1
TR1 = 1 ; //开定时器1
}
/*********************************************************/
// 定时器1中断服务程序.作为PWM高电平定时
/*********************************************************/
void timer1() interrupt 3
{
TR1=0; //关定时器1
EN1_PWM = 0; //PWM输出低电平
//TH0 = STH0;
//TL0 = STL0; //重新加载定时器0初值
//TR0=1;
}
/**************************************************************** the function: 转换键值,将硬件键值转换成逻辑键值。
*****************************************************************/ uchar getKeyValue(uchar i)
{
uchar keyvalue = 0xff;
switch(i)
{
case KEY_0: keyvalue = 0x00; break;
case KEY_1: keyvalue = 0x01; break;
case KEY_2: keyvalue = 0x02; break;
case KEY_3: keyvalue = 0x03; break;
default : keyvalue = 0xff;
}
return keyvalue;
}
/**************************************************************** the function:独立键盘,由于本版开发板删除了矩阵键盘,
只保4个独立键盘,所以本实验仅作为原理演示之用。
*****************************************************************/ uchar checkInput(void)
{
P1 |= 0x0f;
return ~(P1 | 0xf0); //取反键值,方便键值 }
void main(void)
{
uchar i = 0;
uchar duty = 10; //占空比值
uchar preKey = 0xff; //前一时刻的键值
system_init(); //初始化
setMotorA_ForWard(); while(1) { i = checkInput(); //设为正转方向 i = getKeyValue(i); if (preKey == 0xff) //有按键 { switch(i) { case 0: if (duty0) //占空比大于0 { duty-=5; } setMotorA_Speed(duty); break; case 2: if (Direction == ForWard) //更改方向 { setMotorA_Reverse(); } else { setMotorA_ForWard(); } break; case 3: if (!Running) //更改运行状态 { setMotorA_Start(); } else { setMotorA_FreeStop(); } break;
} } } P0 = duty; //LED = Direction; preKey = i; delay(100); //输出占空比值 //保存键值
/*
用S51单片机控制驱动芯片L298驱动1路直流电机程序(C语言)
*/
#include
#define uint unsigned int
#define uchar unsigned char
#define MAX_TIMER_COUNT 0xffff //
#define TIMER_PERIOD_VALUE 0xfc18 //PWM周期,1ms
#define KEY_0 0x01 //键值
#define KEY_1 0x02
#define KEY_2 0x04
#define KEY_3 0x08
#define ForWard 0 //正向
#define Reverse 1 //反向
#define True 1
#define False 0
// 电机驱动引脚定义
sbit MA=P1^4; //
sbit MB=P1^5;
sbit MC=P1^6;
sbit MD=P1^7;
sbit LED = P0^0; //测试LED
sbit EN1_PWM = P3^5; //PWM使能输出脚
uchar STH0 = 0; //T0计数缓存
uchar STL0 = 0;
uchar STH1 = 0; //T1计数缓存
uchar STL1 = 0;
bit Breaked = False; //刹车停止标志
bit Running = False; //运行标志
bit Direction = ForWard; //方向标志
uint MaxPeriodCNT = MAX_TIMER_COUNT - TIMER_PERIOD_VALUE; //PWM周
期,1ms
//static int spcount = 0; //步进电机转速参数计数
/*********************************************************
发送数据子函数
*********************************************************/
/*void txdata(uchar dat)
{
SBUF = dat; //发送数据
while (!TI);//等待数据发送完中断
TI = 0; //清中断标志
}*/
void delay(unsigned int N)
{
int i;
for(i=0;i
}
void setMotorA_ForWard() //设为正向
{
MA = 1;
MB = 0;
Breaked = False;
Direction = ForWard; //正向标志
}
void setMotorA_Reverse() //设为反向
{
MA = 0;
MB = 1;
Breaked = False;
Direction = Reverse; //反向
}
void setMotorA_FastBreak() //快速停转
{
MA = 0;
MB = 0;
Breaked = True; //已刹车(停止)
Running = False; //电机运行停止
}
void setMotorA_FreeStop() //自由停转
{
TR0=0 ; //关定时器0
TR1=0 ; //关定时器1
EN1_PWM = 0;
Running = False; //电机运行停止
}
void setMotorA_Speed(uchar duty) //uint duty为占比值乘100后的整数
{
uint THiVot ; //
uint TLoVot ; //
uint tmp = MAX_TIMER_COUNT - MaxPeriodCNT * (double)(duty / 100.0);
THiVot = TIMER_PERIOD_VALUE; //这里计算PWM占空比对应的高电平 if (tmp > THiVot) //高电平时间计数要比周期值计数值大 {
TLoVot = tmp; //这里计算PWM占空比对应的高电平 }
//setMotorA_FreeStop();
//高电时间
STH0 = THiVot/256;
STL0 = THiVot%256;
//低电时间
STH1 = TLoVot/256;
STL1 = TLoVot%256;
TR0=1;
}
void setMotorA_Start() //启动直流电机
{
if (Breaked) //已快速制动(刹车)
{
setMotorA_Reverse();
}
Breaked = False;
TR1=0 ; //关定时器1
TH0 = STH0;
TL0 = STL0; //重新加载定时器0初值
TR0=1;
TR0=1 ; //开定时器0
Running = True; //已运行
}
void system_init(void )
{
TMOD=0x11;
EA=1; //全局中断开
ET0=1; //ET0 : T0的溢出中断允许位。ET0=1,允许T0中断;ET0=0禁止T0中断。
ET1=1; //ET1 : 定时/计数器T1的溢出中断允许位。ET1=1,允许T1中断;ET1=0,禁止T1中断。
setMotorA_FreeStop(); //开机停转
}
/*********************************************************/
// 定时器0中断服务程序.作为PWM周期定时
/*********************************************************/
void timer0() interrupt 1
{
//TR0 = 0 ; //关定时器0
TH0 = STH0; //把新的脉宽值给定时器1
TL0 = STL0; //把新的脉宽值给定时器1
//TR0 = 1 ; //开定时器0
EN1_PWM = 1; //PWM输出高电平
TH1 = STH1; //把新的脉宽值给定时器1
TL1 = STL1; //把新的脉宽值给定时器1
TR1 = 1 ; //开定时器1
}
/*********************************************************/
// 定时器1中断服务程序.作为PWM高电平定时
/*********************************************************/
void timer1() interrupt 3
{
TR1=0; //关定时器1
EN1_PWM = 0; //PWM输出低电平
//TH0 = STH0;
//TL0 = STL0; //重新加载定时器0初值
//TR0=1;
}
/**************************************************************** the function: 转换键值,将硬件键值转换成逻辑键值。
*****************************************************************/ uchar getKeyValue(uchar i)
{
uchar keyvalue = 0xff;
switch(i)
{
case KEY_0: keyvalue = 0x00; break;
case KEY_1: keyvalue = 0x01; break;
case KEY_2: keyvalue = 0x02; break;
case KEY_3: keyvalue = 0x03; break;
default : keyvalue = 0xff;
}
return keyvalue;
}
/**************************************************************** the function:独立键盘,由于本版开发板删除了矩阵键盘,
只保4个独立键盘,所以本实验仅作为原理演示之用。
*****************************************************************/ uchar checkInput(void)
{
P1 |= 0x0f;
return ~(P1 | 0xf0); //取反键值,方便键值 }
void main(void)
{
uchar i = 0;
uchar duty = 10; //占空比值
uchar preKey = 0xff; //前一时刻的键值
system_init(); //初始化
setMotorA_ForWard(); while(1) { i = checkInput(); //设为正转方向 i = getKeyValue(i); if (preKey == 0xff) //有按键 { switch(i) { case 0: if (duty0) //占空比大于0 { duty-=5; } setMotorA_Speed(duty); break; case 2: if (Direction == ForWard) //更改方向 { setMotorA_Reverse(); } else { setMotorA_ForWard(); } break; case 3: if (!Running) //更改运行状态 { setMotorA_Start(); } else { setMotorA_FreeStop(); } break;
} } } P0 = duty; //LED = Direction; preKey = i; delay(100); //输出占空比值 //保存键值