📄 新建 文本文档 (4).txt
字号:
}
/*********************************************************
CCU溢出中断服务子程序
**********************************************************/
void CCU_int()
{
I++;
if(I==ccu_inter_count)
{
TCAP2H=ICRAH;
TCAP2L=ICRAL;
TPNA=NA;
TPI=I;
TCBP2H=ICRBH;
TCBP2L=ICRBL;
TPNB=NB;
NA=0x00;
NB=0x00;
I=0x0000;
}
TIFR2=TIFR2&0x7F; //将CCU溢出中断标志位清零
}
/*********************************************************
二进制数转BCD码
**********************************************************/
//二进制数转BCD码子程序0
void CONVBIT0(uint num,uchar hor)
{
DATA0[hor] = num/1000;
DATA0[hor+1] = num%1000/100;
DATA0[hor+2] = num%100/10;
DATA0[hor+3] = num%10/1;
}
//二进制数转BCD码子程序1
void CONVBIT1(uint num,uchar hor)
{
DATA1[hor] = num/1000;
DATA1[hor+1] = num%1000/100;
DATA1[hor+2] = num%100/10;
DATA1[hor+3] = num%10/1;
}
/*********************************************************
数据发送子程序
**********************************************************/
void SEND()
{
SPSTAT=0x80;
SPDAT=digitable[x];
while(SPSTAT!=0xbf)
{
};
SPSTAT=0x80;
SPDAT=digitable[y];
while(SPSTAT!=0xbf)
{
};
SPSTAT=0x80;
SPDAT=selectable[k];
while(SPSTAT!=0xbf)
{
};
RCLK=0;
RCLK=0;
RCLK=0;
RCLK=1;
RCLK=1;
RCLK=1;
RCLK=1;
RCLK=0;
RCLK=0;
RCLK=0;
}
/*********************************************************
读取EEPROM子程序
**********************************************************/
void rEEPROM()
{
for(j=1;j<2*CSM;j++)
{
DEECON=0x00; //初始化DEECON
DEEADR=(2*j-2);
while((DEECON&0x80)==0);
EDATA[0]=DEEDAT;
DEECON&=0x7F;
DEEADR=(2*j-1);
while((DEECON&0x80)==0);
EDATA[1]=DEEDAT;
CS[j-1]=(EDATA[0]*0x100+EDATA[1]);
DEECON&=0x7F;
}
}
/*********************************************************
频率计算法则
**********************************************************/
/* void CALL_frequency()
{
CAP2=(TCAP2H*0x100+TCAP2L); //将捕获值送入缓冲区
FA[p]=(32000000/(TPI*RESHIP+CAP1-CAP2)*TPNA); //计算ICA捕获信号频率
CAP1=CAP2;
CBP2=(TCBP2H*0x100+TCBP2L); //将捕获值送入缓冲区
FB[p]=(32000000/(TPI*RESHIP+CBP1-CBP2)*TPNB); //计算ICB捕获信号频率
CBP1=CBP2;
TPI=0;
} */
/*********************************************************
PID内环调速
**********************************************************/
/* void CALL_PID(void)
{
EKA1=VA-circl_count_A; //内环控速;
EKB1=VD-circl_count_B;
UKA=UKA+10*(EKA1-EKA2)+1*EKA1+1*(EKA1-2*EKA2+EKA3);
UKB=UKB+10*(EKB1-EKB2)+1*EKB1+1*(EKA1-2*EKA2+EKA3);
if(UKA>(RESHIP-3000))
UKA=(RESHIP-3000);
else{};
if(UKA<20)
UKA=20;
else{};
if(UKB>(RESHIP-3000))
UKB=(RESHIP-3000);
else{};
if(UKB<20)
UKB=20;
else{};
EKA3=EKA2;
EKB3=EKB2;
EKA2=EKA1;
EKB2=EKB1;
} */
/*********************************************************
开环控制
**********************************************************/
/* void KAI_HUAN(void)
{
UKA = VA;
UKB = VD;
} */
/*********************************************************
初始化IO口
**********************************************************/
void IO_ini(void)
{
P0M1=0xFF;
P0M2=0x00; //P0口做寻迹传感器接口,仅为输入
P1M1=0x0c;
P1M2=0xdf; //P1.0、P1.1、P1.2、P1.3、P1.4(P1.0、P1.3个继电器吸合控制口,对应电机PWM输出口分别为OCA和OCD)设为推挽输出
P2M1=0x89;
P2M2=0x76; //P2.3(READKEY)、P2.0(CAPTURE_b)和P2.7(CAPTURE_a)仅输入,其它推挽输出。
P1 = 0;
}
/*********************************************************
初始化定时器优先级
**********************************************************/
void IP_ini(void)
{
IP0H=IP0H&0xFD;
IP0=IP0&0xFD; //将定时器0中断优先级降最低
IP1H=IP1H|0x10;
IP1=IP1|0x10; //将CCU中断优先级升为最高
}
/*********************************************************
初始化SPI
**********************************************************/
void SPI_ini(void)
{
IN=1;
SCLK=1;
RCLK=0;
SPCTL=0xD0;
SPDAT=0x00;
}
/*********************************************************
初始化定时器
**********************************************************/
void TIME_ini(void)
{
TMOD=0x01;
TAMOD=0x00;
TH0=TH0_data;
TL0=TL0_data;
ET0=1;
TR0=1;
// TL2=0x00;
// TH2=0x7D; //SET THE T2 REPEAT VALUE
}
/*********************************************************
初始化CCU
**********************************************************/
void CCU_ini()
{
OCA=0;
OCB=0;
OCC=0;
OCD=0; //enable P2.6&P2.1 as PWM output
ICA=0;
ICB=0; //enable P2.7&P2.0 as pulse capture
TOR2L=0x92;
TOR2H=0xB2; //CCU重装初值
RESHIP=(TOR2H*0x100+TOR2L);//计算重装值
OCRAH=0x00; //vary both duty cycles
OCRAL=0x00;
OCRDH=0x00; //vary both duty cycles
OCRDL=0x00;
OCRAH=0x00; //vary both duty cycles
OCRBH=0x00; //vary both duty cycles
OCRBL=0x00;
OCRCH=0x00; //vary both duty cycles
OCRCL=0x00;
UKA=(OCRAH*0x100+OCRAL);
UKB=(OCRDH*0x100+OCRDL);
TPCR2H=0x00; //CCU预分频:
TPCR2L=0x00;
TCR21=0x85; //SET TCOU2=1 AND ENTER THE VALUE,PLLCLK=((Fosc/2)/(TCR21&0x0F+1))*32;
TCR20=0x00; //OutputMode: stop
CCCRA=0x19;
CCCRD=0x19; //SET CCCRA REGISTER
CCCRB=0x19;
CCCRC=0x19;
TIFR2=0x00; //清除所有CCU中断标志位
TCR20=0x86; //CCU定时器启动,输出PWM
TICR2=0x83; //开启捕获中断
ECCU=1;
}
/*********************************************************
初始化KBI
**********************************************************/
void KEY_ini()
{
EKBI = 1;
KBCON = 0x00;
KBPATN = 0xFF;
KBMASK = 0xFC; //KBI P0.4:0.7
}
/*********************************************************
初始化A/D转换
**********************************************************/
void AD_ini()
{
ADMODA = 0x11; //0x20:DUAL CHANNEL 2 CONVERTIONS
ADMODB = 0x60; //fosc:12MHZ,转换速度1.5M
ADINS = 0x12; //A/D通道选择P00与P01
ADCON0 = 0x04; //使能ADC0
ADCON1 = 0x04; //使能ADC1
ADCON0 |= 0x03; //启动ADC转换器
ADCON1 |= 0x03;
}
/*********************************************************
主程序
**********************************************************/
void main()
{
IO_ini();
IP_ini();
SPI_ini();
rEEPROM(); //读EEPROM;
TIME_ini();
CCU_ini();
KEY_ini();
AD_ini();
refreshMV();
EA=1;
while(1)
{
// if((TPI==ccu_inter_count)||(kflag==1))
// {
AD(); //启动A/D转换
CTRLUD(); //前进与后退方向控制
CTRLLR(); //左右方向控制
CTRLEXE(); //方向驱动程序
if(run==1)
{
// KAI_HUAN();
OCRAH=(UKA/0x100);
OCRAL=(UKA%0x100);
OCRDH=(UKB/0x100);
OCRDL=(UKB%0x100);
TCR21=0x85;
}
// else
// {} //end while(TPI==ccu_inter_count)
SCANKEY(); //手柄控制程序
// } //end if(run==1)
} //end while(1)
} //end main()
/*********************************************************
定时器0中服程序
用于键盘参数设计与数码显示
如果有键按下,先记下来,下次扫描才执行
**********************************************************/
void timer0_int(void) interrupt 1
{
TR0=0;
TH0=0xF0;
TL0=0x00;
while(w==80) //中断80次刷新显示一次
{
if(M==0)
{
CONVBIT0(AD_0,0);
CONVBIT0(AD_1,4);
CONVBIT1(0,0);
CONVBIT1(0,4);
}
else
{};
w=0;
SF=~SF;
}; // end while(w==80)
// 是否进入修改状态
if(M==0)
{
x=DATA0[k];
y=DATA1[k];
}
else
{
y=10; //y=10对应的段码是黑码
if(k==R)
{
if(SF==0)
{
x=10;
}
else
{
x=DATA0[k];
}
}
else
x=DATA0[k];
}
w++;
SEND();
//键盘扫描
if(KEY==1)
{
if(k==TK)
{
switch(TK)
{
case 7:
{
if(M==CSM)
{
M=1;
}
else
M++;
CONVBIT0(M,0);
CONVBIT0(CS[M-1],4);
}
break;
case 1:
{
if(R==7)
R=4;
else
R++;
}
break;
case 2:
{
if(DATA0[R]==9)
DATA0[R]=0;
else
DATA0[R]++;
}
break;
case 3:
{
if(DATA0[R]==0)
DATA0[R]=9;
else
DATA0[R]--;
}
break;
case 4:
{
while(!M==0)
{
CS[M-1]=(DATA0[4]*1000+DATA0[5]*100+DATA0[6]*10+DATA0[7]);
j=(2*M-2);
EDATA[j]=(CS[M-1]/0x100);
EDATA[j+1]=(CS[M-1]%0x100);
EA=0; //写EEPROM,关中断
DEECON=0x00;
DEEDAT=EDATA[j];
DEEADR=j;
while((DEECON&0x80)==0);
DEECON=DEECON&0x7F;
DEEDAT=EDATA[j+1];
DEEADR=(j+1);
while((DEECON&0x80)==0);
EA=1; //完成写操作,开中断
R=4;
M=0;
};
}
break;
}; //end switch(TK)
TK=0x09;
}
else
{}; //end if(k==TK)
}
else
{
TK=k;
}; //end if(KEY==1)
if(k==7)
k=0;
else
k++;
TR0=1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -