打印

W79E833 电动自行车源程序

[复制链接]
2406|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
millertson|  楼主 | 2008-2-25 18:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
tyw| | 2008-2-25 18:16 | 只看该作者

好!帮lz贴一下

/*******************************************************************************
华邦W79E833电动自行车方案程序
 作者:邹工   13761016264  zou_zhi_chao@hotmail.com
注:程序在不同的电机上表现有一些差异,有任何问题可以与我联系;
若需要头文件,原理图、PCB也可以和我联系。 
******************************************************************************/
#include "intrins.h"
#include "E_BIKE_83.H"
#include"W79E834.h"
#define Current_Max 0x700
/*****************************************************************************
* 主函数
******************************************************************************/
void main(void)
{
 Init_IO(); // 初始化端口
 Init();   // 初始化
 H_Sample(); // 霍尔信号采样
 EA=1;
 while(1)
 { 
  PWM_Setting(); 
  if(Speed_REQ)
  {PWM_ADJ();}
  EA=0;
  if(MotorStop_CNT > 5)
  { H_Sample();
   Phase_Change();
   MotorStop_CNT = 0;
  }
  EA=1; 
 }
}
/******************************************************************************
* I/O端口初始化
******************************************************************************/
void Init_IO(void)
{
 P0M1=0xFC;//------P0端口设置------//
 P0M2=0x03;
 P0=0xFF;
 P1M1=0x1C;//------P1端口设置------//
 P1M2=0xC3;
 P1=0xFF;
 P2M1=0x01; //------P2端口设置------//
 P2M2=0x5E;
 P2=0xFF;
}
/******************************************************************************
* 初始化程序
******************************************************************************/
void Init(void)
{
 unsigned char i; 
 PWMPH=0X03;//------PWM设置------//
 PWMPL=0X55;
 PWM0H=0X00;
 PWM0L=0X00;
 PWM1H=0X00;
 PWM1L=0X00; 
 PWM2H=0X00;
 PWM2L=0X00; 
 PWMCON1=0XC7; // 打开PWM电路,三个PWM口反相输出
 PWMCON3=0xF0;
 P21 = 0;
 UT=0;VT=0;WT=0;
 UB=1;VB=1;WB=1; // 电机停转
 while(P14==0)//-----相位检测-------//
 {
  H_Sample(); 
  Phase_Detect();    
 }
 for (i=0;i<16;i++)//------变量初始化------//
  {Current_Buffer=0;}
 for (i=0;i<20;i++)
  {Speed_Buffer=0;}
 for (i=0;i<16;i++)
  {Voltage_Buffer=0;}
 Current_P=0;
 Speed_P=0;
 Voltage_P=0;;
 Speed_SUM=0;
 Current_SUM=0;
 Voltage_SUM=0;
 H_State=0;
 Old_State=0;
 PWM_Duty=0;
 Count_Current=0;
 Count_Speed=0;
 Count_Voltage=0;
 Speed_REQ=0;
 Current_REQ=0;
 Voltage_REQ=0;
 ADC_Ready=0; 
 PWM_Duty_min=1; 
 Motor_Speed = 0x50;
 Speed_Low=0x0500;
 TH0=0x7A;TL0=0x7A; // 设定定时器的初值   
 TMOD=0x22; // T0选为定时器(八位)模式2,TL0自动加载TH0中的初值
 CKCON&=0X00; // 定时器选择为1/12系统时钟
 ET0=1; // 允许定时器中断
 TR0=1; // 启动定时器
 AUXR1|=0x04; // 打开ADC电路
 EADC=1; // 允许ADC中断
 ADCCON &= 0xE7;
 CKCON=0x60; // Settings of Timer2 capture mode 
 CAPCON0=0xA8;
 CAPCON1=0x00;
 T2MOD=0xF0;
 IE1 |= 0x80; // enable capture mode interrupt 
 IP1H = 0x80;
 RCAP2L = 0x00;             //自动重装载低位
 RCAP2H = 0x00;             //自动重装载高位
 IE1 |= 0x40;
 T2CON |= 0x04;//enable timer2
}
/******************************************************************************
* ADC中断处理程序
******************************************************************************/
void ADC_ISR(void) interrupt 11
{
 ADC_Ready=1;
 ADCCON &= 0xE7;
 if(Current_REQ) // 电流采样
  { 
   Current_REQ=0;
   if(Current_SUM>Current_Buffer[Current_P])
    Current_SUM -= Current_Buffer[Current_P];
   Current_Buffer[Current_P]=ADCH;
   Current_SUM += ADCH;
   Current_P++;
   if(Current_P>15)
   Current_P=0;
  }
 if(Speed_REQ) // 转把电压采样
 {
  Speed_REQ=0;
  if(Speed_SUM>Speed_Buffer[Speed_P])
   Speed_SUM-=Speed_Buffer[Speed_P];
  Speed_Buffer[Speed_P]=ADCH;
  Speed_SUM+=ADCH;
  Speed_P++;
  if(Speed_P == 14)
   Speed_P=0;
 }
 if(Voltage_REQ) // 电源电压采样
 { 
  Voltage_REQ=0;
  if(Voltage_SUM>Voltage_Buffer[Voltage_P])
   Voltage_SUM -= Voltage_Buffer[Voltage_P];
  Voltage_Buffer[Voltage_P]=ADCH;
  Voltage_SUM += ADCH;
  Voltage_P++;
  if(Voltage_P>15)
   Voltage_P=0;
 }
}
/******************************************************************************
* 定时器0中断处理函数
******************************************************************************/
// ========== Interrupt Cycle: 100uS ===================
void T0M1_ISR(void) interrupt 1
{
 ADC_Ready=0;
 Current_REQ=1;
 Speed_REQ=0;
 Voltage_REQ=0;
 ADCCON=3;
 Count_Speed++;
if(Count_Speed>5)//17
 {
  ADCCON=1;
  Current_REQ=0;
  Speed_REQ=1;
  Count_Speed=0;
  Count_Voltage++;
  Current_Protect();
  if( Count_Voltage>20)//50
  {
   ADCCON=2;
   Speed_REQ=0;Voltage_REQ=1;
   Count_Voltage=0; 
  } 
 }
 ADCCON&=0xef;ADCCON|=0x08;
 EADC=1;
  MotorStop_CNT++;
}
/******************************************************************************
* 定时器2捕获模式中断处理函数
******************************************************************************/
void Timer2_ISR() interrupt 13 using 2
{
 EA = 0;
 Motor_Speed = TH2;
 TH2 = 0;
 TL2 = 0;
 MotorStop_CNT = 0;
 H_Sample(); // 霍尔信号采集
 Phase_Change(); // 相位变换
 EA = 1;
}
/******************************************************************************
* 定时器2溢出中断处理函数
******************************************************************************/
void T2_ISR() interrupt 8
{
 TF2 = 0;
 Motor_Speed = 0x50;
 Block_Detect(); // 堵转保护
}
/******************************************************************************
* 定时器3中断处理函数,采取捕获模式
******************************************************************************/
void H_Sample(void)
{
 CAPCON1 &= 0xF8;
 H1=P12;
 H2=P20;
 H3=P07;
 H_State=H1<<2;
 H_State+=H2<<1;
 H_State+=H3;
}
/******************************************************************************
* 根据电机霍尔换向信号给出相应控制信号
* 上桥臂:VT,UT,WT
* 下桥臂:VB,UB,WB
******************************************************************************/
void Phase_Change(void)
{
 if(PWM_Duty_min)
 {  
  UT=0;VT=0;WT=0;
  UB=1;VB=1;WB=1; // 电机停转
  PWM_Duty_Max = 0;
 } 
 else//========//
 {
  switch(H_State)
  {
   case 6: // 110,V3,V4
    VT=0;UT=0;VB=1;WB=1;     
    WT=1;UB=0;
    break;
   case 2: // 010,V4,V5
   case 7:
    UT=0;WT=0;VB=1;WB=1;
    VT=1;UB=0;
    break;
   case 3: // 011,V5,V6 
    UT=0;WT=0;UB=1;VB=1;
    VT=1;WB=0;
    break;
   case 1: // 001,V6,V1
    WT=0;VT=0;UB=1;VB=1;
    UT=1;WB=0; 
    break;
   case 5: // 101,V1,V2
   case 0:
    WT=0;VT=0;UB=1;WB=1;   
    VB=0;UT=1;
    break;
   case 4: // 100,V2,V3
    UT=0;VT=0;UB=1;WB=1;     
    WT=1;VB=0;
    break;
   case 9:
    UT=0;VT=0;WT=0;
    UB=1;VB=1;WB=1;
    break;
   default:break;
  }
 }

//-------检测--------//
void Phase_Detect(void)

 WT=0;UT=0;VT=0;
 switch(H_State)
 {
  case 6: // 110,V3,V4
    UB=0;VB=1;WB=1;
    break;
  case 2: // 010,V4,V5
  case 7:
    UB=0;VB=1;WB=1;
    break;
  case 3: // 011,V5,V6
    UB=1;VB=1;WB=0;
    break;
  case 1: // 001,V6,V1
    UB=1;VB=1;WB=0;
    break;
  case 5: // 101,V1,V2
  case 0:
    UB=1;VB=0;WB=1;
    break;
  case 4: // 100,V2,V3
    UB=1;VB=0;WB=1;
    break;
  default:break;
 }
}
/******************************************************************************
* PWM值转换程序
* 将转把电压ADC值转换为PWMn的值
******************************************************************************/
void PWM_ADJ(void)
{
 if(Speed_SUM < Speed_Low)
 { //---没有转把电压,由Speed_Low的值决定转把电压最小值---//  
  PWM_Duty_Max = 0;
  PWM_Duty_min=1; // 停转标志
  Block_Flag = 0; 
  Block_CNT = 0;           
 }
 else if(P14 == 1)
 { //---转把电压有效---//  
  PWM_Duty_Max=Speed_SUM-Speed_Low; // 对应转把电压的最大计算值
  if(PWM_Duty_min)
  {
   if(!Block_Flag) PWM_Duty_min = 0; // 退出无有效转把电压状况
  }
  if(PWM_Duty_Max>0x06F0)PWM_Duty_Max = 0x06E8; // 最大值限制
  if(Block_Flag)PWM_Duty_Max = 0;
  PWM_Duty_Max=PWM_Duty_Max>>1; // 由转把电压转换为PWMn的值
 } 
}
/******************************************************************************
* 电流闭环控制器
******************************************************************************/
void Current_Protect(void)
{
 if(Current_SUM < Current_Max) //  过流保护
 {
  if(PWM_Duty < PWM_Duty_Max)
    PWM_Duty ++; // 转把电压相对应的PWMn值缓慢增加
  else
  {
   if(PWM_Duty > 3)
    PWM_Duty --; // 转把电压相对应的PWMn值缓慢减小
   else
    PWM_Duty = 0;
  } 
 }
 else if(Current_SUM > Current_Max+5)
 {
  if(PWM_Duty > 2)
    PWM_Duty -= 2;
  else
   PWM_Duty=0;
 }
 PWM_Duty_H = PWM_Duty>>8;
 PWM_Duty_L = (PWM_Duty & 0x0FF); // 对应PWMn的值(高、低位)
}
/******************************************************************************
* 堵转保护程序
******************************************************************************/
void Block_Detect(void)
{
 if(Current_SUM > Current_Max-0x1A0)
 {  
  Block_CNT++; 
 }
 if(Current_SUM<0x300)
  Block_CNT = 0;
 if(Block_CNT >= 10)
 {
  EA = 0;
  UT=0;VT=0;WT=0;
  UB=1;VB=1;WB=1; // 电机停转
  PWM_Duty_min = 1;
  Block_Flag = 1;
  PWM_Duty = 0;
  PWM_Duty_Max = 0;
  PWM_Duty_H = 0;
  PWM_Duty_L = 0;  
  EA = 1;
 }
}
/******************************************************************************
* PWM设定
******************************************************************************/
void PWM_Setting(void)

 PWM0H=PWM_Duty_H;
 PWM0L=PWM_Duty_L;
 PWM1H=PWM_Duty_H;
 PWM1L=PWM_Duty_L; 
 PWM2H=PWM_Duty_H;
 PWM2L=PWM_Duty_L;
 PWMCON1 |= 0x40;
}
/******************************************************************************
******************************************************************************/

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

4

帖子

1

粉丝