代码,打算后期更改成ccs的代码:原文:http://www.51hei.com/bbs/dpj-196382-1.html
1 //****************************************************************************** 2 // Author:wwj 3 // Built with IAR V7.0 4 // Gui Lin 5 // IDE IAR430 6 /*截止当前: 7 功能: 8 本程序从平衡车程序移植出来,仍有平衡车的影子,但不影响运行。 9 1.硬件IIC读取6050,并在OLED上显示 10 2.中断测速 11 3.pwm电机驱动 12 4.循迹(由于每个人装循迹模块的位置都会有差异,需要自己调整传感器) 13 5.按键检测 14 6.蓝牙控制 15 7....ADD ING 16 17 勿拿本代码做交易!!! 18 勿拿本代码做交易!!! 19 勿拿本代码做交易!!! 20 21 本来只想放出来演示,突然发现有人从中谋取利益,于是决定共享源码!!! 22 各位朋友加油,未来的科技看你们!!! 23 24 */ 25 26 //****************************************************************************** 27 28 #include <msp430.h> 29 #include <stdint.h> 30 #include <stdbool.h> 31 //#include "oledfont.h" 32 //#include "msp430f5529.h" 33 #include "MPU6050.h" 34 #include "uart.h" 35 #include "exter_interr.h" 36 #include "pwm.h" 37 #include "time.h" 38 #include "hardw_i2c_oled.h" 39 #include "mathfun.h" 40 #include "xunji.h" 41 42 void OledDisApp(void); 43 44 void delay(unsigned int z) 45 { 46 unsigned int x,y; 47 for(x=z;x>0;x--) 48 for(y=5000;y>0;y--); 49 } 50 51 52 //****************************************************************************** 53 // Device Initialization ******************************************************* 54 //****************************************************************************** 55 56 void initClockTo16MHz() 57 { 58 UCSCTL3 |= SELREF_2; // Set DCO FLL reference = REFO 59 UCSCTL4 |= SELA_2; // Set ACLK = REFO 60 __bis_SR_register(SCG0); // Disable the FLL control loop 61 UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx 62 UCSCTL1 = DCORSEL_5; // Select DCO range 16MHz operation 63 UCSCTL2 = FLLD_0 + 487; // Set DCO Multiplier for 16MHz 64 // (N + 1) * FLLRef = Fdco 65 // (487 + 1) * 32768 = 16MHz 66 // Set FLL Div = fDCOCLK 67 __bic_SR_register(SCG0); // Enable the FLL control loop 68 69 // Worst-case settling time for the DCO when the DCO range bits have been 70 // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx 71 // UG for optimization. 72 // 32 x 32 x 16 MHz / 32,768 Hz = 500000 = MCLK cycles for DCO to settle 73 __delay_cycles(500000);// 74 // Loop until XT1,XT2 & DCO fault flag is cleared 75 do 76 { 77 UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags 78 SFRIFG1 &= ~OFIFG; // Clear fault flags 79 }while (SFRIFG1&OFIFG); // Test oscillator fault flag 80 } 81 uint16_t setVCoreUp(uint8_t level){ 82 uint32_t PMMRIE_backup, SVSMHCTL_backup, SVSMLCTL_backup; 83 84 //The code flow for increasing the Vcore has been altered to work around 85 //the erratum FLASH37. 86 //Please refer to the Errata sheet to know if a specific device is affected 87 //DO NOT ALTER THIS FUNCTION 88 89 //Open PMM registers for write access 90 PMMCTL0_H = 0xA5; 91 92 //Disable dedicated Interrupts 93 //Backup all registers 94 PMMRIE_backup = PMMRIE; 95 PMMRIE &= ~(SVMHVLRPE | SVSHPE | SVMLVLRPE | 96 SVSLPE | SVMHVLRIE | SVMHIE | 97 SVSMHDLYIE | SVMLVLRIE | SVMLIE | 98 SVSMLDLYIE 99 ); 100 SVSMHCTL_backup = SVSMHCTL; 101 SVSMLCTL_backup = SVSMLCTL; 102 103 //Clear flags 104 PMMIFG = 0; 105 106 //Set SVM highside to new level and check if a VCore increase is possible 107 SVSMHCTL = SVMHE | SVSHE | (SVSMHRRL0 * level); 108 109 //Wait until SVM highside is settled 110 while((PMMIFG & SVSMHDLYIFG) == 0) 111 { 112 ; 113 } 114 115 //Clear flag 116 PMMIFG &= ~SVSMHDLYIFG; 117 118 //Check if a VCore increase is possible 119 if((PMMIFG & SVMHIFG) == SVMHIFG) 120 { 121 //-> Vcc is too low for a Vcore increase 122 //recover the previous settings 123 PMMIFG &= ~SVSMHDLYIFG; 124 SVSMHCTL = SVSMHCTL_backup; 125 126 //Wait until SVM highside is settled 127 while((PMMIFG & SVSMHDLYIFG) == 0) 128 { 129 ; 130 } 131 132 //Clear all Flags 133 PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | 134 SVMLVLRIFG | SVMLIFG | 135 SVSMLDLYIFG 136 ); 137 138 //Restore PMM interrupt enable register 139 PMMRIE = PMMRIE_backup; 140 //Lock PMM registers for write access 141 PMMCTL0_H = 0x00; 142 //return: voltage not set 143 return false; 144 } 145 146 //Set also SVS highside to new level 147 //Vcc is high enough for a Vcore increase 148 SVSMHCTL |= (SVSHRVL0 * level); 149 150 //Wait until SVM highside is settled 151 while((PMMIFG & SVSMHDLYIFG) == 0) 152 { 153 ; 154 } 155 156 //Clear flag 157 PMMIFG &= ~SVSMHDLYIFG; 158 159 //Set VCore to new level 160 PMMCTL0_L = PMMCOREV0 * level; 161 162 //Set SVM, SVS low side to new level 163 SVSMLCTL = SVMLE | (SVSMLRRL0 * level) | 164 SVSLE | (SVSLRVL0 * level); 165 166 //Wait until SVM, SVS low side is settled 167 while((PMMIFG & SVSMLDLYIFG) == 0) 168 { 169 ; 170 } 171 172 //Clear flag 173 PMMIFG &= ~SVSMLDLYIFG; 174 //SVS, SVM core and high side are now set to protect for the new core level 175 176 //Restore Low side settings 177 //Clear all other bits _except_ level settings 178 SVSMLCTL &= (SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + 179 SVSMLRRL1 + SVSMLRRL2 180 ); 181 182 //Clear level settings in the backup register,keep all other bits 183 SVSMLCTL_backup &= 184 ~(SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2); 185 186 //Restore low-side SVS monitor settings 187 SVSMLCTL |= SVSMLCTL_backup; 188 189 //Restore High side settings 190 //Clear all other bits except level settings 191 SVSMHCTL &= (SVSHRVL0 + SVSHRVL1 + 192 SVSMHRRL0 + SVSMHRRL1 + 193 SVSMHRRL2 194 ); 195 196 //Clear level settings in the backup register,keep all other bits 197 SVSMHCTL_backup &= 198 ~(SVSHRVL0 + SVSHRVL1 + SVSMHRRL0 + SVSMHRRL1 + SVSMHRRL2); 199 200 //Restore backup 201 SVSMHCTL |= SVSMHCTL_backup; 202 203 //Wait until high side, low side settled 204 while(((PMMIFG & SVSMLDLYIFG) == 0) && 205 ((PMMIFG & SVSMHDLYIFG) == 0)) 206 { 207 ; 208 } 209 210 //Clear all Flags 211 PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | 212 SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG 213 ); 214 215 //Restore PMM interrupt enable register 216 PMMRIE = PMMRIE_backup; 217 218 //Lock PMM registers for write access 219 PMMCTL0_H = 0x00; 220 221 return true; 222 } 223 bool increaseVCoreToLevel2() 224 { 225 uint8_t level = 2; 226 uint8_t actlevel; 227 bool status = true; 228 229 //Set Mask for Max. level 230 level &= PMMCOREV_3; 231 232 //Get actual VCore 233 actlevel = PMMCTL0 & PMMCOREV_3; 234 235 //step by step increase or decrease 236 while((level != actlevel) && (status == true)) 237 { 238 if(level > actlevel) 239 { 240 status = setVCoreUp(++actlevel); 241 } 242 } 243 244 return (status); 245 } 246 247 void initGPIO() 248 { 249 //I2C Pins 250 P3SEL |= BIT0 + BIT1; // P3.0,1 option select 251 252 P1DIR |=BIT0; 253 P4DIR |=BIT7; 254 //按键输入 255 P2DIR &=~BIT1; 256 P1DIR &=~BIT1; 257 258 P2REN |= BIT1;//使能上下拉 259 P2OUT |= BIT1;//上拉 260 261 P1REN |= BIT1;//使能上下拉 262 P1OUT |= BIT1;//上拉 263 } 264 265 void initI2C() 266 { 267 268 269 UCB0CTL1 |= UCSWRST; // Enable SW reset(复位使能) 270 UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // Master, I2C,synchronous mode(同步模式) 271 UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset 272 UCB0BR0 = 160; // fSCL = SMCLK/160 = ~100kHz 273 UCB0BR1 = 0; 274 UCB0CTL0 &=~UCSLA10; //7位地址模式 275 UCB0I2CSA = SLAVE_ADDR>>1; //SlaveAddress>>1;//SLAVE_ADDR>>1; // 276 UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation 277 278 UCB0IFG &=~UCTXIFG; 279 280 } 281 282 int num; 283 int main(void) { 284 285 WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer 286 increaseVCoreToLevel2(); 287 initClockTo16MHz(); //配置系统时钟为16Mhz 288 //delay(10); 289 initGPIO(); 290 initI2C(); 291 //delay(10); 292 OLED_Init(); 293 //delay(10); 294 UART_Init('n',8,1); 295 InitMPU6050(); 296 //delay(10); 297 exterPin();//外部引脚中断 298 //MotorSpeedDetectionInit(); 299 PWMInit(); 300 TB6612INOUT(); 301 time0InterInit(); 302 xunioinit();//寻迹引脚初始化 303 delay(10); 304 //OLED_ShowChar(0,0,'A',16); 305 //OLED_ShowChar(16,0,'B',16); 306 //OLED_ShowChar(16*2,0,'C',16); 307 308 _EINT();//开启总中断 309 //曾经由于没开总中断,调了一下午... 310 while(1) 311 { 312 //按键检测 313 if((P2IN & BIT1) == 0) 314 { 315 delay(3); 316 if((P2IN & BIT1) == 0) 317 { 318 P1OUT ^= BIT0; 319 } 320 321 //PWM_Motor(-20,-20); 322 } 323 while(!(P2IN&BIT1)); 324 325 xunjiing();//寻迹 326 327 328 if(count_time >=20) 329 { 330 count_time =0; 331 // P1OUT ^= BIT0; //形成闪灯效果 332 Angle = Mpu6050AccelAngle(ACCEL_XOUT,ACCEL_ZOUT); 333 Angle_dot = Mpu6050GyroAngle(GYRO_YOUT); 334 335 // pwm_calculate();//PWM计算输出 336 337 338 } 339 340 341 342 #if 1 343 if(count_time2 >=10) 344 { 345 count_time2 =0; 346 OledDisApp(); 347 348 } 349 #endif 350 351 #if 0 352 if(Angle >10.0) 353 { 354 PWM_Motor(20,20); 355 } 356 else if(Angle < -10.0) 357 { 358 PWM_Motor(-20,-20); 359 } 360 else 361 { 362 Stop(); 363 } 364 365 #endif 366 367 368 369 370 //printf ("Pwm = %d \r\n",Pwm); 371 372 // 373 // OLED_Show_Number(0,6,abs(Angle),16); 374 //P1OUT ^=BIT0; 375 376 //printf("angle = %1f , angle_dot = %2f \r\n",Angle,Angle_dot); 377 //printf("ML = %d , MR = %d \r\n",speed_mL,speed_mR);//打印编码器 378 379 380 //PWM_Motor(20,-20);//测试电机,应看到左轮后退,右轮前进 381 382 //TA2CCR1 = abs(-100);//L 383 //TA1CCR1 = abs(256/2);//R 384 385 P4OUT ^=BIT7; 386 387 388 // delay(10); 389 } 390 391 } 392 void OledDisApp(void) 393 { 394 #if 1 395 if(Angle < 0.0) 396 { 397 //sprintf 398 OLED_ShowChar(32, 2, '-', 16); 399 } 400 else 401 { 402 OLED_ShowChar(32, 2, ' ', 16); 403 } 404 OLED_ShowNum(32+8, 2, abs(Angle), 3, 16); 405 OLED_ShowNum(32+8, 5, speedcar/2, 3, 16); 406 #endif 407 //================Speed==================== 408 #if 0 409 if(Speed < 0.0) 410 { 411 //sprintf 412 OLED_ShowChar(50, 2, '-', 16); 413 } 414 else 415 { 416 OLED_ShowChar(50, 2, ' ', 16); 417 } 418 OLED_ShowNum(50+8, 2, abs(Speed), 3, 16); 419 #endif 420 421 //fillRect(124, 64/2, 2, -63, 1,1); 422 423 424 }