//-----------------------函数声明,变量定义--------------------------------------------------------
#include <reg51.h>
sbit INT_0 =P3^2; // 将p3.2外部中断0
sbit pulse_A=P1^2; // P1.2为脉冲A输入
sbit PWM=P1^0; //PWM波形输出
sbit DR=P1^1; //方向控制
//-----------------------预定义值--------------------------------------------------------
#define PWM_T 1800 //定义PWM的周期T为18ms
#define Ts 1000 //定义光电编码器采样时间为10ms
#define timer_data (256-10) //定时器预置值,12M时钟是,定时0.01ms
//-----------------------预设定值--------------------------------------------------------
bit direction; //方向标志位 用户设定
unsigned char R; //需要得到的直流电机转速 用户设定
//-----------------------实际运行状态--------------------------------------------------------
bit real_direction; //电机实际运行方向
unsigned char Rr; //直流电机实际转速
//-----------------------计算所得补偿状态------------------------------------------
bit compensate_polarity; //补偿极性
unsigned char dR; //转速补偿
//-----------------------经补偿后得到的脉宽------------------------------------------
unsigned char PWM_t; //PWM_t为脉冲宽度(320~400)时间为3.2~4.0ms
unsigned char PWM_count; //输出PWM周期计数
//-----------------------各中间计数值------------------------------------------
unsigned char pulseB_count; //脉冲计数
unsigned char time0_count; //定时计数
unsigned char time1_count; //定时计数
//--------------------------------------------------------------------------------------------------
// 函数名称:timer_init
// 函数功能:初始化设置定时器
//--------------------------------------------------------------------------------------------------
void timer_init()
{
TMOD=0x22; /*定时器1为工作模式2(8位自动重装),0为模式2(8位自动重装) */
PCON=0x00;
TF0=0;
TH0=timer_data; //保证定时时长为0.01ms
TL0=TH0;
TH1=timer_data; //保证定时时长为0.01ms
TL1=TH0;
ET0=1; //定时器0中断允许
TR0=1; //定时器0开始计数
ET1=1; //定时器1中断允许
TR1=1; //定时器1开始计数
EA=1; //中断允许
}
//--------------------------------------------------------------------------------------------------
// 函数名称: INT0_init()
// 函数功能: 初始化设置
// 设定INT0的工作方式
//--------------------------------------------------------------------------------------------------
void INT0_init(void )
{
pulseB_count=0; //脉冲计数器清零
IT0=1; //选择INT0为沿触发方式
EX0=1; //外部中断允许
EA=1; //系统中断允许
}
//--------------------------------------------------------------------------------------------------
// 函数名称:setting_PWM
// 函数功能:设置PWM的脉冲宽度和设定方向
//--------------------------------------------------------------------------------------------------
void setting_PWM()
{
// direction=1; //设定转动方向
// R=540; //设定转速
// dR=0; //转速补偿为零
// calculate_PWM_t(); //重新计算脉宽
}
//--------------------------------------------------------------------------------------------------
// 函数名称: calculate_PWM_t
// 入口参数: R需要得到的直流电机转速,dR转速补偿
// 出口参数: PWM_t为脉冲宽度(320~400)时间为3.2~4.0ms
// 函数功能: 计算脉冲宽度,PWM_t=R/150;
//--------------------------------------------------------------------------------------------------
void calculate_PWM_t()
{
if(compensate_polarity==1) //正补偿
PWM_t=(R+dR)/150;
else
PWM_t=(R-dR)/150; //负修正
}
//--------------------------------------------------------------------------------------------------
// 函数名称: calculate_Rr
// 入口参数: pulseB_count脉冲计数
// 出口参数: Rr直流电机实际转速
// 函数功能: 计算实际转速
//--------------------------------------------------------------------------------------------------
void calculate_Rr()
{
Rr=pulseB_count/6;
}
//--------------------------------------------------------------------------------------------------
// 函数名称: compensate_dR
// 入口参数: Rr直流电机实际转速
// R需要得到的直流电机转速
// 出口参数: dR转速补偿
// 函数功能: 计算实际补偿值和补偿极性 ,根据不同的补偿算法重新设计
//--------------------------------------------------------------------------------------------------
void compensate_Rr()
{
Rr=1;
if(Rr>R)
compensate_polarity=0; //补偿极性
else
compensate_polarity=1;
}
//--------------------------------------------------------------------------------------------------
// 函数名称: INT0_intrupt
// 函数功能: 外部中断0处理程序
//--------------------------------------------------------------------------------------------------
void INT0_intrupt() interrupt 0 using 1
{
pulseB_count++;
if(pulse_A==0)
{
real_direction=1; //若P1.2为低电平,则电机为正转,计数器N的值加1
}
else //若为高电平,则电机为反转,计数器N值减l。
{
real_direction=1;
}
}
//--------------------------------------------------------------------------------------------------
// 函数名称:IntTimer0
// 函数功能:定时器中断处理程序
//--------------------------------------------------------------------------------------------------
void IntTimer0() interrupt 1
{
time0_count++;
DR=direction;
if(time0_count>=PWM_T)
{
time0_count=0;
PWM_count++;
setting_PWM(); //每输出一个PWM波调用一次
}
if(time0_count<PWM_t)
PWM=1;
else
PWM=0;
}
//--------------------------------------------------------------------------------------------------
// 函数名称:IntTimer1
// 函数功能:定时器中断处理程序
//--------------------------------------------------------------------------------------------------
void IntTimer1() interrupt 3
{
time1_count++;
if(time1_count==1)
{
INT0_init(); //初始化外部中断设置
}
if(time1_count>=Ts)
{
time1_count=0; //一个补偿周期结束,计数器清零
calculate_Rr(); //计算实际转速
compensate_Rr(); //计算实际补偿值和补偿极性
calculate_PWM_t(); //重新计算脉宽
}
}
//--------------------------------------------------------------------------------------------------
// 函数名称:main
// 用户主函数
// 函数功能:主函数
//--------------------------------------------------------------------------------------------------
void main()
{
direction=1; //设定转动方向
R=540; //设定转速
dR=0; //转速补偿为零
calculate_PWM_t(); //重新计算脉宽
timer_init();
}
iloveyoujunping
- 粉丝: 11
- 资源: 14
最新资源
- PIPE物理层接口规范:PCIe SATA USB3.1 DisplayPort 和 Converged IO 架构
- SparkSQL进阶操作相关数据
- java制作的小游戏,作为巩固java知识之用.zip
- Java语言写的围棋小游戏 半成品A Go game written in golang(Semi-finished).zip
- 基于Java-swing的俄罗斯方块游戏:源码+答辩文档+PPT.zip
- florr map详细版
- shiahdifhiahfiqefiwhfi weifwijfiwqufiqweefijeq0jfe
- registry-2.8.3<arm/amd>二进制文件
- Kotlin接口与抽象类详解及其应用
- 51单片机加减乘除计算器系统设计(proteus8.17,keil5),复制粘贴就可以运行
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈