MSP430f5529小车源码

代码,打算后期更改成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   }

 

posted @ 2020-12-13 15:15  叕叒双又  阅读(1201)  评论(1编辑  收藏  举报