📄 tri_emc.c
字号:
#pragma model(kc)
#include <kc_sfrs.h>
#include <kc_funcs.h>
#define ENABLE_HSI1_INPUT 0x04 //IOC0
#define ENABLE_TIMER1_OVERFLOW_INT 0x04 //IOC1
#define ENABLE_ACH7_INTERRUPT 0x02 //IOC1 EXTINT P0.7
#define DOU_PWM_PERIOD 0x04 //IOC2
#define ENABLE_PWM1 0x04 //IOC3(HWIN1)
#define ENABLE_TIMEROVF_INTERRUPT 0x01 //INT_MASK (timer)
#define ENABLE_HSIDATA_INTERRUPT 0x04 //INT_MASK (hsi)
#define ENABLE_EXT_INT1 0x20 //INT_MASK1 P2.2 (can)
#define CAN_BASEADDR 0x8000
#define LOCK_BASEADDR 0x9000
#define DIR_BASEADDR 0xA000
#define PWM_EN_BASEADDR 0xB000
#define F1_EN_BASEADDR 0xC000
#define SW_BASEADDR 0xD000
#define PWM_VALUE1 20 //导致模块保护的PWM差值
#define PWM_VALUE2 10 //加载的PWM差值,此值要小于上值
#define PWM_VALUE3 20//换向的最大PWM值,应大于步进初始值
#define TIME_CONST1 3 //发送信息
#define TIME_CONST2 50 //保护时PWM增加时间
#define CAN_ID1 0x22
#define CAN_ID2 0x2F
#define TMS_INFO_ID 0xF1
unsigned char can_mode[32];
#pragma locate(can_mode=CAN_BASEADDR)
unsigned char lock;
#pragma locate(lock=LOCK_BASEADDR)
unsigned char motor_switch;
#pragma locate(motor_switch=DIR_BASEADDR)
unsigned char pwm_en;
#pragma locate(pwm_en=PWM_EN_BASEADDR)
unsigned char f1_status;
#pragma locate(f1_status=F1_EN_BASEADDR)
unsigned char sw_status;
#pragma locate(sw_status=SW_BASEADDR)
unsigned char send_data_buffer[8]={0x01,0x34,0x56,0x78,0x90,0xAB,0xCD,0xEF}; //发送数据缓冲,8个字节
unsigned char send_data_length; //发送数据的长度,半个字节为单位
unsigned char received_data_buffer[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //接收数据缓冲
unsigned char received_data_length=0; //接收数据长度
unsigned char wsr_image;
unsigned char motor_pwm=0;
unsigned char motor_direction=0x00;
unsigned char function;
unsigned int motor_pulse=0;
unsigned int motor_rotate_speed=0;
unsigned char time_ref=0;
void wait_ms(unsigned int x )
{
unsigned int i,j;
for(i = x; i > 0; i--)
for(j = 187; j > 0; j--);
}
void set_motor_pwm1(unsigned char pwm_value)
{
wsr_image=wsr;
disable();
wsr=1;
pwm1_control=pwm_value;
wsr=wsr_image;
enable();
motor_pwm = pwm_value;
}
void set_motor_pwm(unsigned char pwm_value)
{
unsigned char m;
if (pwm_value > motor_pwm)
{
while((pwm_value - motor_pwm) > PWM_VALUE1)
{
set_motor_pwm1(motor_pwm + PWM_VALUE2);
wait_ms(TIME_CONST2);
}
set_motor_pwm1(pwm_value);
}
if(pwm_value < motor_pwm)
{
if((motor_pwm - pwm_value ) > PWM_VALUE1)
{
m=motor_pwm;
set_motor_pwm1(pwm_value);
wait_ms(m*3);
}
set_motor_pwm1(pwm_value);
}
set_motor_pwm1(pwm_value);
}
//===============================================
// 控制电机方向
//===============================================
void set_motor_direction(unsigned char direction)
{
unsigned char m;
if(direction!= motor_direction)
{
if (motor_pwm > PWM_VALUE3)
{
m=motor_pwm; //转向保护
set_motor_pwm1(0); //直接调用set_motor_pwm1,减少延时
wait_ms(m*4);
motor_switch = direction;
set_motor_pwm(m);
}
else
motor_switch = direction;
//更新方向信息
motor_direction=direction;
}
}
//===============================================
// 使用面板控制
//===============================================
void control_by_panel()
{
unsigned char ad_temp;
//控制电机方向
if (sw_status == 0x00)
set_motor_direction(0x00);
else set_motor_direction(0x80);
//控制电机转速
ad_command=0x0A;
zero_reg=zero_reg+zero_reg;
zero_reg=zero_reg+zero_reg;
while(ad_result_lo & 0x08);
ad_temp=ad_result_hi;
set_motor_pwm(ad_temp);
}
void init_can()
{
do
{
can_mode[0]=0x01;
}
while (can_mode[0] & 0x01 !=0x01); //复位sja1000
can_mode[4]=0x09; //enable receive int 数据溢出中断使能
can_mode[2]=0x00; //status reg
can_mode[31]=0xc8; //clock div
can_mode[30]=0x00; //RX缓冲区起始地址
can_mode[14]=0x00; //RX error count
can_mode[15]=0x00; //Tx error count
can_mode[16]=0x22; //验收代码 00100010001
can_mode[17]=0x2F;
can_mode[18]=0xFF;
can_mode[19]=0xFF;
can_mode[20]=0xFF; //验收屏蔽 0时比较
can_mode[21]=0xFF;
can_mode[22]=0xFF;
can_mode[23]=0xFF;
can_mode[6]=0x40; //总线时序
can_mode[7]=0x6F;
can_mode[8]=0x1A; //输出控制
do
{
can_mode[0]=0x04;
}
while(can_mode[0]!=0x04);
can_mode[4]=0x01; //输出中断使能
}
//===============================================
// CAN处理
//===============================================
void can_process()
{
unsigned char state;
unsigned char direction;
unsigned char pwm;
if (received_data_buffer[0]==0xC1)
function=received_data_buffer[1];
if (received_data_buffer[0]==0xC2)
{
state=received_data_buffer[1];
pwm=received_data_buffer[2];
if ((state & 0x10) ==0x10)
direction=0x80;
else
direction=0x00;
if ((state & 0x40)==0x40) set_motor_direction(direction);
if ((state & 0x80)==0x80) set_motor_pwm(pwm);
}
}
//===============================================
// can发送程序
//===============================================
void can_send()
{
unsigned char i;
//等待发送缓冲器释放
while(can_mode[2]&0x04!=0x04);
//填充数据
can_mode[16]=send_data_length; //数据个数
can_mode[17]=CAN_ID1;
can_mode[18]=CAN_ID2;
for(i=0;i<send_data_length;i++)
{
can_mode[19+i]=send_data_buffer[i];
}
//发送数据
can_mode[1]=0x01;
}
//===============================================
//发送速度信息
//===============================================
void send_motor_info()
{
unsigned char dir=0;
unsigned int *p;
send_data_length=8;
send_data_buffer[0]=TMS_INFO_ID;
if (motor_direction==0x80) dir = 0x10;
send_data_buffer[1]=dir;
p=(unsigned int *)&send_data_buffer[2];
*p= motor_rotate_speed;
can_send();
}
//===============================================
// 定时中断
//===============================================
#pragma interrupt(TIMER_isr=0)
void TIMER_isr(void)
{
//22.8881* 脉冲数
disable();
//////////////////////////
//测速
/////////////////////////
motor_rotate_speed=23 * motor_pulse;
motor_pulse=0;
/////////////////////////
//发送电机运行信息
/////////////////////////
if (time_ref==TIME_CONST1)
{
time_ref=0;
send_motor_info();
}
else
time_ref++;
enable();
}
//===============================================
// 高速输入中断
//===============================================
#pragma interrupt(HSI_isr=2) //中断矢量地址2004
void HSI_isr(void)
{
//22.8881* 脉冲数
disable();
zero_reg=hsi_time;
motor_pulse++;
enable();
}
//===============================================
// CAN中断
//===============================================
#pragma interrupt(CanInt_isr=29) //中断矢量地址203A
void CanInt_isr(void)
{
unsigned char i;
disable();
if ((can_mode[3]& 0x01) ==0x01) //判断是否为接收中断
{
while((can_mode[2]& 0x01)==0x01) //判断接收缓冲器是否有报文
{
received_data_length=can_mode[16];
for(i=0;i<received_data_length;i++)
{
received_data_buffer[i]=can_mode[19+i];
}
can_process();
can_mode[1]=0x04;
}
}
enable();
}
void main()
{
disable();
//清HSI
while((ios1 & 0x80) ==0x80)
zero_reg=hsi_time;
hsi_mode=0xFF;
hsi_mode=0xFF; //hsi输入全部是每次跳变(正和负)
ioc0=ENABLE_HSI1_INPUT;
ioc1=ENABLE_TIMER1_OVERFLOW_INT|ENABLE_ACH7_INTERRUPT;
ioc2=DOU_PWM_PERIOD;
wsr_image=wsr;
wsr=1;
ioc3=ENABLE_PWM1;
wsr=wsr_image;
//设置中断
int_mask=ENABLE_HSIDATA_INTERRUPT|ENABLE_TIMEROVF_INTERRUPT ;
int_mask1=ENABLE_EXT_INT1;
int_pend=0x00;
int_pend1=0x00;
lock=0x80; //解除锁定
pwm_en=0x00; //PWM使能
f1_status=0x00; //F2灭
function=0xF1;
set_motor_pwm(0x00);
init_can();
enable();
while(1)
{
if (function==0xF1)
control_by_panel();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -