Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of Nucleo_spi by
main.cpp
00001 // Reply to a SPI master as slave 00002 float GAIN_P = 4.3f; // 比例ゲイン 00003 float GAIN_I = 1.3f; // 積分ゲイン 00004 float GAIN_D = 1.21f; 00005 00006 #include "mbed.h" 00007 #include "Motor.h" 00008 #include "QEI.h" 00009 #include "PID.h" 00010 #include "Defines.h" 00011 #include "Registar.h" 00012 BusOut LED(Red_Pin,Green_Pin,Blue_Pin); 00013 class LEDMode 00014 { 00015 Ticker Tic; 00016 private: 00017 char led,Off; 00018 void Inter() 00019 { 00020 static int flag; 00021 flag++; 00022 if(flag&2) 00023 { 00024 LED = led; 00025 } 00026 else 00027 { 00028 Tic.attach(this,&LEDMode::Inter,TransWait*0.3); 00029 LED = Off; 00030 } 00031 } 00032 public: 00033 char Red,Blue,Green; 00034 char TransWait; 00035 char InterVal; 00036 char Mode[7];// = {RED|BLUE,RED|GREEN,RED|GREEN,BLUE|GREEN,BLUE|GREEN}; 00037 float Int[7]; 00038 char OFF[7]; 00039 LEDMode() 00040 { 00041 char mode[7] = {RED,RED|BLUE,RED|GREEN,RED|GREEN,BLUE|GREEN,BLUE|GREEN,RED|BLUE}; 00042 char off[7] = {0,0,0,GREEN,0,GREEN,RED}; 00043 float in[7] = {1,1,1.5,1.7,1.5,1.7,1.0}; 00044 for(int i=0;i<7;i++) 00045 { 00046 Mode[i]=mode[i]; 00047 Int[i]=in[i]; 00048 OFF[i]=off[i]; 00049 } 00050 Red=RED; 00051 Blue=BLUE; 00052 Green=GREEN; 00053 Off=0; 00054 } 00055 void Wait(int i) 00056 { 00057 float in = 1.0; 00058 TransWait = in; 00059 if(i==0)led = BLUE; 00060 else led = GREEN; 00061 Off=0; 00062 Tic.detach(); 00063 Tic.attach(this,&LEDMode::Inter,TransWait); 00064 } 00065 void Act(int i) 00066 { 00067 if(i>=6)i=6; 00068 { 00069 Off=OFF[i]; 00070 led = Mode[i]; 00071 TransWait = Int[i]; 00072 Tic.detach(); 00073 Tic.attach(this,&LEDMode::Inter,TransWait); 00074 } 00075 } 00076 }; 00077 LEDMode Led; 00078 PID pid(GAIN_P,GAIN_I,GAIN_D); 00079 short PR; 00080 short pulse ; 00081 short Rev; 00082 char Registar[0x80]={0}; 00083 char mode; 00084 /*double PIctrl(double dCommand, double dVal) 00085 { 00086 static double s_dErrIntg = 0 ,dErr_prev=0; 00087 double dErr; 00088 double dRet; 00089 00090 // 誤差 00091 dErr = dCommand - dVal; 00092 00093 // 誤差積分 00094 s_dErrIntg += (dErr+dErr_prev )* timer.read() /2.0; 00095 00096 // 制御入力 00097 dRet = GAIN_P * dErr + GAIN_I * s_dErrIntg + GAIN_D*(dErr-dErr_prev)/timer.read(); 00098 //printf("%f ",timer.read()); 00099 timer.reset(); 00100 //printf("%f ",dRet); 00101 dErr_prev = dErr; 00102 return (dRet); 00103 }*/ 00104 Ticker rotateT; 00105 //Ticker rotateN; 00106 //QEI wheel(Rotal_A,Rotal_B,NC,100,QEI::X4_ENCODING); 00107 00108 00109 Motor motor(Motor_H1,Motor_L2,Motor_L1,Motor_H2,Motor_PWM,short(0xffff)); 00110 00111 void ManiacMotor_Mode(float duty,char mode) 00112 { 00113 motor.run(mode,duty); 00114 //motor=1; 00115 //printf("%f %f\n " , duty,1.0/duty); 00116 } 00117 //PinName rotatepin[3]; 00118 int rotatemode; 00119 void RotateSet() 00120 { 00121 //delete wheel; 00122 //pulse = short(Registar[PulsePerRev]<<8|Registar[PulsePerRev2]); 00123 /*if(Registar[RotateMode]&0x01)rotatepin[0]=Rotal_A; 00124 //else rotatepin[0]=dp13; 00125 if(Registar[RotateMode]&0x02)rotatepin[1]=Rotal_B; 00126 //else rotatepin[0]=dp13; 00127 if(Registar[RotateMode]&0x04)rotatepin[2]=Rotal_Z; 00128 //else rotatepin[0]=dp13;*/ 00129 if(Registar[RotateMode]&0x08)rotatemode=1; 00130 else if(!Registar[RotateMode]&0x08)rotatemode=0; 00131 if(Registar[RotateMode]&0x80) 00132 { 00133 //wheel.SetUp(rotatepin[0],rotatepin[1],rotatepin[2],pulse,rotatemode); 00134 //printf("make QEI\n"); 00135 } 00136 } 00137 void Rotate(/*void const *argument*/) 00138 { 00139 static bool flag=0; 00140 00141 if(/*Registar[RotateMode]&0x80*/1) 00142 { 00143 if(!flag) 00144 { 00145 RotateSet(); 00146 flag=1; 00147 } 00148 pulse = short((Registar[PulsePerRev]<<8)|Registar[PulsePerRev+1]/*wheel.getPulses()*/); 00149 Rev = short((Registar[PulsePerRev]<<8)|Registar[PulsePerRev]/*wheel.getRevolutions()*/); 00150 PR = short((Registar[PulsePerSec]<<8)|Registar[PulsePerSec+1]/*wheel.getRPMS()*1000*/); 00151 Registar[MoterRevolutionH] = (Rev&0xff00)>>8; 00152 Registar[MoterRevolutionH-1] = (Rev&0xff); 00153 Registar[MoterPulseH] = (pulse&0xff00)>>8; 00154 Registar[MoterPulseH-1] = (pulse&0xff); 00155 Registar[MoterSpeedH] = (PR&0xff00)>>8; 00156 Registar[MoterSpeedH-1] = (PR&0xff); 00157 char IF = Registar[MotorMode]&(~0x80); 00158 if(IF == 3 || IF == 5) 00159 { 00160 pid.GAIN_P = (float)Registar[MotorP]/10; 00161 pid.GAIN_I = (float)Registar[MotorI]/10; 00162 pid.GAIN_D = (float)Registar[MotorD]/10; 00163 //printf("PID P%f I%f D%f \n",pid.GAIN_P,pid.GAIN_I,pid.GAIN_D); 00164 } 00165 //printf("Rotate::: %d ,%d ,%d\n",pulse, Registar[PulsePerRev], Registar[PulsePerRev+1]); 00166 } 00167 /*if(flag==1) 00168 { 00169 static char Reg; 00170 static short pul; 00171 if(Registar[RotateMode]!=Reg||short(Registar[PulsePerRev]<<8|Registar[PulsePerRev2])!=pul) 00172 flag=0; 00173 }*/ 00174 } 00175 void AngleStay(float point , float mypoint ,bool mode) 00176 { 00177 float sa; 00178 if(mode==1) sa = (int)point%360-(int)mypoint%360; 00179 else sa = point-mypoint; 00180 if(sa>10) 00181 motor.run(Front,1); 00182 else if(sa<-10) 00183 motor.run(Back,1); 00184 else motor.run(Stop,1); 00185 00186 //printf("%f %f %f \n",mypoint,point,sa); 00187 } 00188 void AngleStay_PID(float point , float mypoint,bool mode) 00189 { 00190 //float x = PIctrl(point , mypoint); 00191 float sa=0; 00192 if(mode==1) sa = (int)point%360-(int)mypoint%360; 00193 else sa = point-mypoint; 00194 //pid.dPoint = mypoint; 00195 //pid.point = pid.PIDval;//wheel1.getSumangle(); 00196 pid.dPoint = mypoint; 00197 pid.dTarget = point;//wheel1.getSumangle(); 00198 float x = (float)pid.data; 00199 //float x = pid.PIDval; 00200 motor = x/5000; 00201 //printf("%f %f %f \n",mypoint,point,x/5000); 00202 } 00203 00204 void SpeedStay(float point , float mypoint ,int mode) 00205 { 00206 float sa; 00207 static float duty=0.1; 00208 int X[2] = {Front , Back}; 00209 sa = (point-mypoint); 00210 float a = sa; 00211 if(sa<0)sa*=-1; 00212 if(a>0.3) 00213 { 00214 motor.run(X[mode],sa*duty/1000); 00215 duty+=1; 00216 } 00217 else if(a<-0.3) 00218 { 00219 motor.run(X[mode],sa*duty/1000); 00220 duty-=1; 00221 } 00222 else motor.run(X[mode],sa*duty/1000); 00223 00224 //printf("%f %f %f \n",mypoint,point,sa*duty/1000); 00225 } 00226 void SpeedStay_PID(float point , float mypoint,int mode) 00227 { 00228 float x = 0; 00229 //x = PIctrl(point , mypoint); 00230 if(x<0)x*=-1; 00231 //if(point<0)point*=-1; 00232 int X[2] = {Front , Back}; 00233 pid.dPoint = mypoint; 00234 pid.dTarget = point;//wheel1.getSumangle(); 00235 x = (float)pid.data/1000; 00236 if(x<0.001&&x>-0.001)motor.run(Stop,x); 00237 else motor.run(X[mode],x); 00238 //printf("%f %f %f %i\n",mypoint,point,x/1000,mode); 00239 } 00240 char Inflag=0; 00241 void Motor_mode() 00242 { 00243 static char a=0; 00244 char IF = Registar[MotorMode]&(~0x80); 00245 switch(IF) 00246 { 00247 case 0:motor.run(Free,0);break; 00248 case 1:ManiacMotor_Mode(float((int(Registar[MotorPWM])<<8)|Registar[MotorPWM2])/0xffff,Registar[MotorState]);break; 00249 case 2:AngleStay(short(Registar[TargetAngle]<<8|Registar[TargetAngle2]),pulse*Registar[PulsePerAngle],Registar[MotorMode]>>7);break; 00250 case 3:AngleStay_PID(short(Registar[TargetAngle]<<8|Registar[TargetAngle2]),pulse*Registar[PulsePerAngle],Registar[MotorMode]>>7);break; 00251 case 4:SpeedStay(short(Registar[TargetSpeed]<<8|Registar[TargetSpeed2]),(float)PR*Registar[PulsePerAngle]/1000,int((Registar[TargetSpeed]>>7)==1));break; 00252 case 5:SpeedStay_PID(short(Registar[TargetSpeed]<<8|Registar[TargetSpeed2]),(float)PR*Registar[PulsePerAngle]/1000,int((Registar[TargetSpeed]>>7)==1));break; 00253 default:motor.run(Stop,0xffff); 00254 } 00255 static bool bo=false; 00256 if(!(IF==3||IF==5)&&bo==false) 00257 { 00258 //t.stop(); 00259 //printf("STOP\n"); 00260 pid.stop(); 00261 pid.s_dErrIntg = 0; 00262 bo=true; 00263 } 00264 else if((IF==3||IF==5)&&bo==true) 00265 { 00266 bo=false; 00267 //printf("START\n"); 00268 //t.stop(); 00269 pid.Start(); 00270 } 00271 //printf("%d",IF); 00272 if(IF!=a) 00273 Led.Act((int)IF); 00274 a=IF; 00275 //motor.run(Registar[MotorState],float(Registar[MotorPWM])/256.0); 00276 /*motor=float(Registar[MotorPWM]<<8|Registar[MotorPWM2]-32768)/32768.0; 00277 printf("%f\n",float(Registar[MotorPWM]<<8|Registar[MotorPWM2]-32768)/32768.0);*/ 00278 } 00279 00280 void Tic(/*void const *argument*/) 00281 { 00282 Motor_mode(); 00283 Rotate(); 00284 00285 //printf("Tic %d\n"); 00286 } 00287 //void timer(){ 00288 extern "C" void execute_spi_slave_hw( void ) 00289 { 00290 //ledDbg = 1; 00291 //wheel.state(1); 00292 if(i2c->receive()==I2CSlave::WriteAddressed&&mode==I2C_MODE) 00293 { 00294 //LED=Red; 00295 //encoder.stop(); 00296 //wheel->state(1); 00297 char DATA[2] = {}; 00298 i2c->read(DATA,2); 00299 char reg=DATA[0]; 00300 char num =DATA[1]; 00301 char X[num]; 00302 char f=0; 00303 wait_us(1000); 00304 //printf("R registar %d \n",reg); 00305 switch(i2c->receive()) 00306 { 00307 case 0 :break; 00308 case I2CSlave::ReadAddressed: 00309 { 00310 //char *po = Registar+reg; 00311 for(int i=0;i<num;i++) 00312 { 00313 //char a=*po+i; 00314 X[i] = Registar[reg+i]; 00315 } 00316 i2c->write(X,num); 00317 /*f=1; 00318 do 00319 { 00320 f = i2c->write(Registar[reg]); 00321 // printf(" %d ",Registar[reg]); 00322 reg++; 00323 }while(f==1);*/ 00324 break; 00325 } 00326 case I2CSlave::WriteGeneral:{ 00327 00328 break; 00329 } 00330 case I2CSlave::WriteAddressed: 00331 { 00332 char num = DATA[1]; 00333 i2c->read(X,num); 00334 //Registar[reg]=D; 00335 for (int i=0;i<num;i++) 00336 { 00337 Registar[reg]=X[i]; 00338 // printf("%d ",Registar[reg]); 00339 //printf(" Registar : %d ,%d\n",Registar[reg],reg); 00340 reg++; 00341 } 00342 //printf(" Registar : %d ,%d\n",Registar[reg],reg); 00343 break; 00344 } 00345 } 00346 //printf("OK\n"); 00347 //wheel.state(0); 00348 } 00349 if(spi->receive()&&mode==SPI_MODE) { 00350 //LED=Blue|Red; 00351 //wheel.state(1); 00352 //rotateT.detach(); 00353 //encoder.stop(); 00354 char flag=1; 00355 char reg = spi->read(); 00356 wait_us(50); 00357 char num = spi->read(); 00358 //printf("SIZE %d\n",num); 00359 if(reg&0x80){ 00360 reg=reg&(~0x80); 00361 flag=0; 00362 spi->reply(Registar[reg]); 00363 } 00364 else spi->reply(0x00); 00365 //wait_us(10); 00366 00367 if(flag) 00368 for(int i=0;i<num;i++) 00369 { 00370 while(!spi->receive()); 00371 wait_us(50); 00372 Registar[reg+i] = spi->read(); 00373 //printf("%d,%d\n",reg+i,Registar[reg+i]); 00374 } 00375 else 00376 { 00377 for(int i=0;i<num;i++) 00378 { 00379 // 00380 while(!spi->receive()); 00381 //wait_us(50); 00382 spi->reply(Registar[reg++]); 00383 char dummy = spi->read(); 00384 //printf("%d,%d\n",reg+i,Registar[reg+i]); 00385 } 00386 00387 } 00388 //printf("%d , %d\n",reg,Registar[reg]); 00389 flag=1; 00390 //spi->reply(00); 00391 00392 //wheel.state(0); 00393 //encoder.start(10); 00394 wait(.01); 00395 } 00396 /*NVIC_ClearPendingIRQ (TIMER_16_0_IRQn); 00397 NVIC_ClearPendingIRQ (TIMER_16_1_IRQn); 00398 NVIC_ClearPendingIRQ (TIMER_32_0_IRQn); 00399 NVIC_ClearPendingIRQ (TIMER_32_1_IRQn);*/ 00400 //wheel.state(0); 00401 //encode(); 00402 Inflag=1; 00403 } 00404 extern "C" void HardFault_Handler() { 00405 printf("Hard Fault!\n"); 00406 while(1); 00407 } 00408 int main() { 00409 //pc.baud(230400); 00410 Mode = new DigitalIn(MODE); 00411 Registar[Who_am_I] = 0x67; 00412 Registar[MotorP] = GAIN_P; 00413 Registar[MotorI] = GAIN_I; 00414 Registar[MotorD] = GAIN_D; 00415 //rotateN.attach(&enc,0.001); 00416 //Motor=0x08|0x01; 00417 if(*Mode==1) 00418 { 00419 spi = new SPISlave(MOSI, MISO, SCK,SSEL); 00420 spi->format(8,1); 00421 spi->frequency(4000000); 00422 spi->reply(0x00); // Prime SPI with first reply 00423 mode=SPI_MODE; 00424 Led.Wait(0); 00425 } 00426 else if(*Mode==0) 00427 { 00428 i2c = new I2CSlave(SDA,SCL); 00429 i2c->frequency(2000000); 00430 char address[4]={0x02,0x04,0x06,0x08}; 00431 Address = new BusIn(I2C_addr_L,I2C_addr_H); 00432 i2c->address(0xa0/*address[Address->read()]*/); 00433 mode=I2C_MODE; 00434 Led.Wait(1); 00435 delete Address ; 00436 } 00437 NVIC_SetVector( I2C_IRQn , ( uint32_t ) execute_spi_slave_hw ) ; 00438 NVIC_SetPriority( I2C_IRQn , 1) ; 00439 NVIC_EnableIRQ( I2C_IRQn ) ; 00440 00441 NVIC_SetPriority(TIMER_16_0_IRQn,3); 00442 NVIC_SetPriority(TIMER_16_1_IRQn,4); 00443 NVIC_SetPriority(TIMER_32_0_IRQn,5); 00444 NVIC_SetPriority(TIMER_32_1_IRQn,6); 00445 rotateT.attach(&Tic,0.005); 00446 while(1) { 00447 00448 //motor.run(1,1); 00449 // Motor_mode(); 00450 // Rotate(); 00451 /*while(10-ti.read_ms()>0) 00452 {} 00453 ti.reset(); 00454 encode();*/ 00455 00456 } 00457 } 00458 00459 00460 00461 00462
Generated on Wed Jul 27 2022 08:00:01 by
1.7.2
