|
https://www.bilibili.com/video/BV1Jz4y1o7Lv/
單片機源程序如下:
- //******************************************************************************
- // Author:wwj
- // Built with IAR V7.0
- // Gui Lin
- // IDE IAR430
- /*截止當(dāng)前:
- 功能:
- 本程序從平衡車程序移植出來,仍有平衡車的影子,但不影響運行。
- 1.硬件IIC讀取6050,并在OLED上顯示
- 2.中斷測速
- 3.pwm電機驅(qū)動
- 4.循跡(由于每個人裝循跡模塊的位置都會有差異,需要自己調(diào)整傳感器)
- 5.按鍵檢測
- 6.藍牙控制
- 7....ADD ING
- 勿拿本代碼做交易!!!
- 勿拿本代碼做交易!!!
- 勿拿本代碼做交易!!!
- 本來只想放出來演示,突然發(fā)現(xiàn)有人從中謀取利益,于是決定共享源碼!!!
- 各位朋友加油,未來的科技看你們!!!
- */
- //******************************************************************************
- #include <msp430.h>
- #include <stdint.h>
- #include <stdbool.h>
- //#include "oledfont.h"
- //#include "msp430f5529.h"
- #include "MPU6050.h"
- #include "uart.h"
- #include "exter_interr.h"
- #include "pwm.h"
- #include "time.h"
- #include "hardw_i2c_oled.h"
- #include "mathfun.h"
- #include "xunji.h"
- void OledDisApp(void);
- void delay(unsigned int z)
- {
- unsigned int x,y;
- for(x=z;x>0;x--)
- for(y=5000;y>0;y--);
- }
- //******************************************************************************
- // Device Initialization *******************************************************
- //******************************************************************************
- void initClockTo16MHz()
- {
- UCSCTL3 |= SELREF_2; // Set DCO FLL reference = REFO
- UCSCTL4 |= SELA_2; // Set ACLK = REFO
- __bis_SR_register(SCG0); // Disable the FLL control loop
- UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx
- UCSCTL1 = DCORSEL_5; // Select DCO range 16MHz operation
- UCSCTL2 = FLLD_0 + 487; // Set DCO Multiplier for 16MHz
- // (N + 1) * FLLRef = Fdco
- // (487 + 1) * 32768 = 16MHz
- // Set FLL Div = fDCOCLK
- __bic_SR_register(SCG0); // Enable the FLL control loop
- // Worst-case settling time for the DCO when the DCO range bits have been
- // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
- // UG for optimization.
- // 32 x 32 x 16 MHz / 32,768 Hz = 500000 = MCLK cycles for DCO to settle
- __delay_cycles(500000);//
- // Loop until XT1,XT2 & DCO fault flag is cleared
- do
- {
- UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags
- SFRIFG1 &= ~OFIFG; // Clear fault flags
- }while (SFRIFG1&OFIFG); // Test oscillator fault flag
- }
- uint16_t setVCoreUp(uint8_t level){
- uint32_t PMMRIE_backup, SVSMHCTL_backup, SVSMLCTL_backup;
- //The code flow for increasing the Vcore has been altered to work around
- //the erratum FLASH37.
- //Please refer to the Errata sheet to know if a specific device is affected
- //DO NOT ALTER THIS FUNCTION
- //Open PMM registers for write access
- PMMCTL0_H = 0xA5;
- //Disable dedicated Interrupts
- //Backup all registers
- PMMRIE_backup = PMMRIE;
- PMMRIE &= ~(SVMHVLRPE | SVSHPE | SVMLVLRPE |
- SVSLPE | SVMHVLRIE | SVMHIE |
- SVSMHDLYIE | SVMLVLRIE | SVMLIE |
- SVSMLDLYIE
- );
- SVSMHCTL_backup = SVSMHCTL;
- SVSMLCTL_backup = SVSMLCTL;
- //Clear flags
- PMMIFG = 0;
- //Set SVM highside to new level and check if a VCore increase is possible
- SVSMHCTL = SVMHE | SVSHE | (SVSMHRRL0 * level);
- //Wait until SVM highside is settled
- while((PMMIFG & SVSMHDLYIFG) == 0)
- {
- ;
- }
- //Clear flag
- PMMIFG &= ~SVSMHDLYIFG;
- //Check if a VCore increase is possible
- if((PMMIFG & SVMHIFG) == SVMHIFG)
- {
- //-> Vcc is too low for a Vcore increase
- //recover the previous settings
- PMMIFG &= ~SVSMHDLYIFG;
- SVSMHCTL = SVSMHCTL_backup;
- //Wait until SVM highside is settled
- while((PMMIFG & SVSMHDLYIFG) == 0)
- {
- ;
- }
- //Clear all Flags
- PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG |
- SVMLVLRIFG | SVMLIFG |
- SVSMLDLYIFG
- );
- //Restore PMM interrupt enable register
- PMMRIE = PMMRIE_backup;
- //Lock PMM registers for write access
- PMMCTL0_H = 0x00;
- //return: voltage not set
- return false;
- }
- //Set also SVS highside to new level
- //Vcc is high enough for a Vcore increase
- SVSMHCTL |= (SVSHRVL0 * level);
- //Wait until SVM highside is settled
- while((PMMIFG & SVSMHDLYIFG) == 0)
- {
- ;
- }
- //Clear flag
- PMMIFG &= ~SVSMHDLYIFG;
- //Set VCore to new level
- PMMCTL0_L = PMMCOREV0 * level;
- //Set SVM, SVS low side to new level
- SVSMLCTL = SVMLE | (SVSMLRRL0 * level) |
- SVSLE | (SVSLRVL0 * level);
- //Wait until SVM, SVS low side is settled
- while((PMMIFG & SVSMLDLYIFG) == 0)
- {
- ;
- }
- //Clear flag
- PMMIFG &= ~SVSMLDLYIFG;
- //SVS, SVM core and high side are now set to protect for the new core level
- //Restore Low side settings
- //Clear all other bits _except_ level settings
- SVSMLCTL &= (SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 +
- SVSMLRRL1 + SVSMLRRL2
- );
- //Clear level settings in the backup register,keep all other bits
- SVSMLCTL_backup &=
- ~(SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2);
- //Restore low-side SVS monitor settings
- SVSMLCTL |= SVSMLCTL_backup;
- //Restore High side settings
- //Clear all other bits except level settings
- SVSMHCTL &= (SVSHRVL0 + SVSHRVL1 +
- SVSMHRRL0 + SVSMHRRL1 +
- SVSMHRRL2
- );
- //Clear level settings in the backup register,keep all other bits
- SVSMHCTL_backup &=
- ~(SVSHRVL0 + SVSHRVL1 + SVSMHRRL0 + SVSMHRRL1 + SVSMHRRL2);
- //Restore backup
- SVSMHCTL |= SVSMHCTL_backup;
- //Wait until high side, low side settled
- while(((PMMIFG & SVSMLDLYIFG) == 0) &&
- ((PMMIFG & SVSMHDLYIFG) == 0))
- {
- ;
- }
- //Clear all Flags
- PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG |
- SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG
- );
- //Restore PMM interrupt enable register
- PMMRIE = PMMRIE_backup;
- //Lock PMM registers for write access
- PMMCTL0_H = 0x00;
- return true;
- }
- bool increaseVCoreToLevel2()
- {
- uint8_t level = 2;
- uint8_t actlevel;
- bool status = true;
- //Set Mask for Max. level
- level &= PMMCOREV_3;
- //Get actual VCore
- actlevel = PMMCTL0 & PMMCOREV_3;
- //step by step increase or decrease
- while((level != actlevel) && (status == true))
- {
- if(level > actlevel)
- {
- status = setVCoreUp(++actlevel);
- }
- }
- return (status);
- }
- void initGPIO()
- {
- //I2C Pins
- P3SEL |= BIT0 + BIT1; // P3.0,1 option select
-
- P1DIR |=BIT0;
- P4DIR |=BIT7;
- //按鍵輸入
- P2DIR &=~BIT1;
- P1DIR &=~BIT1;
-
- P2REN |= BIT1;//使能上下拉
- P2OUT |= BIT1;//上拉
-
- P1REN |= BIT1;//使能上下拉
- P1OUT |= BIT1;//上拉
- }
- void initI2C()
- {
-
-
- UCB0CTL1 |= UCSWRST; // Enable SW reset(復(fù)位使能)
- UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // Master, I2C,synchronous mode(同步模式)
- UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
- UCB0BR0 = 160; // fSCL = SMCLK/160 = ~100kHz
- UCB0BR1 = 0;
- UCB0CTL0 &=~UCSLA10; //7位地址模式
- UCB0I2CSA = SLAVE_ADDR>>1; //SlaveAddress>>1;//SLAVE_ADDR>>1; //
- UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
-
- UCB0IFG &=~UCTXIFG;
-
- }
- int num;
- int main(void) {
- WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
- increaseVCoreToLevel2();
- initClockTo16MHz(); //配置系統(tǒng)時鐘為16Mhz
- //delay(10);
- initGPIO();
- initI2C();
- //delay(10);
- OLED_Init();
- //delay(10);
- UART_Init('n',8,1);
- InitMPU6050();
- //delay(10);
- exterPin();//外部引腳中斷
- //MotorSpeedDetectionInit();
- PWMInit();
- TB6612INOUT();
- time0InterInit();
- xunioinit();//尋跡引腳初始化
- delay(10);
- //OLED_ShowChar(0,0,'A',16);
- //OLED_ShowChar(16,0,'B',16);
- //OLED_ShowChar(16*2,0,'C',16);
-
- _EINT();//開啟總中斷
- //曾經(jīng)由于沒開總中斷,調(diào)了一下午...
- while(1)
- {
- //按鍵檢測
- if((P2IN & BIT1) == 0)
- {
- delay(3);
- if((P2IN & BIT1) == 0)
- {
- P1OUT ^= BIT0;
- }
-
- //PWM_Motor(-20,-20);
- }
- while(!(P2IN&BIT1));
-
- xunjiing();//尋跡
-
-
- if(count_time >=20)
- {
- count_time =0;
- // P1OUT ^= BIT0; //形成閃燈效果
- Angle = Mpu6050AccelAngle(ACCEL_XOUT,ACCEL_ZOUT);
- Angle_dot = Mpu6050GyroAngle(GYRO_YOUT);
-
- // pwm_calculate();//PWM計算輸出
-
-
- }
-
-
- #if 1
- if(count_time2 >=10)
- {
- count_time2 =0;
- OledDisApp();
-
- }
- #endif
-
- #if 0
- if(Angle >10.0)
- {
- PWM_Motor(20,20);
- }
- else if(Angle < -10.0)
- {
- PWM_Motor(-20,-20);
- }
- else
- {
- Stop();
- }
-
- #endif
-
-
-
-
- //printf ("Pwm = %d \r\n",Pwm);
-
- //
- // OLED_Show_Number(0,6,abs(Angle),16);
- //P1OUT ^=BIT0;
-
- //printf("angle = %1f , angle_dot = %2f \r\n",Angle,Angle_dot);
- //printf("ML = %d , MR = %d \r\n",speed_mL,speed_mR);//打印編碼器
-
-
- //PWM_Motor(20,-20);//測試電機,應(yīng)看到左輪后退,右輪前進
-
- //TA2CCR1 = abs(-100);//L
- //TA1CCR1 = abs(256/2);//R
-
- P4OUT ^=BIT7;
-
-
- // delay(10);
- }
-
- }
- void OledDisApp(void)
- {
- #if 1
- if(Angle < 0.0)
- {
- //sprintf
- OLED_ShowChar(32, 2, '-', 16);
- }
- else
- {
- OLED_ShowChar(32, 2, ' ', 16);
- }
- OLED_ShowNum(32+8, 2, abs(Angle), 3, 16);
- OLED_ShowNum(32+8, 5, speedcar/2, 3, 16);
- #endif
- //================Speed====================
- #if 0
- if(Speed < 0.0)
- {
- //sprintf
- OLED_ShowChar(50, 2, '-', 16);
- }
- else
- {
- OLED_ShowChar(50, 2, ' ', 16);
- }
- OLED_ShowNum(50+8, 2, abs(Speed), 3, 16);
- #endif
- //fillRect(124, 64/2, 2, -63, 1,1);
-
- }
復(fù)制代碼
|
|