This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSP430FR4133:伺服电机代码帮助

Guru**** 1111390 points
Other Parts Discussed in Thread: MSP430FR4133
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1329743/msp430fr4133-help-with-servo-motor-code

器件型号:MSP430FR4133

您好!

我正在尝试将伺服电机(sg90)实现到 MSP430的电位器中。 我希望伺服电机由电位器控制、即转动电位器将使电机旋转。 我有 ADC 代码、但我正在努力处理实现此代码所需的其他代码。 非常感谢您提供任何帮助。 非常感谢!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我想您的意思是 A/D、而不是"电位器"。

    对于伺服、您需要将 PWM 设置为特定的频率并调整占空比。 您能向我们展示您拥有的产品吗? 我们不想为您做家庭作业。

    尝试 timer_a_ex4_pwmMultipleUpDown 示例。

    下面是伺服教程:

    https://learn.sparkfun.com/tutorials/basic-servo-control-for-beginners/servo-motor-basics

    对于伺服驱动器、您需要20毫秒的周期和从5%(1ms 脉冲)到10%(2ms 脉冲)不等的占空比

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Bilal:

    不确定您想从 MSP430输出什么内容。

    如果是数字信号、则可以接受 Keith 的建议。

    如果是模拟信号、则该器件不能巧妙地输出模拟电压(DAC)。 也许您可以输出 PWM 信号来模拟一个模拟信号。

    B.R.

    萨尔

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    伺服是接收特定 PWM 信号以将电机设置到特定位置的电机。 在这种情况下, 重复率为20ms 的7.5ms 脉冲用于将伺服设置到其零位置。 调整占空比可设置不同的位置。 它们广泛应用于小型无线电控制车辆。

    我建议你去 SparkFun,买一个,玩它很有趣。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢 Keith 的介绍、我 得到了伺服是什么。  电位器看起来就像电压输出、让我很困惑。

    B.R.

    萨尔

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    他没有说清楚。 我认为这是初学者的家庭作业、它取电位器的位置、并通过 ADC 读数和 PWM 占空比的后续设置来设置相应的伺服。

    即闪烁的伺服电机等效值。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Keith、对我来说、情景很有意义。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Keith、感谢您的回复。 这是我的代码现在看起来的样子、我不确定如何调整它。  

    #包含
    #包含
    #包含

    void configureADC()
    {
    //ADC 设置
    SYSCFG2 |= ADCPCTL9;//打开模拟引脚9,使其不是 GPIO

    ADCCTL0 |= ADCON;//打开 ADC
    ADCCTL1 |= ADCSHP;//选择位9
    ADCCTL1 |= ADCSSEL_2;//选择 SMCLK

    ADCCTL2 |= ADCRES_2;//时钟分辨率


    ADCMCTL0 |= ADCSREF_7;//+ve 和-ve 基准引脚
    ADCMCTL0 |= ADCINCH_9;// A9作为输入

    ADCIFG &&~0x01;//清除中断标志
    ADCIE |= ADCIE0;//启用 ADC 转换完成中断

    void initPWM(){
    TA0CCTL1 = OUTMOD_7;// CCR1复位/设置
    TA0CTL = TASSEL_2 + MC_1 + TACLR;// SMCLK、向上计数模式、清除 TAR
    TA0CCR0 = 20000-1;// 20ms (50Hz)的 PWM 周期
    TA0CCR1 = 1000;// 1ms 脉冲的初始占空比

    P1DIR |= BIT2;// P1.2作为 PWM 的输出
    P1SEL0 |= BIT2;// P1.2选项选择

    void main (void){
    WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器
    configureADC ();//设置 ADC
    initPWM ();//设置伺服的 PWM

    __ bis_SR_register (GIE);//启用全局中断以启动 ADC

    while (1){
    ADCCTL0 |= ADCENC | ADCSC;//开始采样/转换
    __ bis_SR_register (LPM0_bits + GIE);//进入 LPM0、ADC_ISR 将强制退出

    // ADC 中断服务例程
    #pragma vector=adc_vector
    __interrupt void ADC_ISR (void){
    if (ADCIFG & ADCIFG0){//检查转换是否完成
    unsigned int adcValue = ADCMEM0;//获取 ADC 转换结果
    无符号 int dutyCycle = 1000 +(adcValue * 1000 / 4095);//将 ADC 值映射到占空比范围
    TA0CCR1 =占空比;//更新 PWM 占空比以调整伺服位置
    ADCIFG &&~ADCIFG0;//清除中断标志
    __ bic_SR_register_on_exit (LPM0_bits);//退出 LPM0

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    正在发生或未发生什么情况?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我想让电机旋转、但在旋转 MSP430上的 A/D 时没有发生任何情况。 我还将其连接到了5V 电源、因此我不确定它为什么不工作。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您是否具有示波器?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    一个问题是1.2并未连接到定时器、它被 USCI 使用。

    您需要使用1.6或1.7、如示例所示:

    //
    //          MSP430FR4133
    //-------------------------------------------------------         
    //    /|\|               
    //     |||               
    //     --|RST           |
    //       |               
    //       |    P1.7/TA0.1|--> CCR1 - 75% PWM
    //       |    P1.6/TA0.2|--> CCR2 - 25% PWM
    //

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的回复、我做了这些更改、是的、我有范围

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这是我的代码现在看起来的样子:  

    #包含
    #包含
    #包含

    void configureADC(){
    // ADC 设置
    SYSCFG2 |= ADCPCTL9;//为 ADC 输入启用 A9

    ADCCTL0 |= ADCON;//打开 ADC
    ADCCTL1 |= ADCSHP;//采样保持脉冲模式选择
    ADCCTL1 |= ADCSSEL_2;// SMCLK 作为 ADC 时钟源
    ADCCTL2 |= ADCRES_2;// 12位转换结果

    ADCMCTL0 |= ADCSREF_7;//基准电压为 V (R+)= VREF+和 V (R-)= VREF-
    ADCMCTL0 |= ADCINCH_9;// A9作为输入

    ADCIFG &&~0x01;//清除中断标志
    ADCIE |= ADCIE0;//启用 ADC 转换完成中断

    void initPWM(){
    //配置 GPIO
    P1DIR |= BIT7;//将 P1.7设置为输出
    P1SEL0 |= BIT7;//为 P1.7选择 TA0.1选项

    //针对 PWM 的计时器 A0配置
    TA0CCTL1 = OUTMOD_7;// CCR1复位/设置
    TA0CTL = TASSEL_2 + MC_1 + TACLR;// SMCLK、向上计数模式、清除 TAR
    TA0CCR0 = 20000-1;// PWM 周期:20ms (对于50Hz)
    TA0CCR1 = 1500;//开始使用中性占空比(例如、在1.5ms 脉宽下为~7.5%)

    //注意:根据 ADC_ISR 中的 ADC 读数调整 TA0CCR1值

    void main (void){
    WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器
    configureADC ();//设置 ADC
    initPWM ();//设置伺服的 PWM

    __ bis_SR_register (GIE);//启用全局中断以启动 ADC

    while (1){
    ADCCTL0 |= ADCENC | ADCSC;//开始采样/转换
    __ bis_SR_register (LPM0_bits + GIE);//进入 LPM0、ADC_ISR 将强制退出

    // ADC 中断服务例程
    #pragma vector=adc_vector
    __interrupt void ADC_ISR (void){
    if (ADCIFG & ADCIFG0){//检查转换是否完成
    unsigned int adcValue = ADCMEM0;//获取 ADC 转换结果
    //将 ADC 值映射到 PWM 占空比范围(对于5%、为1000到10%)
    无符号 int dutyCycle = 1000 +(adcValue * 1000/4095);
    TA0CCR1 =占空比;//更新 PWM 占空比以调整伺服位置
    ADCIFG &&~ADCIFG0;//清除中断标志
    __ bic_SR_register_on_exit (LPM0_bits);//退出 LPM0

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    unsigned int dutyCycle = 1000 +(adcValue * 1000/4095);

    FR4133具有一个10位 ADC。 此外、乘法极有可能会溢出。 总体结果是您相对于1000的偏移(完全正确?) 电流将在非常小的范围内变化。 您可以在以下方面做得更好:

    > unsigned int dutyCycle = 1000 +(adcValue * 1000UL/1024);

    ----------------

    > ADCMCTL0 |= ADCSREF_7;//基准电压为 V (R+)= VREF+和 V (R-)= VREF-

    我预计您没有连接外部 VREF 引脚、因此我不确定结果会是什么。 SREF= 0 (VCC)或=1 (内部 VREF)可能会获得更好的结果。

    ----------------

    你设置(省略) ADCSHT=0,这是一个很短的时间,特别是来自电阻分压器电路——它们通常具有很高的阻抗。 您没有太着急、于是将 ADCSHT 设置为相当大的值、例如、

    > ADCCTL0 |= ADCSHT_6;  // 128个 ADC 采样/保持时钟

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我只有2311可用、但此代码有效-我更改了数字、以获得您的20ms 周期。

    这是 MSP430fr231X_tb0_16示例。

    我建议您从一个简单的 PWM 示例开始、以便在连接 ADC 之前使其正常工作。

    (噢、请使用代码插入工具使您的代码可读)

    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;                 // Stop WDT
    
        P1DIR |= BIT6 | BIT7;                     // P1.6 and P1.7 output
        P1SEL1 |= BIT6 | BIT7;                    // P1.6 and P1.7 options select
        
        // Disable the GPIO power-on default high-impedance mode to activate
        // previously configured port settings
        PM5CTL0 &= ~LOCKLPM5;
    
        TB0CCR0 = 20000;                         // PWM Period
        TB0CCTL1 = OUTMOD_7;                      // CCR1 reset/set
        TB0CCR1 = 15000;                            // CCR1 PWM duty cycle
        TB0CCTL2 = OUTMOD_7;                      // CCR2 reset/set
        TB0CCR2 = 5000;                            // CCR2 PWM duty cycle
        TB0CTL = TBSSEL__SMCLK | MC__UP | TBCLR;  // SMCLK, up mode, clear TBR
    
        __bis_SR_register(LPM0_bits);             // Enter LPM0
        __no_operation();                         // For debugger
    }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    非常感谢各位、感谢你们的时间和耐心-我来试试、希望它能起作用。 加油打气