[MSP-EXP432P401R] MSP432P401R矩阵按键控制SG90舵机云台

  [复制链接]

12

主题

49

帖子

1382

积分

单晶硅锭

Rank: 3Rank: 3

积分
1382
楼主
查看: 6650回复: 2 发表于 2021-4-23 11:03:56   只看该作者
第4题:电机/舵机相关(问的同学挺多的,先增加这个内容)
1.常见的控制/调速/测速等
2.完整的硬件图片、效果图片
3.引脚连接图等电路图(如板卡和显示板的连接示意图)
4.驱动芯片的手册资料等信息


1.硬件
2.SG90舵机介绍
3.硬件连接
4.效果说明
5.代码
6.工程文件及舵机资料

1.硬件
开发板:    MSP432P401R LaunchPad
矩阵按键:4X4键盘

舵机:       SG90舵机云台


2.SG90舵机介绍

3.硬件连接
*                MSP432P401R
*              ------------------
*         /|\|                            |
*           | |                            |
*          --|RST                      |
*             |                            |
*    舵机  |                            |     矩阵按键
*            |                    P1.6  |<--  C4
*            |                    P1.7  |<--  C3
*            |                    P6.7  |<--  C2
*            |                    P2.3  |<--  C1
*            |                    P6.6  |<--  R1
* 橙线<-|P2.4             P5.1  |<--  R2
* 红线<-|5V                P5.2  |<--  R3
* 棕线<-|GND            P5.6  |<--  R4

4.效果说明
* 从超声波模块背面向正面看,为舵机的正前方,来判断舵机的左转、右转情况
* 功能描述:初始状态,舵机面向正前方,
* 舵机的控制信号为周期20ms的PWM波,
* 脉冲宽度从0.5ms~2.5ms,相对舵盘+90°~-90°呈线性变化。
* 以下为矩阵按键按下对应舵机变化:
*        S1                  S2                          S3                             S4
*      左转45°       左转22.5°                 右转22.5°                  右转45°
*
*        S5                  S6                          S7                              S8
*      左转67.5°     正对前方                  正对前方                    右转67.5°
*
*        S9                  S10                        S11                            S12
*      左转90°       一直左转                  一直右转                      右转90°
*
*        S13                S14                        S15                            S16
*      左转112.5°      不动                        不动                          右转112.5°
*
* 按下独立按键S1,PWM占空比+0.625%,舵机左转+11.25°


正对前方


左转45°


左转90°


右转45°


右转90°


停止不动


5.代码
开发环境:CCS10.1.1
  1. #include <ti/devices/msp432p4xx/driverlib/driverlib.h>

  2. #include <stdint.h>
  3. #include <stdbool.h>

  4. //![单通道Timer_A 配置]
  5. // Timer_A PWM 配置参数
  6. Timer_A_PWMConfig pwmConfig =
  7. {
  8.         TIMER_A_CLOCKSOURCE_SMCLK,
  9.         TIMER_A_CLOCKSOURCE_DIVIDER_1,
  10.         1280,                                //64kHz时钟源,1280大约20ms
  11.         TIMER_A_CAPTURECOMPARE_REGISTER_1,
  12.         TIMER_A_OUTPUTMODE_RESET_SET,
  13.         96                                   //大约1.5ms,舵机正对正前方
  14. };
  15. //![单通道Timer_A 配置]

  16. #define HighC1   {MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN3);}    //第1列C1输出高电平
  17. #define LowC1    {MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN3);}     //第1列C1输出低电平
  18. #define HighC2   {MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P6, GPIO_PIN7);}    //第2列C2输出高电平
  19. #define LowC2    {MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P6, GPIO_PIN7);}     //第2列C2输出低电平
  20. #define HighC3   {MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN7);}    //第3列C3输出高电平
  21. #define LowC3    {MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN7);}     //第3列C3输出低电平
  22. #define HighC4   {MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN6);}    //第4列C4输出高电平
  23. #define LowC4    {MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN6);}     //第4列C4输出低电平

  24. int main(void)
  25. {

  26.                                                           //配置列信号作为输出
  27.     MAP_GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN3);     //第1列C1
  28.     MAP_GPIO_setAsOutputPin(GPIO_PORT_P6, GPIO_PIN7);     //第2列C2
  29.     MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN7);     //第3列C3
  30.     MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN6);     //第4列C4

  31.     //所有列输出低电平
  32.     LowC1;
  33.     LowC2;
  34.     LowC3;
  35.     LowC4;

  36.     //配置第1行R1--P6.6为上拉电阻输入并使能中断
  37.     MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P6, GPIO_PIN6);
  38.     MAP_GPIO_clearInterruptFlag(GPIO_PORT_P6, GPIO_PIN6);
  39.     MAP_GPIO_enableInterrupt(GPIO_PORT_P6, GPIO_PIN6);
  40.     MAP_Interrupt_enableInterrupt(INT_PORT6);

  41.     //配置第2行R2--P5.1为上拉电阻输入并使能中断
  42.     MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P5, GPIO_PIN1);
  43.     MAP_GPIO_clearInterruptFlag(GPIO_PORT_P5, GPIO_PIN1);
  44.     MAP_GPIO_enableInterrupt(GPIO_PORT_P5, GPIO_PIN1);

  45.     //配置第3行R3--P5.2为上拉电阻输入并使能中断
  46.     MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P5, GPIO_PIN2);
  47.     MAP_GPIO_clearInterruptFlag(GPIO_PORT_P5, GPIO_PIN2);
  48.     MAP_GPIO_enableInterrupt(GPIO_PORT_P5, GPIO_PIN2);

  49.     //配置第4行R4--P5.6为上拉电阻输入并使能中断
  50.     MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P5, GPIO_PIN6);
  51.     MAP_GPIO_clearInterruptFlag(GPIO_PORT_P5, GPIO_PIN6);
  52.     MAP_GPIO_enableInterrupt(GPIO_PORT_P5, GPIO_PIN6);
  53.     MAP_Interrupt_enableInterrupt(INT_PORT5);

  54.     //关闭看门狗
  55.     MAP_WDT_A_holdTimer();

  56.     //![单通道Timer_A 配置]
  57.     //配置   MCLK to REFO at 128Khz for LF mode
  58.     //配置 SMCLK to 64Khz
  59.     MAP_CS_setReferenceOscillatorFrequency(CS_REFO_128KHZ);
  60.     MAP_CS_initClockSignal(CS_MCLK, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1);
  61.     MAP_CS_initClockSignal(CS_SMCLK, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_2);
  62.     MAP_PCM_setPowerState(PCM_AM_LF_VCORE0);

  63.     //配置 GPIO2.4 为PWM外围输出, P1.1 为按键中断
  64.     MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2, GPIO_PIN4,
  65.             GPIO_PRIMARY_MODULE_FUNCTION);
  66.     MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1);
  67.     MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN1);
  68.     MAP_GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN1);

  69.     //配置Timer_A 周期大约 20ms ,初始占空比为  7.5% ( 96  ),舵机正对正前方
  70.     MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig);
  71.     //![单通道 Timer_A 例子]

  72.     //使能中断并开启看门狗定时器
  73.     MAP_Interrupt_enableInterrupt(INT_PORT1);
  74.     MAP_Interrupt_enableSleepOnIsrExit();
  75.     MAP_Interrupt_enableMaster();

  76.    //Enabling SRAM Bank Retention
  77.     MAP_SysCtl_enableSRAMBankRetention(SYSCTL_SRAM_BANK1);

  78.     //使能全局中断
  79.     MAP_Interrupt_enableMaster();

  80.     //进入睡眠模式,中断唤醒
  81.     while (1)
  82.     {
  83.         MAP_PCM_gotoLPM0();
  84.     }
  85. }


  86. /* GPIO中断服务程序  */
  87. /* 在中断中进行列扫描判断哪个按键按下,中断结束将所有列置为0,方便下一次进入中断。 */
  88. void PORT5_IRQHandler(void)
  89. {
  90.     uint32_t status1;                                //设置一个状态标志量,寄存中断情况
  91.     status1 = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P5);
  92.     MAP_GPIO_clearInterruptFlag(GPIO_PORT_P5, status1);           //清零所有中断标志位

  93.     //判断第一列按键是否按下,按下输入为0
  94.     LowC1;
  95.     HighC2;
  96.     HighC3;
  97.     HighC4;
  98.     if(!(MAP_GPIO_getInputPinValue(GPIO_PORT_P5, GPIO_PIN1))  )             //S5按下
  99.     {
  100.         pwmConfig.dutyCycle = 144;
  101.         MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig);                 //大约2.25ms,占空比为11.25%,舵机左转67.5°
  102.     }
  103.     else if(!(MAP_GPIO_getInputPinValue(GPIO_PORT_P5, GPIO_PIN2))  )        //S9按下
  104.     {
  105.         pwmConfig.dutyCycle = 160;
  106.         MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig);                 //大约2.5ms,占空比为12.5%,舵机左转90°
  107.     }
  108.     else if(!(MAP_GPIO_getInputPinValue(GPIO_PORT_P5, GPIO_PIN6))  )        //S13按下
  109.     {
  110.         pwmConfig.dutyCycle = 175;
  111.         MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig);                 //大约2.73ms,占空比为13.7%,舵机左转112.5°
  112.     }

  113.     //判断第二列按键是否按下,按下输入为0
  114.     HighC1;
  115.     LowC2;
  116.     HighC3;
  117.     HighC4;
  118.     if(!(MAP_GPIO_getInputPinValue(GPIO_PORT_P5, GPIO_PIN1))  )             //S6按下
  119.     {
  120.         pwmConfig.dutyCycle = 96;
  121.         MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig);                 //大约1.5ms,占空比为7.5%,舵机正对正前方
  122.     }
  123.     else if(!(MAP_GPIO_getInputPinValue(GPIO_PORT_P5, GPIO_PIN2))  )        //S10按下
  124.     {
  125.         pwmConfig.dutyCycle = 180;
  126.         MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig);                 //大约2.8ms,占空比为14.1%,舵机一直左转
  127.     }
  128.     else if(!(MAP_GPIO_getInputPinValue(GPIO_PORT_P5, GPIO_PIN6))  )        //S14按下
  129.     {
  130.         pwmConfig.dutyCycle = 0;
  131.         MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig);                 //0ms,占空比为0%,舵机不动
  132.     }

  133.     //判断第三列按键是否按下,按下输入为0
  134.     HighC1;
  135.     HighC2;
  136.     LowC3;
  137.     HighC4;
  138.     if(!(MAP_GPIO_getInputPinValue(GPIO_PORT_P5, GPIO_PIN1))  )            //S7按下
  139.     {
  140.         pwmConfig.dutyCycle = 96;
  141.         MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig);                //大约1.5ms,占空比为7.5%,舵机正对正前方
  142.     }
  143.     else if(!(MAP_GPIO_getInputPinValue(GPIO_PORT_P5, GPIO_PIN2)) )        //S11按下
  144.     {
  145.         pwmConfig.dutyCycle = 10;
  146.         MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig);                 //大约0.156ms,占空比为0.78%,舵机一直右转
  147.     }
  148.     else if(!(MAP_GPIO_getInputPinValue(GPIO_PORT_P5, GPIO_PIN6)) )        //S15按下
  149.     {
  150.         pwmConfig.dutyCycle = 0;
  151.         MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig);                 //0ms,占空比为0%,舵机不动
  152.     }

  153.     //判断第四列按键是否按下,按下输入为0
  154.     HighC1;
  155.     HighC2;
  156.     HighC3;
  157.     LowC4;
  158.     if(!(MAP_GPIO_getInputPinValue(GPIO_PORT_P5, GPIO_PIN1)) )             //S8按下
  159.     {
  160.         pwmConfig.dutyCycle = 48;
  161.         MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig);                 //大约0.75ms,占空比为3.75%,舵机右转67.5°
  162.     }
  163.     else if(!(MAP_GPIO_getInputPinValue(GPIO_PORT_P5, GPIO_PIN2)) )        //S12按下
  164.     {
  165.         pwmConfig.dutyCycle = 32;
  166.         MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig);                 //大约0.5ms,占空比为2.5%,舵机右转90°
  167.     }
  168.     else if(!(MAP_GPIO_getInputPinValue(GPIO_PORT_P5, GPIO_PIN6)) )        //S16按下
  169.     {
  170.         pwmConfig.dutyCycle = 16;
  171.         MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig);                 //大约0.25ms,占空比为1.25%,舵机右转112.5°
  172.     }

  173.     //所有列置0,方便下一次进入中断
  174.     LowC1;
  175.     LowC2;
  176.     LowC3;
  177.     LowC4;
  178. }

  179. void PORT6_IRQHandler(void)
  180. {
  181.     uint32_t status2;                               //设置一个状态标志量,寄存中断情况
  182.     status2 = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P6);
  183.     MAP_GPIO_clearInterruptFlag(GPIO_PORT_P6, status2);           //清零所有中断标志位

  184.     //判断第一列按键是否按下,按下输入为0
  185.     LowC1;
  186.     HighC2;
  187.     HighC3;
  188.     HighC4;
  189.     if(!(MAP_GPIO_getInputPinValue(GPIO_PORT_P6, GPIO_PIN6))  )        //S1按下
  190.     {
  191.         pwmConfig.dutyCycle = 128;
  192.         MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig);                 //大约2ms,占空比为10%,舵机左转45°
  193.     }

  194.     //判断第二列按键是否按下,按下输入为0
  195.     HighC1;
  196.     LowC2;
  197.     HighC3;
  198.     HighC4;
  199.     if(!(MAP_GPIO_getInputPinValue(GPIO_PORT_P6, GPIO_PIN6))  )        //S2按下
  200.     {
  201.         pwmConfig.dutyCycle = 112;
  202.         MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig);                 //大约1.75ms,占空比为8.75%,舵机左转22.5°
  203.     }

  204.     //判断第三列按键是否按下,按下输入为0
  205.     HighC1;
  206.     HighC2;
  207.     LowC3;
  208.     HighC4;
  209.     if(!(MAP_GPIO_getInputPinValue(GPIO_PORT_P6, GPIO_PIN6)) )        //S3按下
  210.     {
  211.         pwmConfig.dutyCycle = 80;
  212.         MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig);                 //大约1.25ms,占空比为6.25%,舵机右转22.5°
  213.     }

  214.     //判断第四列按键是否按下,按下输入为0
  215.     HighC1;
  216.     HighC2;
  217.     HighC3;
  218.     LowC4;
  219.     if(!(MAP_GPIO_getInputPinValue(GPIO_PORT_P6, GPIO_PIN6)) )        //S4按下
  220.     {
  221.         pwmConfig.dutyCycle = 64;
  222.         MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig);                 //大约1ms,占空比为5%,舵机右转45°
  223.     }

  224.     //所有列置0,方便下一次进入中断
  225.     LowC1;
  226.     LowC2;
  227.     LowC3;
  228.     LowC4;
  229. }

  230. //每按一次S1按键,高电平所占时间大约+0.125ms,占空比+0.625%,舵机左转+11.25°
  231. void PORT1_IRQHandler(void)
  232. {
  233.     uint32_t status3 = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P1);
  234.     MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, status3);

  235.     if (status3 & GPIO_PIN1)
  236.     {
  237.         if(pwmConfig.dutyCycle >= 200)               //超过3.125ms,占空比超过15.625%,占空比清零
  238.             pwmConfig.dutyCycle = 0;
  239.         else
  240.             pwmConfig.dutyCycle += 8;                 //每按一次S1按键,大约+0.125ms,占空比+0.625%,舵机左转+11.25°

  241.         MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig);
  242.     }
  243. }
复制代码



6.工程文件及舵机资料
CCS工程和SG90舵机资料.zip (2.15 MB, 下载次数: 120)


打赏

参与人数 14赫兹币 +70 收起 理由
hu158 + 5
fu188 + 5
mei187 + 5
PIDqqq + 5
lithiumice + 5 赞一个!
辜浩珉 + 5 赞一个!
zombiejbt + 5
hw123456 + 5
RHAnthony + 5
csj0710 + 5
blueblues + 5
JTao + 5 很给力!
shenweizuibang + 5 很给力!
bly + 5 很给力!

查看全部打赏

73

主题

469

帖子

1007

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1007
沙发
发表于 2021-4-27 14:15:27   只看该作者
感谢分享

1

主题

12

帖子

1

积分

一粒轻沙

Rank: 1

积分
1
板凳
发表于 2021-10-30 20:05:34   只看该作者
OPENCV-OPENCV-
快速回复 返回顶部 返回列表