- 打卡等级:偶尔看看I
- 打卡总天数:15
- 最近打卡:2025-03-26 09:09:59
中级会员
- 积分
- 351
|
发表于 2024-10-9 08:46:34
|
显示全部楼层
梁工好,您好,能麻烦您帮我看看嘛?我希望得到的是按下按键转一圈,转到一圈即使按着按键也不动了,松开按键,回到原点。但是现在实际情况是这样,按着按键转一圈后,不停下 还会缓慢转动,但是释放按键后,回到原点,不在转动,这是怎么回事呢。并且调用StopMotor1后电机怎么都不动了
#include "STC8Hxxx.h" //包含此头文件后,不需要再包含"reg51.h"头文件
#include "test.h"
#include "SineTable-256.h"
#define MAIN_Fosc 24000000L //定义主时钟
/************* 功能说明 **************
程序使用
AIN1-P1.1
AIN2-P1.2
BIN1-P1.5
BIN2-P3.4
驱动步进电机
******************************************/
#include "intrins.h"
sfr VRTRIM = 0xA6;
#define CLKSEL (*(unsigned char volatile xdata *)0xfe00)
#define CLKDIV (*(unsigned char volatile xdata *)0xfe01)
//下表为 STC8H1K08-20Pin 的参数列表
#define ID_ROMADDR ((unsigned char code *)0x1ff9)
#define VREF_ROMADDR (*(unsigned int code *)0x1ff7)
#define F32K_ROMADDR (*(unsigned int code *)0x1ff5)
#define T22M_ROMADDR (*(unsigned char code *)0x1ff4) //22.1184MHz
#define T24M_ROMADDR (*(unsigned char code *)0x1ff3) //24MHz
#define T20M_ROMADDR (*(unsigned char code *)0x1ff2) //20MHz
#define T27M_ROMADDR (*(unsigned char code *)0x1ff1) //27MHz
#define T30M_ROMADDR (*(unsigned char code *)0x1ff0) //30MHz
#define T33M_ROMADDR (*(unsigned char code *)0x1fef) //33.1776MHz
#define T35M_ROMADDR (*(unsigned char code *)0x1fee) //35MHz
#define T36M_ROMADDR (*(unsigned char code *)0x1fed) //36.864MHz
#define VRT20M_ROMADDR (*(unsigned char code *)0x1fea) //VRTRIM_20M
#define VRT35M_ROMADDR (*(unsigned char code *)0x1fe9) //VRTRIM_35M
//================== 步进电机相关变量定义 ===================
bit B_M1_RunEn; //运行允许
bit B_M1_RunEnTmp; //用于检测电机从运行到停止的事件
bit B_M1_DIR; //运行方向, 0:顺时针(正转), 1:逆时针(反转)
bit B_f1_update; //请求刷新频率值
bit B_TIMER1_12T; //定时器1时钟模式
u16 f1_period; //当前频率对应的周期
u16 f1; //当前频率
u16 f1_set; //目标频率
u16 f1_step; //加减速频率变化的步长
u16 M1_UpPulse; //加(减)速脉冲数
u16 M1_PulseCnt; //电机运行总脉冲数, 为0则连续运行
u16 M1_DownCnt; //运行到要减速输出的脉冲数
u8 M1_StepCnt; //步数计数
u8 M1_devide; //细分数 1, 2, 4, 8, 16, 32, 64
u8 M1_step; //步距, M1_step = 64 / M1_devide.
//===========================================================
sbit A1F = P1^1;
sbit A2F = P1^2;
sbit B1F = P1^5;
sbit B2F = P3^4;
sbit SLEEP = P1^4;
sbit DECAY = P1^0;
sbit up = P3^2;
sbit down = P3^3;
sbit slow_down = P3^5;
sbit test_flag = P3^6;
sbit nFAULT = P1^3;
bit B_1ms; //1ms时隙标志
unsigned int speed;
unsigned char STEP;
unsigned char LOOP;
unsigned int temp;
unsigned int flag_up;
unsigned int flag_down;
unsigned int flag_slow_down;
unsigned int flag_up_N = 1;
unsigned int flag_down_N = 1;
unsigned int flag_slow_down_N = 1;
unsigned char up_press_number;
unsigned char down_press_number;
unsigned char slow_down_press_number;
unsigned char up_no_press_number;
unsigned char down_no_press_number;
unsigned char slow_down_no_press_number;
unsigned char up_locked;
unsigned char down_locked;
unsigned char slow_down_locked;
unsigned int ms_cnt;
unsigned int P_CNT;
unsigned int p_flag = 0;
unsigned int ms_flag;
unsigned int f_pl;//频率
unsigned char pwm_duty;//占空比
unsigned char Flag_jushengState = 0;//进入举升标志位 =1进入举升 =0举升回转结束
unsigned char Flag_xiajiangState = 0;//进入下降标志位 =1进入下降 =0下降回转结束
unsigned char Flag_huanjiangState = 0;//进入缓降标志位 =1进入缓降 =0缓降回转结束
unsigned char Flag_jushengState_N = 0;//进入举升标志位 =1进入举升 =0举升回转结束
unsigned char Flag_xiajiangState_N = 0;//进入下降标志位 =1进入下降 =0下降回转结束
unsigned char Flag_huanjiangState_N = 0;//进入缓降标志位 =1进入缓降 =0缓降回转结束
unsigned char guzhang_number;
unsigned char jusheng_enable = 0;
unsigned char jusheng_back_enable = 0;
unsigned char xiajiang_enable = 0;
unsigned char xiajiang_back_enable = 0;
unsigned char huanjiang_enable = 0;
unsigned char huanjiang_back_enable = 0;
unsigned char DIR;
/************* 本地函数声明 **************/
void delay_ms(unsigned int ms);
void Delay10ms(void);
void Driver();
void fDriver();
void STEP_MOTOR_Driver(unsigned char RL);
void STEP_MOTOR_NUM(unsigned char RL, unsigned int num);
void STEP_MOTOR_LOOP(unsigned char RL,unsigned char LOOP);
void PWMA_config(void);
u8 Timer1_Config(u8 t, u32 reload); //t=0: reload值是主时钟周期数, t=1: reload值是时间(单位us)
u8 Timer0_Config(u8 t, u32 reload); //t=0: reload值是主时钟周期数, t=1: reload值是时间(单位us), 返回0正确, 返回1装载值过大错误.
void UART1_config(u32 brt, u8 timer, u8 io); // brt: 通信波特率, timer=2: 波特率使用定时器2, 其它值: 使用Timer1做波特率. io=0: 串口1切换到P3.0 P3.1, =1: 切换到P3.6 P3.7, =2: 切换到P1.6 P1.7, =3: 切换到P4.3 P4.4
void UART1_PrintString(u8 *puts);
void UART1_TxByte(u8 dat); // 串口1发送一个字节
void RX1_process(void); // 串口1处理函数
u16 GetStep(u16 f, u16 f_set); // 计算速度变化步进长度
void GetDownPulse(void); // 由M1_PulseCnt(总脉冲数) 和 M1_UpPulse(加速脉冲数) 计算开始减速的脉冲数, .
void LoadTimer1(void); // 计算更新频率的时间参数
void GetFreq1(void); // 计算加减速频率
void StopMotor1(void); // 停止运行一个电机
void RunMotor1(void); // 启动运行一个电机
void LockMotor1(void); //电机停止时减小电流锁转子
/******************** 主函数 **************************/
void main(void)
{
P_SW2 |= 0x80; //扩展寄存器(XFR)访问使能
//选择 24MHz
CLKDIV = 0x04;
IRTRIM = T24M_ROMADDR;
VRTRIM = VRT20M_ROMADDR;
IRCBAND = 0x00;
CLKDIV = 0x00;
MCLKOCR = 0x04;
ms_cnt = 0;
P_CNT = 0;
ms_flag = 0;
p_flag = 0;
P1M1 = 0x08;
P1M0 = 0xf7; //设置P1推挽输出 //P1^3设置为高阻输入
P3M1 = 0x2c; // 0 0 1 0 1 1 0 0
P3M0 = 0xd3; //设置P3推挽输出和高阻输入 1 1 0 1 0 0 1 1
DECAY = 0;
SLEEP = 1;
PWMA_config();
Timer0_Config(0, MAIN_Fosc / 1000); //t=0: reload值是主时钟周期数, t=1: reload值是时间(单位us)
Timer1_Config(1, 20000); //t=0: reload值是主时钟周期数, t=1: reload值是时间(单位us, 这里随便给个值)
EA = 1;
B_M1_RunEn = 0;
B_M1_RunEnTmp = 0;
M1_StepCnt = 0;
M1_devide = 64; //细分数 1, 2, 4, 8, 16, 32, 64
M1_step = 64 / M1_devide; //倒数关系.
while (1)
{
if(B_1ms) //1ms时隙
{
B_1ms = 0;
if(B_M1_RunEn) //加减速处理
{
GetFreq1();
if(f1 < 100)
{
B_M1_RunEn = 0; //停止
}
}
// F0 = B_M1_RunEnTmp;
// B_M1_RunEnTmp = B_M1_RunEn;
// if(F0 && !B_M1_RunEnTmp) LockMotor1(); //检测到电机停止, 则锁转子, 减小电流
if((flag_up == 0)&&(flag_down == 1)&&(flag_slow_down == 1)&&(Flag_xiajiangState == 0)&&(Flag_huanjiangState == 0)) //正转
{
Flag_jushengState=1;//进入举升标志位 =1进入举升 =0举升回转结束
if(!B_M1_RunEn) f1 = 200;
M1_PulseCnt = 12800;
B_M1_DIR = 0;
if(P_CNT < 1)
{
f1_set = 65000;
RunMotor1();
P_CNT++;
}
else if (P_CNT >= 1)
{
P_CNT = 1;
}
}
else if((flag_up == 1)&&(Flag_jushengState==1)&&(Flag_xiajiangState == 0)&&(Flag_huanjiangState == 0)) //举升松开
{
if(!B_M1_RunEn) f1 = 200;
M1_PulseCnt = 12800;
B_M1_DIR = 1;
if(P_CNT == 0)
{
Flag_jushengState=0;
}
else
{
if(P_CNT == 0)
{
Flag_jushengState=0;
}
else
{
if(P_CNT>0)
{
f1_set = 65000;
RunMotor1();
P_CNT --;
}
}
}
}//end else
else if((flag_down == 0)&&(flag_up == 1)&&(flag_slow_down == 1)&&(Flag_jushengState == 0)&&(Flag_huanjiangState == 0))
{
Flag_xiajiangState=1;//进入下降标志位 =1进入下降 =0下降回转结束
if(!B_M1_RunEn) f1 = 200;
M1_PulseCnt = 12800;
B_M1_DIR = 1;
if(P_CNT < 1)
{
f1_set = 65000;
RunMotor1();
P_CNT++;
}
else if(P_CNT >= 1)
{
P_CNT = 1;
}
}// end if(flag_down == 0) //下降
//下降松开执行程序
else if((flag_down == 1)&&(Flag_xiajiangState==1)&&(Flag_jushengState == 0)&&(Flag_huanjiangState == 0)) //下降松开
{
if(!B_M1_RunEn) f1 = 200;
M1_PulseCnt = 12800;
B_M1_DIR = 0;
if(P_CNT == 0)
{
Flag_xiajiangState=0;;
}
else
{
if(P_CNT == 0)
{
Flag_xiajiangState=0;
}
else
{
if(P_CNT>0)
{
f1_set = 65000;
RunMotor1();
P_CNT --;
}
}
}
}//end else
//缓降45°执行程序
else if((flag_slow_down == 0)&&(flag_up == 1)&&(flag_down == 1)&&(Flag_jushengState == 0)&&(Flag_xiajiangState == 0))
{
Flag_huanjiangState=1;//进入缓降45°标志位 =1进入缓降45° =0缓降45°回转结束
if(!B_M1_RunEn) f1 = 200;
M1_PulseCnt = 6400;
B_M1_DIR = 1;
if(P_CNT < 1)
{
f1_set = 65000;
RunMotor1();
P_CNT++;
}
else if(P_CNT >= 1)
{
P_CNT = 1;
}
}// end if(flag_slow_down == 0) //缓降45°
//缓降45°松开执行程序
else if((flag_slow_down == 1)&&(Flag_huanjiangState==1)&&(Flag_jushengState == 0)&&(Flag_xiajiangState == 0)) //缓降45°松开
{
if(!B_M1_RunEn) f1 = 200;
M1_PulseCnt = 6400;
B_M1_DIR = 0;
if(P_CNT == 0)
{
Flag_huanjiangState=0;
}
else
{
if(P_CNT == 0)
{
Flag_huanjiangState=0;
}
else
{
if(P_CNT>0)
{
f1_set = 65000;
RunMotor1();
P_CNT --;
}
}
}//end else
}
}
}
}
#define UpTime 100 //加(减)速时间(ms)
u16 GetStep(u16 f, u16 f_set) //计算速度变化步进长度
{
u16 i;
M1_UpPulse = (u16)((u32)(f + f_set)*UpTime / 2000); // 理论加速脉冲数
if(f_set >= f) f_set = f_set - f; //计算频率差
else f_set = f - f_set; //计算频率差
i = f_set / UpTime; // 加(减)速步进
if(i == 0) i = 1; //步进不能为0
return i; //返回加减速步进值
}
void GetDownPulse(void) // 由M1_PulseCnt(总脉冲数) 和 M1_UpPulse(加速脉冲数) 计算开始减速的脉冲数, .
{
u16 pulse;
if(M1_PulseCnt != 0) //运行总脉冲数非0才有开始减速脉冲数
{
pulse = M1_UpPulse * 2; //加减速脉冲数之和 = M1_UpPulse * 2
if(M1_PulseCnt >= pulse) pulse = M1_UpPulse; //脉冲数 >= 加减速脉冲数之和, 则减速脉冲数按理论计算值
else pulse = M1_PulseCnt / 2; //脉冲数 < 加减速脉冲数之和, 则平分脉冲
M1_DownCnt = M1_PulseCnt - pulse; // 电机开始减速需要走过的脉冲数;
}
}
void LoadTimer1(void) //计算更新频率的时间参数
{
if(f1 < 100) f1 = 90;
if(f1 < 800) //频率太低用12T模式
{
B_TIMER1_12T = 1;
f1_period = 65536UL - MAIN_Fosc/12/f1;
}
else
{
B_TIMER1_12T = 0;
f1_period = 65536UL - MAIN_Fosc/f1;
}
B_f1_update = 1; //请求刷新
}
/************************************/
void GetFreq1(void) // 计算加减速频率
{
if(f1 < f1_set) //加速
{
f1 += f1_step;
if(f1 > f1_set) f1 = f1_set; //目标频率已到
LoadTimer1();
}
else if(f1 > f1_set) //减速
{
if(f1 < f1_step) f1 = 0;
else f1 -= f1_step;
if(f1 < f1_set) f1 = f1_set; //目标频率已到
LoadTimer1();
}
}
void StopMotor1(void) //停止运行一个电机
{
f1_set = 90; //小于100Hz则停止
f1_step = GetStep(f1, f1_set);
// A1F = 0; PWMA_ENO &= ~0x02;
// A2F = 0; PWMA_ENO &= ~0x04;
// B1F = 0; PWMA_ENO &= ~0x20;
// B2F = 0; PWMA_ENO &= ~0x40;
}
void RunMotor1() //启动运行一个电机
{
// PWMA_ENO |= 0x02;
// PWMA_ENO |= 0x04;
// PWMA_ENO |= 0x20;
// PWMA_ENO |= 0x40;
f1_step = GetStep(f1, f1_set);
GetDownPulse();
if(!TR1 || !B_M1_RunEn)
{
PWMA_ENO |= 0x02;
PWMA_ENO |= 0x04;
PWMA_ENO |= 0x20;
PWMA_ENO |= 0x40;
B_M1_RunEn = 1;
TR1 = 0;
LoadTimer1();
TL1 = (u8)(f1_period % 256);
TH1 = (u8)(f1_period / 256);
TR1 = 1;
}
}
//========================================================================
// 函数: void delay_ms(u8 ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 日期: 2021-3-9
// 备注:
//========================================================================
void delay_ms(unsigned int ms)
{
unsigned int i;
do{
i = MAIN_Fosc / 10000;
while(--i); //10T per loop
}while(--ms);
}
void Delay1ms(void) //@24.000MHz
{
unsigned char data i, j;
_nop_();
i = 32;
j = 40;
do
{
while (--j);
} while (--i);
}
void Delay10ms(void) //@24.000MHz
{
unsigned char data i, j;
i = 234;
j = 115;
do
{
while (--j);
} while (--i);
}
/******************** PWM配置函数 **************************/
void PWMA_config()
{
P_SW2 |= 0x80; //SFR enable
PWMA_PSCR = 0; // 预分频寄存器, 分频 Fck_cnt = Fck_psc/(PSCR[15:0}+1), 边沿对齐PWM频率 = SYSclk/((PSCR+1)*(AAR+1)), 中央对齐PWM频率 = SYSclk/((PSCR+1)*(AAR+1)*2).
PWMA_DTR = 24; // 死区时间配置, n=0~127: DTR= n T, 0x80 ~(0x80+n), n=0~63: DTR=(64+n)*2T,
// 0xc0 ~(0xc0+n), n=0~31: DTR=(32+n)*8T, 0xE0 ~(0xE0+n), n=0~31: DTR=(32+n)*16T,
PWMA_ARR = 400; // 自动重装载寄存器, 控制PWM周期
PWMA_CCER1 = 0;
PWMA_CCER2 = 0;
PWMA_SR1 = 0;
PWMA_SR2 = 0;
PWMA_ENO = 0;
PWMA_PS = 0;
PWMA_IER = 0;
// PWMA_ISR_En = 0;
PWMA_CCMR1 = 0x68; // 通道模式配置, PWM模式1, 预装载允许
PWMA_CCR1 = 4; // 比较值, 控制占空比(高电平时钟数)
PWMA_CCER1 |= 0x05; // 开启比较输出, 高电平有效
PWMA_PS |= 0; // 选择IO, 0:选择P1.0 P1.1, 1:选择P2.0 P2.1, 2:选择P6.0 P6.1,
PWMA_ENO |= 0x02; // IO输出允许, bit7: ENO4N, bit6: ENO4P, bit5: ENO3N, bit4: ENO3P, bit3: ENO2N, bit2: ENO2P, bit1: ENO1N, bit0: ENO1P
// PWMA_IER |= 0x02; // 使能中断
PWMA_CCMR2 = 0x68; // 通道模式配置, PWM模式1, 预装载允许
PWMA_CCR2 = 0; // 比较值, 控制占空比(高电平时钟数)
PWMA_CCER1 |= 0x50; // 开启比较输出, 高电平有效
PWMA_PS |= (0<<2); // 选择IO, 0:选择P1.2 P1.3, 1:选择P2.2 P2.3, 2:选择P6.2 P6.3,
PWMA_ENO |= 0x04; // IO输出允许, bit7: ENO4N, bit6: ENO4P, bit5: ENO3N, bit4: ENO3P, bit3: ENO2N, bit2: ENO2P, bit1: ENO1N, bit0: ENO1P
// PWMA_IER |= 0x04; // 使能中断
PWMA_CCMR3 = 0x68; // 通道模式配置, PWM模式1, 预装载允许
PWMA_CCR3 = 0; // 比较值, 控制占空比(高电平时钟数)
PWMA_CCER2 |= 0x05; // 开启比较输出, 高电平有效
PWMA_PS |= (0<<4); // 选择IO, 0:选择P1.4 P1.5, 1:选择P2.4 P2.5, 2:选择P6.4 P6.5,
PWMA_ENO |= 0x20; // IO输出允许, bit7: ENO4N, bit6: ENO4P, bit5: ENO3N, bit4: ENO3P, bit3: ENO2N, bit2: ENO2P, bit1: ENO1N, bit0: ENO1P
// PWMA_IER |= 0x08; // 使能中断
PWMA_CCMR4 = 0x68; // 通道模式配置, PWM模式1, 预装载允许
PWMA_CCR4 = 0; // 比较值, 控制占空比(高电平时钟数)
PWMA_CCER2 |= 0x50; // 开启比较输出, 高电平有效
PWMA_PS |= (3<<6); // 选择IO, 0:选择P1.6 P1.7, 1:选择P2.6 P2.7, 2:选择P6.6 P6.7, 3:选择P3.3 P3.4
PWMA_ENO |= 0x40; // IO输出允许, bit7: ENO4N, bit6: ENO4P, bit5: ENO3N, bit4: ENO3P, bit3: ENO2N, bit2: ENO2P, bit1: ENO1N, bit0: ENO1P
// PWMA_IER |= 0x10; // 使能中断
PWMA_BKR = 0x80; // 主输出使能 相当于总开关
PWMA_CR1 = 0x81; // 使能计数器, 允许自动重装载寄存器缓冲, 边沿对齐模式, 向上计数, bit7=1:写自动重装载寄存器缓冲(本周期不会被打扰), =0:直接写自动重装载寄存器本(周期可能会乱掉)
PWMA_EGR = 0x01; //产生一次更新事件, 清除计数器和预分频计数器, 装载预分频寄存器的值
// PWMA_ISR_En = PWMA_IER; //设置标志允许通道1~4中断处理
}
// PWMA_PS = (0<<6)+(0<<4)+(0<<2)+0; //选择IO, 4项从高到低(从左到右)对应PWM1 PWM2 PWM3 PWM4, 0:选择P1.x, 1:选择P2.x, 2:选择P6.x,
// PWMA_PS PWM4N PWM4P PWM3N PWM3P PWM2N PWM2P PWM1N PWM1P
// 00 P1.7 P1.6 P1.5 P1.4 P1.3 P1.2 P1.1 P1.0
// 01 P2.7 P2.6 P2.5 P2.4 P2.3 P2.2 P2.1 P2.0
// 02 P6.7 P6.6 P6.5 P6.4 P6.3 P6.2 P6.1 P6.0
// 03 P3.3 P3.4 -- -- -- -- -- --
/******************** 按键函数 **************************/
void Key_scan()
{
if(up == 0) //举升按键按下
{
up_press_number+=1;
up_no_press_number = 0;
if( up_press_number >= 4)
{
flag_up = 0;
up_press_number = 0;
}
}
else //举升按键松开
{
up_press_number = 0;
up_no_press_number++;
if(up_no_press_number >= 4)
{
flag_up = 1;
up_no_press_number = 0;
}
}
if(down == 0)//下降按键按下
{
down_press_number+=1;
down_no_press_number = 0;
if( down_press_number >= 4)
{
flag_down = 0;
down_press_number = 0;
}
}
else //下降按键松开
{
down_press_number = 0;
down_no_press_number++;
if(down_no_press_number >= 4)
{
flag_down = 1;
down_no_press_number = 0;
}
}
if(slow_down == 0)//缓降按键按下
{
slow_down_press_number+=1;
slow_down_no_press_number = 0;
if( slow_down_press_number >= 4)
{
flag_slow_down = 0;
slow_down_press_number = 0;
}
}
else //缓降按键松开
{
slow_down_press_number = 0;
slow_down_no_press_number++;
if(slow_down_no_press_number >= 4)
{
flag_slow_down = 1;
slow_down_no_press_number = 0;
}
}
}
//========================================================================
// 函数: u8 Timer1_Config(u8 t, u32 reload)
// 描述: timer1初始化函数.
// 参数: t: 重装值类型, 0表示重装的是系统时钟数, 其余值表示重装的是时间(us).
// reload: 重装值.
// 返回: 0: 初始化正确, 1: 重装值过大, 初始化错误.
// 版本: V1.0, 2018-3-5
//========================================================================
u8 Timer1_Config(u8 t, u32 reload) //t=0: reload值是主时钟周期数, t=1: reload值是时间(单位us)
{
TR1 = 0; //停止计数
if(t != 0) reload = (u32)(((float)MAIN_Fosc * (float)reload)/1000000UL); //重装的是时间(us), 计算所需要的系统时钟数.
if(reload >= (65536UL * 12)) return 1; //值过大, 返回错误
if(reload < 65536UL) AUXR |= 0x40; //1T mode
else
{
AUXR &= ~0x40; //12T mode
reload = reload / 12;
}
reload = 65536UL - reload;
TH1 = (u8)(reload >> 8);
TL1 = (u8)(reload);
ET1 = 1; //允许中断
PT1 = 1; //高优先级中断
TMOD = (TMOD & ~0x30) | (0 << 4); //工作模式, 0: 16位自动重装, 1: 16位定时/计数, 2: 8位自动重装
TR1 = 1; //开始运行
return 0;
}
//========================================================================
// 函数: void timer1_ISR (void) interrupt TIMER1_VECTOR
// 描述: timer1中断函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2016-5-12
//========================================================================
void timer1_ISR (void) interrupt TIMER1_VECTOR
{
u8 area; //区间0~3
u8 pwm_A; //A相spwm
u8 pwm_B; //B相spwm
if(B_M1_RunEn) //电机允许运转
{
pwm_A = M1_StepCnt * M1_step; // A相步数计数, M1_step为细分对应的步距
area = pwm_A / 64; // 区间0~3
pwm_B = pwm_A + 64; // B相步数计数
pwm_A = T_SIN[pwm_A]; // A相sPWM值
pwm_B = T_SIN[pwm_B]; // A相sPWM值
if(area == 0) //0区间
{
PWMA_CCR1L = pwm_A; // A+ = sin(A)
PWMA_CCR2L = 0; // A- = 0
PWMA_CCR3L = pwm_B; // B+ = cos(A) = sin(A+64)
PWMA_CCR4L = 0; // B- = 0
}
else if(area == 1) //1区间
{
PWMA_CCR1L = pwm_A; // A+ = sin(A)
PWMA_CCR2L = 0; // A- = 0
PWMA_CCR3L = 0; // B+ = 0
PWMA_CCR4L = pwm_B; // B- = cos(A) = sin(A+64)
}
else if(area == 2) //2区间
{
PWMA_CCR1L = 0; // A+ = sin(A)
PWMA_CCR2L = pwm_A; // A- = 0
PWMA_CCR3L = 0; // B+ = 0
PWMA_CCR4L = pwm_B; // B- = cos(A) = sin(A+64)
}
else //3区间
{
PWMA_CCR1L = 0; // A+ = sin(A)
PWMA_CCR2L = pwm_A; // A- = 0
PWMA_CCR3L = pwm_B; // B+ = cos(A) = sin(A+64)
PWMA_CCR4L = 0; // B- = 0
}
if(B_M1_DIR == 0) M1_StepCnt++; //正转, 下一步, M1_step为细分对应的步距
else M1_StepCnt--; //反转, 下一步, M1_step为细分对应的步距
if(M1_PulseCnt != 0) //总脉冲数非0减1
{
if(--M1_PulseCnt == 0) B_M1_RunEn = 0;
}
if(M1_DownCnt != 0) //减速时刻脉冲数减1
{
if(--M1_DownCnt == 0) f1_set = 200;
}
}
if(B_f1_update) //刷新频率数据
{
B_f1_update = 0;
TR1 = 0;
TL1 = (u8)(f1_period % 256);
TH1 = (u8)(f1_period / 256);
if(B_TIMER1_12T) AUXR &= ~0x40; //12T mode
else AUXR |= 0x40; //1T mode
TR1 = 1;
}
}
void LockMotor1(void) //电机停止时减小电流锁转子
{
u8 area; //区间0~3
u8 pwm_A; //A相spwm
u8 pwm_B; //B相spwm
pwm_A = M1_StepCnt * M1_step; // A相步数计数
area = pwm_A / 64; // 区间0~3
pwm_B = pwm_A + 64; // B相步数计数
pwm_A = T_SIN[pwm_A]/2; // A相sPWM值
pwm_B = T_SIN[pwm_B]/2; // A相sPWM值
if(area == 0) //0区间
{
PWMA_CCR1L = pwm_A; // A+ = sin(A)
PWMA_CCR2L = 0; // A- = 0
PWMA_CCR3L = pwm_B; // B+ = cos(A) = sin(A+64)
PWMA_CCR4L = 0; // B- = 0
}
else if(area == 1) //1区间
{
PWMA_CCR1L = pwm_A; // A+ = sin(A)
PWMA_CCR2L = 0; // A- = 0
PWMA_CCR3L = 0; // B+ = 0
PWMA_CCR4L = pwm_B; // B- = cos(A) = sin(A+64)
}
else if(area == 2) //2区间
{
PWMA_CCR1L = 0; // A+ = sin(A)
PWMA_CCR2L = pwm_A; // A- = 0
PWMA_CCR3L = 0; // B+ = 0
PWMA_CCR4L = pwm_B; // B- = cos(A) = sin(A+64)
}
else //3区间
{
PWMA_CCR1L = 0; // A+ = sin(A)
PWMA_CCR2L = pwm_A; // A- = 0
PWMA_CCR3L = pwm_B; // B+ = cos(A) = sin(A+64)
PWMA_CCR4L = 0; // B- = 0
}
}
u8 Timer0_Config(u8 t, u32 reload) //t=0: reload值是主时钟周期数, t=1: reload值是时间(单位us)
{
TR0 = 0; //停止计数
if(t != 0) reload = (u32)(((float)MAIN_Fosc * (float)reload)/1000000UL); //重装的是时间(us), 计算所需要的系统时钟数.
if(reload >= (65536UL * 12)) return 1; //值过大, 返回错误
if(reload < 65536UL) AUXR |= 0x80; //1T mode
else
{
AUXR &= ~0x80; //12T mode
reload = reload / 12;
}
reload = 65536UL - reload;
TH0 = (u8)(reload >> 8);
TL0 = (u8)(reload);
ET0 = 1; //允许中断
TMOD = (TMOD & ~0x03) | 0; //工作模式, 0: 16位自动重装, 1: 16位定时/计数, 2: 8位自动重装, 3: 16位自动重装, 不可屏蔽中断
TR0 = 1; //开始运行
return 0;
}
//========================================================================
// 函数: void timer0_ISR(void) interrupt TIMER0_VECTOR
// 描述: timer0中断函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2018-12-20
//========================================================================
void timer0_ISR(void) interrupt TIMER0_VECTOR
{
B_1ms = 1; //标志1ms时隙
ms_flag++;
Key_scan();
} |
|