zoukankan      html  css  js  c++  java
  • 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 
    ",Pwm);
    371   
    372    // 
    373     // OLED_Show_Number(0,6,abs(Angle),16);
    374      //P1OUT ^=BIT0;
    375       
    376      //printf("angle = %1f , angle_dot = %2f 
    ",Angle,Angle_dot);
    377      //printf("ML = %d , MR = %d 
    ",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   }
  • 相关阅读:
    effective c++ 笔记 (30-31)
    设计模式 笔记 装饰模式 Decorator
    设计模式 笔记 组合模式 Composite
    设计模式 笔记 外观模式 Facade
    effective c++ 笔记 (26-29)
    设计模式 笔记 桥接模式 Bridge
    设计模式 笔记 适配器模式 Adapter
    算法导论 第二章作业
    设计模式 创建型模式实践
    设计模式 笔记 单例模式 Singleton
  • 原文地址:https://www.cnblogs.com/guochaoxxl/p/14128730.html
Copyright © 2011-2022 走看看