📄 purpid.c
字号:
/**********************************************************/
#define DAC0 0 /* 1st digital to analog converter */
#define DAC1 1 /* 2nd digital to analog converter */
#define DAC2 2 /* 3rd digital to analog converter */
#define DAC3 3 /* 4th digital to analog converter */
#define DAC_XFER 4 /* transfer data */
#define DAC41 4
#define DAC4 0ch
#define DAC8 0008h
/*
Macro Expansion Declarations
*/
#define _DAC_BASE 0h
/*
Write Only
*/
#define _DAC0 _DAC_BASE+0 /* 1st digital to analog converter */
#define _DAC1 _DAC_BASE+1 /* 2nd digital to analog converter */
#define _DAC2 _DAC_BASE+2 /* 3rd digital to analog converter */
#define _DAC3 _DAC_BASE+3 /* 4th digital to analog converter */
#define _DAC_XFER _DAC_BASE+4 /* transfer data */
#define _DAC4 0ch
#define _DAC8 0008h
/*
Macro definitions
*/
#define ISRA 0x7094
#define ISRB 0x7096
#define PADATDIR 0x7098
#define PBDATDIR 0x709A
#define PCDATDIR 0x709C
/******************************************************************************/
int avera[5]={0,0,0,0,0};
volatile unsigned int * m ;
int YI;
float q;
unsigned int dac_vals[4];
/******************************************************************************/
/* define varies inorder to get the average output speed , every six time */
int average(int y)
{
int average1 ;
avera[0]=avera[1];
avera[1]=avera[2];
avera[2]=avera[3];
avera[3]=avera[4];
avera[4]=y;
average1=(int)(0.1*avera[0]+0.2*avera[1]+0.4*avera[2]+0.2*avera[3]+0.1*avera[4]);
avera[4]=average1;
return average1;
}
/*屏蔽中断子程序*/
void inline disable()
{
asm(" setc INTM");
}
/* 开总中断子程序*/
void inline enable()
{
asm(" clrc INTM ") ;
}
/*系统初始化子程序*/
void initial()
{
asm(" setc SXM"); /* 符号位扩展有效 */
asm(" clrc OVM"); /*累加器中结果正常溢出*/
asm(" clrc CNF"); /*B0 被配置为数据存储空间*/
/* * SCSR1=0x81FE ; */ /*CLKIN=6 M,CLKOUT=4 * CLKIN=24 M*/
*(volatile unsigned int*)SCSR1 = 0x81FE;
* WDCR =0X0E8 ; /* 不使能看门狗,因为SCSR2中的WDOVERRIDE*/
/*即WD保护位复位后的缺省值为1,故可以用*/
/*软件禁止看门狗*/
*IMR=0x0001 ; /*容许INT1中断*/
*IFR=0x0FFFF ; /*清除全部中断标志,"写1清0"*/
}
/* AD初始化程序 */
void ADINIT()
{
int i;
*T4CNT=0X0000; /* T4计数器清0部件*/
*T4CON=0X170C; /* T4为连续增计数模式,128分频,且选用内部时钟源*/
*T4PER=0X75; /* 设置T4的周期寄存器*/
*GPTCONB=0X400; /* T4周期中断标志触发AD转换*/
*EVBIFRB=0XFFFF; /* 清除EVB中断标志,"写1清0"*/
/*ADCTRL1=0X10 /* 采样时间窗口预定标位为ACQ PS3~ACQ PS0为0*/
*ADCTRL1=0X10; /*转换时间预定标位CPS为本0,AD为起动/停止模式*/
/* 排序器为级联工作方式,且禁止特殊的两种工作模式*/
*ADCTRL2=0X8404; /* 可以用EVB的一个事件信号触发AD转换*/
/* 且用中断模式1*/
*MAXCONV=0X00; /* 16通道*/
*CHSELSEQ1=0X3211;
*CHSELSEQ2=0X7654;
*CHSELSEQ3=0X0ba98;
*CHSELSEQ4=0X0fedc; /* 转换通道是0~15*/
for(i=0;i<24;i++)
{pcdata[i]=0;}
}
/* 启动AD转换子程序(通过启动定时器4的方式间接启动)*/
void ADSOC()
{
*T4CON=*T4CON|0x40 ; /*启动定时器4*/
}
/*AD中断服务子程序*/
int flag =0 ;
int k=0;
int j=0 ;
int as=0; /*抑制符号位扩展*/
int fan=0;
int x=0 ;
/*********/
/*给上位机送参数*/
void sendpc(float value,int charr)
{
int mid;
me=charr;
uart();
mid=value/10;
me=mid+48;
uart();
me=value-mid*10+48;
uart();
}
void interrupt adint()
{
while(fan<0x0f)
{
INMAC(_DAC8,as); /*关断DSP*/
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
if(as==0x02)
{
fan=0xff;
}
/* Y=2.0;
hd=0;
hi=0.25;
p=5; */
m=RESULT0;
YI=*m>>6;
q=average(YI) ;
backspeed=q/1023*3.3;
error[0]=error[1];
error[1]=error[2];
error[2]=1.0-backspeed;
mide1= error[2]-error[1];
mide2= error[2]-2*error[1]+error[0];
mide3=(mide3+error[2]);
runspeed=runspeed+(kp*mide1+ki*error[2]+kd*mide2);
/*mul=error[2]*backspeed;*/
if( runspeed >2.5) runspeed = 2.5; /* 过电压时保护调节 */
if( runspeed <0) runspeed = 0 ;
j=(int)(runspeed/2.5*4095);
/*******************************/
midv=q*3.3/1023 ;
/*midv=5.666;*/
me =72 ;
uart();
fpart=modf(midv , &ipart) ;
me =ipart+48 ;
uart();
fpart1 =(midv-ipart)*10 ;
modf(fpart1 , &ipart1) ;
me =ipart1+48 ;
uart();
fpart2 =(midv-ipart-(ipart1/10))*100 ;
modf(fpart2 , &ipart2) ;
me =ipart2+48 ;
uart();
fpart3 =(midv-ipart-(ipart1/10)-(ipart2/100))*1000 ;
modf(fpart3 , &ipart3) ;
me =ipart3+48 ;
uart();
pidi=kp;
pidf=(kp-pidi)*100;
sendpc(pidi,80);
sendpc(pidf,81);
pidi=ki;
pidf=(ki-pidi)*100;
sendpc(pidi,73);
sendpc(pidf,74);
pidi=kd;
pidf=(kd-pidi)*100;
sendpc(pidi,68);
sendpc(pidf,69) ;
wait_ms(2);
/*取一个字符*/
getchar=uart1_get_char();
/********************************/
OUTMAC( _DAC0, j);
for(x=0;x<=434;x++)
{
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
}
OUTMAC( _DAC_XFER, j); /* just need a write, any data */
OUTMAC( _DAC4,j); /* 实验现象*/
for(x=0;x<=434;x++)
{
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
}
}
j=0; /*程序结束*/
OUTMAC( _DAC0, j);
for(x=0;x<=34;x++)
{
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
OUTMAC( _DAC_XFER, j); /* just need a write, any data */
}
*ADCTRL2=*ADCTRL2|0X4200; /*复位SEQ1,且清除INT FLAG SEQ1 标志 "写1清0"*/
flag=1;
enable(); /*开总中断,因为一进入中断总中断就自动关闭了*/
}
main()
{
unsigned int uart_ctr;
disable() ; /*禁止总中断*/
initial() ; /*系统初始化*/
ADINIT() ; /*AD初始化子程序*/
test_init(); /* init variables & hardware */
init_uart1(); /* set up uart 9600, no parity, 1 stop */
uart_ctr = wait_ms(2);
enable() ; /*开总中断*/
ADSOC(); /*启动AD转换*/
/*while(1)
/*{
/* if(flag==0x1) break ; /*如果已发生中断,则停止等待(发生中断后,i=0x1)*/
/*} /*等待中断发生*/
/*T4CON=*T4CON&0X0FFBF; /* stop定时器4 ,即间接停止A/D转换*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -