找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8873|回复: 14
打印 上一主题 下一主题
收起左侧

MSP430f5529小车源码

  [复制链接]
跳转到指定楼层
楼主
ID:138313 发表于 2020-10-11 17:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
https://www.bilibili.com/video/BV1Jz4y1o7Lv/

单片机源程序如下:
  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. #include <msp430.h>
  24. #include <stdint.h>
  25. #include <stdbool.h>
  26. //#include "oledfont.h"
  27. //#include "msp430f5529.h"
  28. #include "MPU6050.h"
  29. #include "uart.h"
  30. #include "exter_interr.h"
  31. #include "pwm.h"
  32. #include "time.h"
  33. #include "hardw_i2c_oled.h"
  34. #include "mathfun.h"
  35. #include "xunji.h"

  36. void OledDisApp(void);

  37. void delay(unsigned int z)
  38. {
  39.   unsigned int x,y;
  40.   for(x=z;x>0;x--)
  41.     for(y=5000;y>0;y--);
  42. }


  43. //******************************************************************************
  44. // Device Initialization *******************************************************
  45. //******************************************************************************

  46. void initClockTo16MHz()
  47. {
  48.     UCSCTL3 |= SELREF_2;                      // Set DCO FLL reference = REFO
  49.     UCSCTL4 |= SELA_2;                        // Set ACLK = REFO
  50.     __bis_SR_register(SCG0);                  // Disable the FLL control loop
  51.     UCSCTL0 = 0x0000;                         // Set lowest possible DCOx, MODx
  52.     UCSCTL1 = DCORSEL_5;                      // Select DCO range 16MHz operation
  53.     UCSCTL2 = FLLD_0 + 487;                   // Set DCO Multiplier for 16MHz
  54.                                               // (N + 1) * FLLRef = Fdco
  55.                                               // (487 + 1) * 32768 = 16MHz
  56.                                               // Set FLL Div = fDCOCLK
  57.     __bic_SR_register(SCG0);                  // Enable the FLL control loop

  58.     // Worst-case settling time for the DCO when the DCO range bits have been
  59.     // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
  60.     // UG for optimization.
  61.     // 32 x 32 x 16 MHz / 32,768 Hz = 500000 = MCLK cycles for DCO to settle
  62.     __delay_cycles(500000);//
  63.     // Loop until XT1,XT2 & DCO fault flag is cleared
  64.     do
  65.     {
  66.         UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags
  67.         SFRIFG1 &= ~OFIFG;                          // Clear fault flags
  68.     }while (SFRIFG1&OFIFG);                         // Test oscillator fault flag
  69. }
  70. uint16_t setVCoreUp(uint8_t level){
  71.     uint32_t PMMRIE_backup, SVSMHCTL_backup, SVSMLCTL_backup;

  72.     //The code flow for increasing the Vcore has been altered to work around
  73.     //the erratum FLASH37.
  74.     //Please refer to the Errata sheet to know if a specific device is affected
  75.     //DO NOT ALTER THIS FUNCTION

  76.     //Open PMM registers for write access
  77.     PMMCTL0_H = 0xA5;

  78.     //Disable dedicated Interrupts
  79.     //Backup all registers
  80.     PMMRIE_backup = PMMRIE;
  81.     PMMRIE &= ~(SVMHVLRPE | SVSHPE | SVMLVLRPE |
  82.                 SVSLPE | SVMHVLRIE | SVMHIE |
  83.                 SVSMHDLYIE | SVMLVLRIE | SVMLIE |
  84.                 SVSMLDLYIE
  85.                 );
  86.     SVSMHCTL_backup = SVSMHCTL;
  87.     SVSMLCTL_backup = SVSMLCTL;

  88.     //Clear flags
  89.     PMMIFG = 0;

  90.     //Set SVM highside to new level and check if a VCore increase is possible
  91.     SVSMHCTL = SVMHE | SVSHE | (SVSMHRRL0 * level);

  92.     //Wait until SVM highside is settled
  93.     while((PMMIFG & SVSMHDLYIFG) == 0)
  94.     {
  95.         ;
  96.     }

  97.     //Clear flag
  98.     PMMIFG &= ~SVSMHDLYIFG;

  99.     //Check if a VCore increase is possible
  100.     if((PMMIFG & SVMHIFG) == SVMHIFG)
  101.     {
  102.         //-> Vcc is too low for a Vcore increase
  103.         //recover the previous settings
  104.         PMMIFG &= ~SVSMHDLYIFG;
  105.         SVSMHCTL = SVSMHCTL_backup;

  106.         //Wait until SVM highside is settled
  107.         while((PMMIFG & SVSMHDLYIFG) == 0)
  108.         {
  109.             ;
  110.         }

  111.         //Clear all Flags
  112.         PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG |
  113.                      SVMLVLRIFG | SVMLIFG |
  114.                      SVSMLDLYIFG
  115.                      );

  116.         //Restore PMM interrupt enable register
  117.         PMMRIE = PMMRIE_backup;
  118.         //Lock PMM registers for write access
  119.         PMMCTL0_H = 0x00;
  120.         //return: voltage not set
  121.         return false;
  122.     }

  123.     //Set also SVS highside to new level
  124.     //Vcc is high enough for a Vcore increase
  125.     SVSMHCTL |= (SVSHRVL0 * level);

  126.     //Wait until SVM highside is settled
  127.     while((PMMIFG & SVSMHDLYIFG) == 0)
  128.     {
  129.         ;
  130.     }

  131.     //Clear flag
  132.     PMMIFG &= ~SVSMHDLYIFG;

  133.     //Set VCore to new level
  134.     PMMCTL0_L = PMMCOREV0 * level;

  135.     //Set SVM, SVS low side to new level
  136.     SVSMLCTL = SVMLE | (SVSMLRRL0 * level) |
  137.                SVSLE | (SVSLRVL0 * level);

  138.     //Wait until SVM, SVS low side is settled
  139.     while((PMMIFG & SVSMLDLYIFG) == 0)
  140.     {
  141.         ;
  142.     }

  143.     //Clear flag
  144.     PMMIFG &= ~SVSMLDLYIFG;
  145.     //SVS, SVM core and high side are now set to protect for the new core level

  146.     //Restore Low side settings
  147.     //Clear all other bits _except_ level settings
  148.     SVSMLCTL &= (SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 +
  149.                  SVSMLRRL1 + SVSMLRRL2
  150.                  );

  151.     //Clear level settings in the backup register,keep all other bits
  152.     SVSMLCTL_backup &=
  153.         ~(SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2);

  154.     //Restore low-side SVS monitor settings
  155.     SVSMLCTL |= SVSMLCTL_backup;

  156.     //Restore High side settings
  157.     //Clear all other bits except level settings
  158.     SVSMHCTL &= (SVSHRVL0 + SVSHRVL1 +
  159.                  SVSMHRRL0 + SVSMHRRL1 +
  160.                  SVSMHRRL2
  161.                  );

  162.     //Clear level settings in the backup register,keep all other bits
  163.     SVSMHCTL_backup &=
  164.         ~(SVSHRVL0 + SVSHRVL1 + SVSMHRRL0 + SVSMHRRL1 + SVSMHRRL2);

  165.     //Restore backup
  166.     SVSMHCTL |= SVSMHCTL_backup;

  167.     //Wait until high side, low side settled
  168.     while(((PMMIFG & SVSMLDLYIFG) == 0) &&
  169.           ((PMMIFG & SVSMHDLYIFG) == 0))
  170.     {
  171.         ;
  172.     }

  173.     //Clear all Flags
  174.     PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG |
  175.                 SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG
  176.                 );

  177.     //Restore PMM interrupt enable register
  178.     PMMRIE = PMMRIE_backup;

  179.     //Lock PMM registers for write access
  180.     PMMCTL0_H = 0x00;

  181.     return true;
  182. }
  183. bool increaseVCoreToLevel2()
  184. {
  185.     uint8_t level = 2;
  186.     uint8_t actlevel;
  187.     bool status = true;

  188.     //Set Mask for Max. level
  189.     level &= PMMCOREV_3;

  190.     //Get actual VCore
  191.     actlevel = PMMCTL0 & PMMCOREV_3;

  192.     //step by step increase or decrease
  193.     while((level != actlevel) && (status == true))
  194.     {
  195.         if(level > actlevel)
  196.         {
  197.             status = setVCoreUp(++actlevel);
  198.         }
  199.     }

  200.     return (status);
  201. }

  202. void initGPIO()
  203. {
  204.     //I2C Pins
  205.     P3SEL |= BIT0 + BIT1;                     // P3.0,1 option select
  206.    
  207.     P1DIR |=BIT0;
  208.     P4DIR |=BIT7;
  209.     //按键输入
  210.     P2DIR &=~BIT1;
  211.     P1DIR &=~BIT1;
  212.    
  213.     P2REN |= BIT1;//使能上下拉
  214.     P2OUT |= BIT1;//上拉
  215.    
  216.     P1REN |= BIT1;//使能上下拉
  217.     P1OUT |= BIT1;//上拉
  218. }

  219. void initI2C()
  220. {
  221.   
  222.   
  223.     UCB0CTL1 |= UCSWRST;                      // Enable SW reset(复位使能)
  224.     UCB0CTL0 =  UCMST + UCMODE_3 + UCSYNC;     //  Master, I2C,synchronous mode(同步模式)
  225.     UCB0CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep SW reset
  226.     UCB0BR0 = 160;                            // fSCL = SMCLK/160 = ~100kHz
  227.     UCB0BR1 = 0;
  228.     UCB0CTL0 &=~UCSLA10;                      //7位地址模式
  229.     UCB0I2CSA = SLAVE_ADDR>>1; //SlaveAddress>>1;//SLAVE_ADDR>>1;                //  
  230.     UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
  231.    
  232.     UCB0IFG &=~UCTXIFG;
  233.    
  234. }

  235. int num;
  236. int main(void) {

  237.     WDTCTL = WDTPW | WDTHOLD;                 // Stop watchdog timer
  238.     increaseVCoreToLevel2();
  239.     initClockTo16MHz();                        //配置系统时钟为16Mhz
  240.     //delay(10);
  241.     initGPIO();
  242.     initI2C();
  243.     //delay(10);
  244.     OLED_Init();
  245.     //delay(10);
  246.     UART_Init('n',8,1);
  247.     InitMPU6050();
  248.     //delay(10);
  249.     exterPin();//外部引脚中断
  250.     //MotorSpeedDetectionInit();   
  251.     PWMInit();
  252.     TB6612INOUT();
  253.     time0InterInit();
  254.     xunioinit();//寻迹引脚初始化
  255.     delay(10);
  256.     //OLED_ShowChar(0,0,'A',16);
  257.     //OLED_ShowChar(16,0,'B',16);
  258.     //OLED_ShowChar(16*2,0,'C',16);
  259.    
  260.     _EINT();//开启总中断
  261.     //曾经由于没开总中断,调了一下午...
  262.     while(1)
  263.     {
  264.       //按键检测
  265.       if((P2IN & BIT1) == 0)
  266.       {
  267.         delay(3);
  268.         if((P2IN & BIT1) == 0)
  269.         {
  270.           P1OUT ^= BIT0;
  271.         }
  272.         
  273.       //PWM_Motor(-20,-20);
  274.       }
  275.       while(!(P2IN&BIT1));
  276.       
  277.       xunjiing();//寻迹
  278.      
  279.       
  280.   if(count_time >=20)
  281.   {
  282.     count_time =0;
  283.    // P1OUT ^= BIT0;              //形成闪灯效果
  284.    Angle = Mpu6050AccelAngle(ACCEL_XOUT,ACCEL_ZOUT);
  285.    Angle_dot =  Mpu6050GyroAngle(GYRO_YOUT);
  286.   
  287.   // pwm_calculate();//PWM计算输出
  288.      
  289.    
  290.   }
  291.         

  292.   
  293. #if 1
  294.   if(count_time2 >=10)
  295.   {
  296.       count_time2 =0;
  297.       OledDisApp();
  298.    
  299.   }
  300. #endif
  301.   
  302. #if 0
  303.   if(Angle >10.0)
  304.   {
  305.    PWM_Motor(20,20);
  306.   }
  307.   else if(Angle < -10.0)
  308.   {
  309.   PWM_Motor(-20,-20);
  310.   }
  311.   else
  312.   {
  313.   Stop();
  314.   }
  315.   
  316. #endif
  317.   
  318.   
  319.   
  320.   
  321.   //printf ("Pwm = %d \r\n",Pwm);
  322.   
  323.    //
  324.     // OLED_Show_Number(0,6,abs(Angle),16);
  325.      //P1OUT ^=BIT0;
  326.       
  327.      //printf("angle = %1f , angle_dot = %2f \r\n",Angle,Angle_dot);
  328.      //printf("ML = %d , MR = %d \r\n",speed_mL,speed_mR);//打印编码器
  329.       
  330.       
  331.      //PWM_Motor(20,-20);//测试电机,应看到左轮后退,右轮前进
  332.       
  333.       //TA2CCR1 = abs(-100);//L
  334.       //TA1CCR1 = abs(256/2);//R
  335.       
  336.      P4OUT ^=BIT7;
  337.      
  338.      
  339.    // delay(10);
  340.     }
  341.    
  342. }
  343. void OledDisApp(void)
  344. {
  345. #if 1
  346. if(Angle < 0.0)
  347. {   
  348. //sprintf
  349. OLED_ShowChar(32, 2,  '-', 16);
  350. }
  351. else
  352. {
  353. OLED_ShowChar(32, 2, ' ', 16);
  354. }
  355. OLED_ShowNum(32+8, 2, abs(Angle), 3, 16);
  356. OLED_ShowNum(32+8, 5, speedcar/2, 3, 16);
  357. #endif
  358. //================Speed====================
  359. #if 0
  360. if(Speed < 0.0)
  361. {   
  362. //sprintf
  363. OLED_ShowChar(50, 2,  '-', 16);
  364. }
  365. else
  366. {
  367. OLED_ShowChar(50, 2, ' ', 16);
  368. }
  369. OLED_ShowNum(50+8, 2, abs(Speed), 3, 16);
  370. #endif

  371. //fillRect(124, 64/2, 2, -63, 1,1);

  372.   
  373.   }
复制代码


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏7 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:138313 发表于 2020-10-11 22:52 | 只看该作者
使用FDC2214寻迹效果更佳
回复

使用道具 举报

板凳
ID:828564 发表于 2020-10-12 01:07 | 只看该作者
开发环境是ccs吗?
回复

使用道具 举报

地板
ID:596548 发表于 2020-10-12 01:48 | 只看该作者
大佬有接线图吗,I2C不是很看得懂,不会接线???
ball ball you。。。。。
回复

使用道具 举报

5#
ID:618513 发表于 2020-10-12 05:51 | 只看该作者
楼主拿过来接上线就能跑哇
回复

使用道具 举报

6#
ID:755986 发表于 2020-10-12 17:20 | 只看该作者
沐浴 发表于 2020-10-12 05:51
楼主拿过来接上线就能跑哇

大哥,求接线
回复

使用道具 举报

7#
ID:561575 发表于 2021-5-5 11:32 | 只看该作者
这代码不完整
回复

使用道具 举报

8#
ID:692345 发表于 2021-7-12 11:25 | 只看该作者
头文件能否分享
回复

使用道具 举报

9#
ID:954468 发表于 2021-7-18 23:30 | 只看该作者
是用keil开发的吗?
回复

使用道具 举报

10#
ID:954006 发表于 2021-7-20 09:32 | 只看该作者
大佬可以分享一下头文件嘛
回复

使用道具 举报

11#
ID:955079 发表于 2021-7-22 18:39 | 只看该作者
这代码少了个子函数啊,求完整的
回复

使用道具 举报

12#
ID:1039079 发表于 2022-7-15 11:10 | 只看该作者
求完整的代码和接线图,谢谢
回复

使用道具 举报

13#
ID:1039079 发表于 2022-7-25 10:16 | 只看该作者
这个咋接线啊,大佬
回复

使用道具 举报

14#
ID:1038977 发表于 2023-7-21 17:29 | 只看该作者
头文件里的.C文件可以分享吗,否则不能用啊
回复

使用道具 举报

15#
ID:1088853 发表于 2023-7-24 11:29 | 只看该作者
求完整代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表