Kiko Ishimoto
/
Nucleo_spi
MBEDテスト
main.cpp
- Committer:
- kikoaac
- Date:
- 2015-07-21
- Revision:
- 2:1194c29429bf
- Parent:
- 0:5af71b978fb7
File content as of revision 2:1194c29429bf:
// Reply to a SPI master as slave float GAIN_P = 4.3f; // 比例ゲイン float GAIN_I = 1.3f; // 積分ゲイン float GAIN_D = 1.21f; #include "mbed.h" #include "Motor.h" #include "QEI.h" #include "PID.h" #include "Defines.h" #include "Registar.h" BusOut LED(Red_Pin,Green_Pin,Blue_Pin); class LEDMode { Ticker Tic; private: char led,Off; void Inter() { static int flag; flag++; if(flag&2) { LED = led; } else { Tic.attach(this,&LEDMode::Inter,TransWait*0.3); LED = Off; } } public: char Red,Blue,Green; char TransWait; char InterVal; char Mode[7];// = {RED|BLUE,RED|GREEN,RED|GREEN,BLUE|GREEN,BLUE|GREEN}; float Int[7]; char OFF[7]; LEDMode() { char mode[7] = {RED,RED|BLUE,RED|GREEN,RED|GREEN,BLUE|GREEN,BLUE|GREEN,RED|BLUE}; char off[7] = {0,0,0,GREEN,0,GREEN,RED}; float in[7] = {1,1,1.5,1.7,1.5,1.7,1.0}; for(int i=0;i<7;i++) { Mode[i]=mode[i]; Int[i]=in[i]; OFF[i]=off[i]; } Red=RED; Blue=BLUE; Green=GREEN; Off=0; } void Wait(int i) { float in = 1.0; TransWait = in; if(i==0)led = BLUE; else led = GREEN; Off=0; Tic.detach(); Tic.attach(this,&LEDMode::Inter,TransWait); } void Act(int i) { if(i>=6)i=6; { Off=OFF[i]; led = Mode[i]; TransWait = Int[i]; Tic.detach(); Tic.attach(this,&LEDMode::Inter,TransWait); } } }; LEDMode Led; PID pid(GAIN_P,GAIN_I,GAIN_D); short PR; short pulse ; short Rev; char Registar[0x80]={0}; char mode; /*double PIctrl(double dCommand, double dVal) { static double s_dErrIntg = 0 ,dErr_prev=0; double dErr; double dRet; // 誤差 dErr = dCommand - dVal; // 誤差積分 s_dErrIntg += (dErr+dErr_prev )* timer.read() /2.0; // 制御入力 dRet = GAIN_P * dErr + GAIN_I * s_dErrIntg + GAIN_D*(dErr-dErr_prev)/timer.read(); //printf("%f ",timer.read()); timer.reset(); //printf("%f ",dRet); dErr_prev = dErr; return (dRet); }*/ Ticker rotateT; //Ticker rotateN; //QEI wheel(Rotal_A,Rotal_B,NC,100,QEI::X4_ENCODING); Motor motor(Motor_H1,Motor_L2,Motor_L1,Motor_H2,Motor_PWM,short(0xffff)); void ManiacMotor_Mode(float duty,char mode) { motor.run(mode,duty); //motor=1; //printf("%f %f\n " , duty,1.0/duty); } //PinName rotatepin[3]; int rotatemode; void RotateSet() { //delete wheel; //pulse = short(Registar[PulsePerRev]<<8|Registar[PulsePerRev2]); /*if(Registar[RotateMode]&0x01)rotatepin[0]=Rotal_A; //else rotatepin[0]=dp13; if(Registar[RotateMode]&0x02)rotatepin[1]=Rotal_B; //else rotatepin[0]=dp13; if(Registar[RotateMode]&0x04)rotatepin[2]=Rotal_Z; //else rotatepin[0]=dp13;*/ if(Registar[RotateMode]&0x08)rotatemode=1; else if(!Registar[RotateMode]&0x08)rotatemode=0; if(Registar[RotateMode]&0x80) { //wheel.SetUp(rotatepin[0],rotatepin[1],rotatepin[2],pulse,rotatemode); //printf("make QEI\n"); } } void Rotate(/*void const *argument*/) { static bool flag=0; if(/*Registar[RotateMode]&0x80*/1) { if(!flag) { RotateSet(); flag=1; } pulse = short((Registar[PulsePerRev]<<8)|Registar[PulsePerRev+1]/*wheel.getPulses()*/); Rev = short((Registar[PulsePerRev]<<8)|Registar[PulsePerRev]/*wheel.getRevolutions()*/); PR = short((Registar[PulsePerSec]<<8)|Registar[PulsePerSec+1]/*wheel.getRPMS()*1000*/); Registar[MoterRevolutionH] = (Rev&0xff00)>>8; Registar[MoterRevolutionH-1] = (Rev&0xff); Registar[MoterPulseH] = (pulse&0xff00)>>8; Registar[MoterPulseH-1] = (pulse&0xff); Registar[MoterSpeedH] = (PR&0xff00)>>8; Registar[MoterSpeedH-1] = (PR&0xff); char IF = Registar[MotorMode]&(~0x80); if(IF == 3 || IF == 5) { pid.GAIN_P = (float)Registar[MotorP]/10; pid.GAIN_I = (float)Registar[MotorI]/10; pid.GAIN_D = (float)Registar[MotorD]/10; //printf("PID P%f I%f D%f \n",pid.GAIN_P,pid.GAIN_I,pid.GAIN_D); } //printf("Rotate::: %d ,%d ,%d\n",pulse, Registar[PulsePerRev], Registar[PulsePerRev+1]); } /*if(flag==1) { static char Reg; static short pul; if(Registar[RotateMode]!=Reg||short(Registar[PulsePerRev]<<8|Registar[PulsePerRev2])!=pul) flag=0; }*/ } void AngleStay(float point , float mypoint ,bool mode) { float sa; if(mode==1) sa = (int)point%360-(int)mypoint%360; else sa = point-mypoint; if(sa>10) motor.run(Front,1); else if(sa<-10) motor.run(Back,1); else motor.run(Stop,1); //printf("%f %f %f \n",mypoint,point,sa); } void AngleStay_PID(float point , float mypoint,bool mode) { //float x = PIctrl(point , mypoint); float sa=0; if(mode==1) sa = (int)point%360-(int)mypoint%360; else sa = point-mypoint; //pid.dPoint = mypoint; //pid.point = pid.PIDval;//wheel1.getSumangle(); pid.dPoint = mypoint; pid.dTarget = point;//wheel1.getSumangle(); float x = (float)pid.data; //float x = pid.PIDval; motor = x/5000; //printf("%f %f %f \n",mypoint,point,x/5000); } void SpeedStay(float point , float mypoint ,int mode) { float sa; static float duty=0.1; int X[2] = {Front , Back}; sa = (point-mypoint); float a = sa; if(sa<0)sa*=-1; if(a>0.3) { motor.run(X[mode],sa*duty/1000); duty+=1; } else if(a<-0.3) { motor.run(X[mode],sa*duty/1000); duty-=1; } else motor.run(X[mode],sa*duty/1000); //printf("%f %f %f \n",mypoint,point,sa*duty/1000); } void SpeedStay_PID(float point , float mypoint,int mode) { float x = 0; //x = PIctrl(point , mypoint); if(x<0)x*=-1; //if(point<0)point*=-1; int X[2] = {Front , Back}; pid.dPoint = mypoint; pid.dTarget = point;//wheel1.getSumangle(); x = (float)pid.data/1000; if(x<0.001&&x>-0.001)motor.run(Stop,x); else motor.run(X[mode],x); //printf("%f %f %f %i\n",mypoint,point,x/1000,mode); } char Inflag=0; void Motor_mode() { static char a=0; char IF = Registar[MotorMode]&(~0x80); switch(IF) { case 0:motor.run(Free,0);break; case 1:ManiacMotor_Mode(float((int(Registar[MotorPWM])<<8)|Registar[MotorPWM2])/0xffff,Registar[MotorState]);break; case 2:AngleStay(short(Registar[TargetAngle]<<8|Registar[TargetAngle2]),pulse*Registar[PulsePerAngle],Registar[MotorMode]>>7);break; case 3:AngleStay_PID(short(Registar[TargetAngle]<<8|Registar[TargetAngle2]),pulse*Registar[PulsePerAngle],Registar[MotorMode]>>7);break; case 4:SpeedStay(short(Registar[TargetSpeed]<<8|Registar[TargetSpeed2]),(float)PR*Registar[PulsePerAngle]/1000,int((Registar[TargetSpeed]>>7)==1));break; case 5:SpeedStay_PID(short(Registar[TargetSpeed]<<8|Registar[TargetSpeed2]),(float)PR*Registar[PulsePerAngle]/1000,int((Registar[TargetSpeed]>>7)==1));break; default:motor.run(Stop,0xffff); } static bool bo=false; if(!(IF==3||IF==5)&&bo==false) { //t.stop(); //printf("STOP\n"); pid.stop(); pid.s_dErrIntg = 0; bo=true; } else if((IF==3||IF==5)&&bo==true) { bo=false; //printf("START\n"); //t.stop(); pid.Start(); } //printf("%d",IF); if(IF!=a) Led.Act((int)IF); a=IF; //motor.run(Registar[MotorState],float(Registar[MotorPWM])/256.0); /*motor=float(Registar[MotorPWM]<<8|Registar[MotorPWM2]-32768)/32768.0; printf("%f\n",float(Registar[MotorPWM]<<8|Registar[MotorPWM2]-32768)/32768.0);*/ } void Tic(/*void const *argument*/) { Motor_mode(); Rotate(); //printf("Tic\n"); } //void timer(){ extern "C" void execute_spi_slave_hw( void ) { //ledDbg = 1; //wheel.state(1); if(i2c->receive()==I2CSlave::WriteAddressed&&mode==I2C_MODE) { //LED=Red; //encoder.stop(); //wheel->state(1); char DATA[2] = {}; i2c->read(DATA,2); char reg=DATA[0]; char num =DATA[1]; char X[num]; char f=0; wait_us(1000); //printf("R registar %d \n",reg); switch(i2c->receive()) { case 0 :break; case I2CSlave::ReadAddressed: { //char *po = Registar+reg; for(int i=0;i<num;i++) { //char a=*po+i; X[i] = Registar[reg+i]; } i2c->write(X,num); /*f=1; do { f = i2c->write(Registar[reg]); // printf(" %d ",Registar[reg]); reg++; }while(f==1);*/ break; } case I2CSlave::WriteGeneral:{ break; } case I2CSlave::WriteAddressed: { char num = DATA[1]; i2c->read(X,num); //Registar[reg]=D; for (int i=0;i<num;i++) { Registar[reg]=X[i]; // printf("%d ",Registar[reg]); //printf(" Registar : %d ,%d\n",Registar[reg],reg); reg++; } //printf(" Registar : %d ,%d\n",Registar[reg],reg); break; } } //printf("OK\n"); //wheel.state(0); } if(spi->receive()&&mode==SPI_MODE) { //LED=Blue|Red; //wheel.state(1); //rotateT.detach(); //encoder.stop(); char flag=1; char reg = spi->read(); wait_us(50); char num = spi->read(); //printf("SIZE %d\n",num); if(reg&0x80){ reg=reg&(~0x80); flag=0; spi->reply(Registar[reg]); } else spi->reply(0x00); //wait_us(10); if(flag) for(int i=0;i<num;i++) { while(!spi->receive()); wait_us(50); Registar[reg+i] = spi->read(); //printf("%d,%d\n",reg+i,Registar[reg+i]); } else { for(int i=0;i<num;i++) { // while(!spi->receive()); //wait_us(50); spi->reply(Registar[reg++]); char dummy = spi->read(); //printf("%d,%d\n",reg+i,Registar[reg+i]); } } //printf("%d , %d\n",reg,Registar[reg]); flag=1; //spi->reply(00); //wheel.state(0); //encoder.start(10); wait(.01); } /*NVIC_ClearPendingIRQ (TIMER_16_0_IRQn); NVIC_ClearPendingIRQ (TIMER_16_1_IRQn); NVIC_ClearPendingIRQ (TIMER_32_0_IRQn); NVIC_ClearPendingIRQ (TIMER_32_1_IRQn);*/ //wheel.state(0); //encode(); Inflag=1; } extern "C" void HardFault_Handler() { printf("Hard Fault!\n"); while(1); } int main() { //pc.baud(230400); Mode = new DigitalIn(MODE); Registar[Who_am_I] = 0x67; Registar[MotorP] = GAIN_P; Registar[MotorI] = GAIN_I; Registar[MotorD] = GAIN_D; //rotateN.attach(&enc,0.001); //Motor=0x08|0x01; if(*Mode==1) { spi = new SPISlave(MOSI, MISO, SCK,SSEL); spi->format(8,1); spi->frequency(4000000); spi->reply(0x00); // Prime SPI with first reply mode=SPI_MODE; Led.Wait(0); } else if(*Mode==0) { i2c = new I2CSlave(SDA,SCL); i2c->frequency(2000000); char address[4]={0x02,0x04,0x06,0x08}; Address = new BusIn(I2C_addr_L,I2C_addr_H); i2c->address(0xa0/*address[Address->read()]*/); mode=I2C_MODE; Led.Wait(1); delete Address ; } NVIC_SetVector( I2C_IRQn , ( uint32_t ) execute_spi_slave_hw ) ; NVIC_SetPriority( I2C_IRQn , 1) ; NVIC_EnableIRQ( I2C_IRQn ) ; NVIC_SetPriority(TIMER_16_0_IRQn,3); NVIC_SetPriority(TIMER_16_1_IRQn,4); NVIC_SetPriority(TIMER_32_0_IRQn,5); NVIC_SetPriority(TIMER_32_1_IRQn,6); rotateT.attach(&Tic,0.005); while(1) { //motor.run(1,1); // Motor_mode(); // Rotate(); /*while(10-ti.read_ms()>0) {} ti.reset(); encode();*/ } }