📄 brush2.c
字号:
/**********************************************
有刷电机控制:WZKD3615G
功能:助力
巡航
过流保护
欠压保护
面板显示(去掉)
使用芯片:EM78P259
PWM频率:10KHz
刹车:高电平
程序员:蒋科
******************************************************/
#include "EM78P259.h"
#define AD_CH_V 0x01 //AD采样通道
#define AD_CH_S 0x02
#define AD_CH_C 0x00
#define AD_CH_SS 0x03
#define PWM_HZ 0xc3 //10khz
#define S_1V6 0x4f
#define S_1V8 0x5c
#define S_2V4 0x7a
#define S_3V8 0xc4
#define S_MAX 0x60//0-0X75
#define CUR_LMT 0x3a /*正常状态限流15A*/
#define S_PORT R62//助力口
#define B_PORT R61//刹车口
#define K_PORT R63//巡航口
#define L_PORT R53//限速口
#define tcc_cyc 0x0c
#define tcc_type tcc_cyc //TCC设置值
//static unsigned char hc164_code; //要写入HC164的值
static unsigned char v_data; //电压值
static unsigned char c_data; //电流值
static unsigned char s_data; //速度值
static unsigned char keep_data;//巡航时间
//static unsigned char ss_data; //限速值
static unsigned char flash_data;
static unsigned char time_sec;//计数时间的秒
static unsigned char time_msec;////计数时间的毫秒
static unsigned char time_flash_data;
//static unsigned char pwm_data;
static unsigned char pwm_old_data;
static unsigned char pwm_set_data;
static unsigned char test_time_data;//采样时间
static unsigned char v_time_data;//电压采样时间
static unsigned char over_no_time;//过流撤消时间
static unsigned char over_time;//过流时间
static unsigned char low_no_time;//欠压撤消次数
static unsigned char low_time;//欠压次数
static unsigned short h_time;//高电平时间
static unsigned short l_time;//低电平时间
static unsigned char add_change;
static unsigned char sensor_data;
static bit low_flag;//欠压标志
static bit over_flag;//过流标志
static bit find_flag;//自检标志
static bit brake_flag;//刹车标志
static bit time_flag;//中断益处标志
static bit flash_flag;//闪烁标志
static bit pwm_no_flag;//无PWM标志
//static bit hc164_dis_flag;//HC164显示标志
static bit v_time_flag;//采样电压时间到
static bit s_time_flag;//采样速度时间到
static bit c_time_flag;//采样电流时间到
static bit error_flag;//电动车状态出错标志
static bit same_flag;//转把值相同标志
static bit keep_flag;//巡航标志
static bit s_over_flag;//巡航以后转把复位后又转起
static bit s_return_flag;//巡航后转把复位标志
static bit sensor_flag;//助力标志
static bit ele_flag;//电动标志
static bit limit_flag;//限速标志
static bit h_flag;//高电平计时标志
static bit l_flag;//低电平计时标志
static bit sensor_start_flag;//助力
static bit sensor_start_flag1;
static bit k_port_flag;//巡航口释放标志
void nop1(void)//延时
{
unsigned char delay1;
for(delay1=0;delay1<100;delay1++)
{
}
}
unsigned char ad_sample(unsigned char ad_ch)//AD采样
{
unsigned char ad_data,ad_loop;
unsigned char ad_add_data;
ADCON=ad_ch|0x08;//设置采样通道
while(ADRUN==1);//等待AD空闲
nop1();
ADRUN=1;
while(ADRUN==1)//采样开始
{
}
ad_add_data=ADDATA;
for(ad_loop=0;ad_loop<8;ad_loop++)//采样10次,取平均
{
ADRUN=1;
while(ADRUN==1)
{
}
ad_add_data=ad_add_data/2+ADDATA/2;
}
ad_data=ad_add_data;
return(ad_data);//返回采样值
}
void f_brake(void) //刹车查询
{
if(B_PORT==0)
{
nop1();
if(B_PORT==0) //去抖动
{
brake_flag=1;//置刹车标志
}
}
}
void f_keep(void) //巡航查询
{
if(K_PORT==0)
{
nop1();
if(K_PORT==0) //确认有巡航按扭按下
{
if(k_port_flag==1)//巡航按扭释放
{
k_port_flag=0;
if(pwm_no_flag==0)
{
keep_flag=!keep_flag;//改变巡航状态
}
}
}
}
else
{
k_port_flag=1;//巡航按扭释放
}
}
void f_limit(void) //限速查询
{
limit_flag=0;
if(L_PORT==0)
{
nop1();
if(L_PORT==0)
{
limit_flag=1;
}
}
}
void set_pwm(void)//PWM设置
{
if(pwm_set_data==0)
{
IOCA0=0x88;
R67=1;
pwm_no_flag=1;
}
else
{
IOCA0=0x89;
LTR=pwm_set_data;//低时间
HTR=PWM_HZ-pwm_set_data;//高时间
pwm_no_flag=0;
}
}
void timer(void)
{
if(time_flag==1)//TCCC益处中断后的处理
{
if(h_flag==1)
{
h_time++;//助力为高时间
}
if(l_flag==1)
{
l_time++;//助力为低时间
}
if((h_time+l_time)>=1000)//总时间超时
{
h_time=0;
l_time=0;
add_change=0;
h_flag=0;
l_flag=0;
sensor_data=0;
}
time_flag=0;
test_time_data++;
if(test_time_data>=5)
{
test_time_data=0;
s_time_flag=1;//速度采样时间到
v_time_data++;
if(v_time_data>12)//电压采样时间到
{
v_time_data=0;
v_time_flag=1;//电压采样时间到
}
}
else
{
c_time_flag=1;//采样电流标志
}
}
}
void find(void) //飞车保护
{
find_flag=1;
while(find_flag==1)
{
s_data=ad_sample(AD_CH_S);
if(s_data<=S_1V6)
{
find_flag=0;
}
}
}
void inisys(void)
{
//I/O口初始化
P6CR=0x0e;
P5CR=0x3f;
PORT6=0x80;
PORT5=0;
PHCR=0;
//AD初始化
ADCISR=0x07;
//PWM初始化
IOC90=0xc4;//TCCB&TCCC
IOCA0=0x88;
R67=0;
// LTR=PWM_HZ;
// HTR=0;//频率10KHZ
ICOB1=0x88;
TCCCC=0x00;
//tcca
IOC80=0x04;
//tccb
// TCCBH=0xfe;//5ms
// TCCBL=0xdf;
//中断使能和初始化
ISR=0;
IOCF0=0x10;
}
void iniuse(void)
{
find_flag=0;
over_flag=0;
time_flash_data=0xff;
pwm_set_data=0;
brake_flag=0;
keep_data=0;
over_time=0;
over_no_time=0;
low_time=0;
low_no_time=0;
sensor_flag=0;
ele_flag=0;
keep_flag=0;
limit_flag=0;
h_time=0;
l_time=0;
add_change=0;
h_flag=0;
l_flag=0;
}
void pwm_do(void)//计算PWM
{
unsigned char pwm_data;
if(s_data>0x4f)//转把大于开启电压
{
s_data=s_data-0x4f;
// s_over_flag=0;
// if(s_return_flag==1)//两次转动转把后,巡航撤消
// {
// s_over_flag=1;
// }
}
else
{
ele_flag=0;
s_data=0;
// if(keep_flag==1)
// {
// s_return_flag=1;
// if(s_over_flag==1)
// {
// s_return_flag=0;
// keep_flag=0;
// keep_data=0;
// }
// }
}
if(s_data>S_MAX)//转把大于最大值
{
if(limit_flag==1)
{
s_data=S_MAX;//有限速时限制速度
}
else
{
if(s_data>0x75)
{
s_data=0x75;//没有限速
}
}
}
pwm_data=(s_data/3)*5;//归一化PWM
same_flag=0;
if(keep_flag==1)//如果有巡航
{
pwm_data=pwm_old_data;//保持原由速度
}
// if(pwm_data==pwm_old_data)
// {
// if(s_data>0x0d)
// {
// same_flag=1;
// keep_data=0;
// }
// }
pwm_old_data=pwm_data;
if(sensor_data>pwm_data)
{
pwm_data=sensor_data;//当助力大于转把,使用助力
// sensor_data=0;
}
if(pwm_data>pwm_set_data)//速度增加
{
if(pwm_data>=pwm_set_data+4)
{
pwm_set_data=pwm_set_data+4;//增量4
}
else
{
pwm_set_data=pwm_set_data+1;//增量1
}
}
else
{
pwm_set_data=pwm_data;//速度减小
}
}
void lowpower_test()//欠压测试
{
if(v_data<0xa6)//低于32.5为欠压
{
low_time++;
low_no_time=0;
if(low_time>10)
{
low_flag=1;
}
}
// if(low_flag==1)//34.5为返回值
// {
if(v_data>0xb0)
{
low_no_time++;
low_time=0;
if(low_no_time>10)
{
low_flag=0;
}
}
// }
}
void over_test(void)//过流测试
{
if(c_data>=CUR_LMT)
{
over_time++;
over_no_time=0;
if(over_time>10)
{
over_time=0;
over_flag=1;
}
}
else
{
over_time=0;
over_no_time++;
if(over_no_time>10)
{
over_no_time=0;
over_flag=0;
}
}
}
void sporttest(void)//助力口判断
{
if(S_PORT==1)//助力口为高电平
{
if((sensor_start_flag==1)||(l_flag==1))
{
h_flag=1;
sensor_start_flag1=1;
sensor_start_flag=0;
}
l_flag=0;
if(add_change>=5)
{
add_change=0;
if(l_time>=2*h_time)
{
h_time=h_time+l_time;
if(h_time>=1000)
{
h_time=1000;
}
h_time=h_time/6;
if(h_time>150)
{
h_time=150;
}
sensor_data=150-h_time;//归一化霍耳值
h_flag=0;
sensor_start_flag1=0;
h_time=0;
l_time=0;
}
else
{
h_flag=0;
sensor_start_flag1=0;
h_time=0;
l_time=0;
sensor_data=0;
}
}
}
else
{
l_flag=1;
if(h_flag==1)
{
h_flag=0;
add_change++;
}
else
{
if(sensor_start_flag1==0)
{
sensor_start_flag=1;
}
}
}
}
void brake_do(void)//刹车处理
{
pwm_set_data=0;
pwm_old_data=0;
h_time=0;
l_time=0;
add_change=0;
h_flag=0;
l_flag=0;
sensor_data=0;
same_flag=0;
set_pwm(); //清PWM
while(B_PORT==0) //等待刹车结束
{
nop1();
while(B_PORT==0)
{
nop1();
}
}
brake_flag=0;
keep_flag=0;
}
void main()
{
_asm
{
mov a,0//@tcc_type
contw
}
inisys();//系统初始化
iniuse();//用户寄存器初始化
_asm
{
eni
}
f_brake();//采样刹车
v_data=ad_sample(AD_CH_V);//采样电压
lowpower_test();//欠压测试
s_data=ad_sample(AD_CH_S);//采样转把
if((s_data>S_1V6)||(brake_flag==1))//转把没有复位或有刹车后进入自检
{
find_flag=1;
find();//自检
}
while(1)
{
f_limit();
if(c_time_flag==1)
{
c_time_flag=0;
c_data=ad_sample(AD_CH_C);//电流采样
over_test();//过流测试
}
f_brake();
if(brake_flag==1)
{
brake_do();//刹车处理
}
if(s_time_flag==1)
{
s_time_flag=0;
s_data=ad_sample(AD_CH_S); //采样转把值
if(over_flag==1)
{
keep_flag=0;
if(pwm_set_data==0)
{
pwm_set_data=0;
}
else
{
pwm_set_data--;
}
}
else
{
pwm_do();//PWM计算
}
set_pwm();
}
if(v_time_flag==1)
{
v_time_flag=0;
v_data=ad_sample(AD_CH_V);//采样电压
lowpower_test();//欠压测试
}
if(low_flag==1)
{
pwm_set_data=0;
pwm_old_data=0;
set_pwm(); //清PWM
while(low_flag==1)
{
v_data=ad_sample(AD_CH_V);
if(v_data>0xb0)
{
low_flag=0;
}
}
brake_flag=0;
keep_flag=0;
}
f_keep();
sporttest();//助力口判断
timer();
}
}
//==================================
void _intcall tccb_l(void) @ 0x1B:low_int 8
{
}
void _intcall tccb(void) @ int 8
{
//backup ACC,R3,R4
_asm
{
//save A --> 0x1F ; R3 --> 0x3E (ram bank 1); R4 --> 0x3F (ram bank 1)
//保存数据
MOV 0X1F,A ;backup A to 0x1F
SWAPA 0X04 ;backup R4 to 0x3F at bank 3
BS 0X04,6 ;switch bank 1
// BS 0X04,7
MOV 0X3F,A ;backup R4 to 0x3F at bank 3
SWAPA 0X03
MOV 0X3E,A ;backup R3 to 0x3E at bank 3
}
TCCBH=0x63;//10ms
TCCBL=0xbf;
time_flag=1;
// R65=!R65;
ISR=0;
_asm
{//恢复现场
BS 0X04,6 ;switch to ram bank 1
// BS 0X04,7
SWAPA 0X3E ;restore R3
MOV 0X03,A
SWAPA 0X3F ;restore R4
MOV 0X04,A
SWAP 0X1F ;restore A
SWAPA 0X1F
RETI
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -