⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 brush2.c

📁 使用低成本单片机义隆EM78P259的有刷电机控制器程序
💻 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 + -