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.

[参考译文] MSP430FR6989:PWM 作为 DAC

Guru**** 2394075 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/608289/msp430fr6989-pwm-as-dac

器件型号:MSP430FR6989
主题中讨论的其他器件:MSP430G2231

尊敬的所有人:

我是一名新的微控制器编程器、我发现理解微控制器寄存器的工作方式以及如何知道在使用计时器 A0时必须选择哪个引脚和 PINSEL 让我感到非常困惑、 是否有一个表显示了引脚名称及其功能之间的关系、用户指南令我感到困惑、有很多表包含大量引脚和数字、因此我的第一个问题是详细参考、并提供如何使用此微控制器的示例、 我的第二个问题是关于我的代码,我想 通过 ADC 读取9个模拟值,然后我保存了它,并被其他数字(出于某种原因)占用,将它用作9 PWM 的占空比。 此代码的主要目标是读取模拟值、对其进行处理、然后将其转换回模拟 throgh PWM+ RC 滤波器、我不确定我所做的是正确的、我只需读取一个值即可使代码保持简单、以便进行测试:

#include
//#pragma PERSISTENT (FRAM_DATA)
//#include
#define ACLK 0x0100 //计时器 ACLK 源
#define up 0x0010 //计时器启动模式
#define ENABLE_Pins 0xFFFE //需要使用输入和输出
#define ENABLE_Pins 0xFFFE //启用输入和输出
//#define BIT2 0x0F
//volatile uint16_t ADCResults = 0;
void ADC_Setup (void);//用于设置 ADC12外设
const int x1=1;
const int x2=1;
volatile int 乘以_value;

MAIN ()

PM5CTL0 = ENABLE_Pins;//启用输入和输出
P1DIR =BIT0;//将红色 LED 设置为输出


ADC_Setup();//设置 ADC 外设
while (1)

ADC12CTL0 = ADC12CTL0 | ADC12ENC;//启用转换
ADC12CTL0 = ADC12CTL0 | ADC12SC;//开始转换
MPLED_VALUE =(ADC12MEM0);
//P1OUT=MPLICE_VALUE;
如果(乘以_value > 0x800)//如果输入> 1.65V

P1OUT = BIT0;//打开红色 LED

else // else 输入<= 1.65V

P1OUT = 0x00;//关闭红色 LED


P1DIR |= BIT1;// P1.2至输出
P1SEL1 |= BIT1;// P1.2至 TA0.1
// P1SEL2 &=~BIT6;// P1.7至 TA0.1

TA0CCR0 =乘以值;// PWM 周期
TA0CCTL1 = OUTMOD_7;// CCR1复位/置位
TA0CCR1 =倍增值;// CCR1 PWM 占空比
TA0CTL = tassel_2 + MC_1;// SMCLK、向上计数模式

BIS_SR (LPM0_Bits);//输入 LPM0


void ADC_Setup (void)

#define ADC12_SHT_16 0x0200 //采样保持的16个时钟周期
#define ADC12_ON 0x0010 //用于打开 ADC12外设
#define ADC12_SHT_SRC_SEL 0x0200 //选择采样保持源
#define ADC12_12位0x0020 //选择12位分辨率
#define ADC12_P92 0x000A //将输入 P9.2用于模拟输入
#define ADC12_P43 0x000A
#define ADC12_P32 0x000A
#define ADC12_P93 0x000A
#define ADC12_P14 0x000A
#define ADC12_P20 0x000A
#define ADC12_P41 0x000A
ADC12CTL0 = ADC12_SHT_16 | ADC12_ON;//开启,设置采样保持时间
ADC12CTL1 = ADC12_SHT_SRC_SEL;//指定采样保持时钟源
ADC12CTL2 = ADC12_12位;// 12位转换结果
ADC12MCTL0 = ADC12_P92;// P9.2是模拟输入
ADC12MCTL1 = ADC12_P43;

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

    我发现输入/输出图表(数据表的第6.11.24节)对于了解 PxSEL 引脚设置非常有帮助。 例如、P9.2的 A10功能通过 P9SEL1 |= BIT2;& P9SEL1 |= BIT2来选择;TA0.1 PWM 输出通过 P1SEL0 |= BIT66 & P1SEL1 |= BIT6或 P7SEL0 |= BIT2或 BIT6来选择、具体取决于您要使用的引脚。 如果要使用 P1.2、则应配置 TA1、而不是 TA0。

    任何 ADC12MCTLx 寄存器都不应设置为相同的 ADC 输入通道、ADC12CTL1的0x200会更改 ADC12SHP (采样保持脉冲模式选择)位、而不是采样保持源选择(ADC12SHS)、但这一点很重要、因为您使用的是 ADC12SC 位。 您将需要评估 ADC12BUSY 或 ADC12IFG 位、以确保在存储 ADC12MEM0值之前完成转换。

    将 TA0CCR0设置为等于 TA0CCR1将始终产生100%占空比、TA0CCR1应是 TA0CCR0的一小部分。 计时器初始化应存在于 while 循环之外、每次迭代仅更改 TA0CCR1。 您还需要在代码开始时停止看门狗计时器。 请进一步评估 TI 提供的代码示例。

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

    感谢 Ryan 的回复。

    请再次重写您回复的这一部分、"没有 ADC12MCTLx 寄存器应设置为相同的 ADC 输入通道、ADC12CTL1的0x200会更改 ADC12SHP (采样保持脉冲模式选择)位、而不是采样保持源选择(ADC12SHS)、但这一点很重要、因为您使用的是 ADC12SC 位。 您将需要评估 ADC12BUSY 或 ADC12IFG 位、以确保在存储 ADC12MEM0值之前完成转换"  

    我真的没有完全理解它。

    非常感谢您、

    萨利

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

    在上面的代码中、ADC12MCTL0 = ADC12MCTL1 = 0x0A、这是不正确的。

    #define ADC12_SHT_SRC_SEL 0x0200旁边的注释应更改源代码、但它会影响位9、即 ADC12SHP。 但是、您始终使用 ADC12SC 作为源、因此 ADC12SHSx 根据需要保持为零、您可能确实希望毕竟切换 ADC12SHP。

    在使用 ADC12SC 位开始转换后、您可以立即将变量分配给 ADC12MEM0、而无需等待任何时间完成转换、因此、在分配时、ADC12MEM0中的值不是当前值。

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

    感谢您的回复。

    所以您说"ADC12MCTL0 = ADC12MCTL1 = 0x0A、这是不正确的"。 就我的理解而言、这是您的意思  

    ADC12MCTL0 = ADC12_P92;// P9.2是模拟输入
    ADC12MCTL1 = ADC12_P43;

    那么、如何同时读取多个模拟信号。 我有9到10个模拟输入

    谢谢你

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您的意思是、我应该在此处分配不同的地址:
    #define ADC12_P92 0x000A //将输入 P9.2用于模拟输入
    #define ADC12_P43 0x000A
    #define ADC12_P32 0x000A
    #define ADC12_P93 0x000A
    #define ADC12_P14 0x000A
    #define ADC12_P20 0x000A
    #define ADC12_P41 0x000A
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    正确的 Sali、ADC12_Pxx 应具有与各种模拟输入引脚对应的不同值。

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

    #include
    #define ACLK 0x0100 //计时器 ACLK 源
    #define up 0x0010 //计时器启动模式
    #define ENABLE_Pins 0xFFFE //需要使用输入和输出
    #define ENABLE_Pins 0xFFFE //启用输入和输出
    void ADC_Setup (void);//用于设置 ADC12外设
    const int x1=1;
    const int x2=1;
    volatile int 乘以_value;

    MAIN ()

    PM5CTL0 = ENABLE_Pins;//启用输入和输出
    P1DIR =BIT0;//将红色 LED 设置为输出


    ADC_Setup();//设置 ADC 外设
    while (1)

    ADC12CTL0 = ADC12CTL0 | ADC12ENC;//启用转换
    ADC12CTL0 = ADC12CTL0 | ADC12SC;//开始转换
    while (ADC12BUSY = 1){
    MPLED_VALUE =(ADC12MEM0);
    如果(乘以_value > 0x800)//如果输入> 1.65V

    P1OUT = BIT0;//打开红色 LED

    else // else 输入<= 1.65V

    P1OUT = 0x00;//关闭红色 LED



    P2DIR |= BIT1; // P2.1到输出
    P2SEL1 |= BIT1; // P2.1到 TA0.1

    TA0CCR0 =乘以值*2; // PWM 周期
    TA0CCTL1 = OUTMOD_7; // CCR1复位/置位
    TA0CCR1 =乘以值; // CCR1 PWM 占空比
    TA0CTL = tassel_2 + MC_1;// SMCLK、向上计数模式

    BIS_SR (LPM0_Bits); //输入 LPM0



    void ADC_Setup (void)

    #define ADC12_SHT_16 0x0200 //采样保持的16个时钟周期
    #define ADC12_ON 0x0010 //用于打开 ADC12外设
    #define ADC12_SHT_SRC_SEL 0x0200 //选择采样保持源
    #define ADC12_12位0x0020 //选择12位分辨率
    #define ADC12_P92 0x000A //将输入 P9.2用于模拟输入
    //#define ADC12_P43 0x000A
    //#define ADC12_P32 0x000A
    //#define ADC12_P93 0x000A
    //#define ADC12_P14 0x000A
    //#define ADC12_P20 0x000A
    //#define ADC12_P41 0x000A
    ADC12CTL0 = ADC12_SHT_16 | ADC12_ON;//开启,设置采样保持时间
    ADC12CTL1 = ADC12_SHT_SRC_SEL;//指定采样保持时钟源
    ADC12CTL2 = ADC12_12位;// 12位转换结果
    ADC12MCTL0 = ADC12_P92;// P9.2是模拟输入
    //ADC12MCTL1 = ADC12_P43;




    我测量了引脚 P9.2,它是2伏,我想产生 PWM,我将周期分配为4,占空比分配为2,所以我期望引脚 p2.1上的频率为0.25Hz,但它是0.5KHz! 我不知道为什么它会给我这个数字。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    什么是 AVCC 基准电源电压、ADC12MEM0和 m倍增_value? 如果 TA0CCR0实际为4、则输出频率应为~250kHz、因为 SMCLK 为1.048MHz (默认值)。

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

    您好、Ryan、

    感谢您对我的耐心,我知道我可能会问一些愚蠢的问题,但这对我来说是全新的东西,我从未使用过 MSP430。

    我通过 USB 将芯片连接到 PC、因此我假设反向电压为3.3V

    然后、我创建了一个小型测试电路来确保 MCU 可能正常工作、我的电路只是 一个直接 连接 到 MCU 的电位计、 电位计的输出 连接到引脚9.2 (模拟输入) 我调节 电位器 以提供2V 的输出电压、然后将该值保存在"倍增 值"变量中。

    现在、PWM 的周期= 乘以_value*2。

    占空比=乘以值

    ADC12MEM0、根据我的理解、当我使用 ADC12CTL0启用并开始转换时、转换后的模拟值将自动保存在 ADC12MEM0中!、我对吗?

    谢谢、

    萨利

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    输入电压为2V、基准电压为3.3V、分辨率为12位(4096点):

    MPLICE_VALUE = ADC12MEM0 =(2/3.3)*4096 = 2482

    TACCR0 = 2482*2 = 4965

    因此、在具有默认 SMCLK 源的计时器向上计时模式下、我预计周期为1048576/4965 = 211Hz、您将需要调试程序以确定视差。

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

    您好、Ryan

    什么是 1048576?  

    我是否应将采样保持率设置为 SMCLK?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    2^20 = 1048576 =默认 SMCLK 频率、此时我们刚刚讨论过它以用于计时器。 ADC 采样保持时间根据 ADCCLK 周期数进行设置、提供的代码指示16个 ADC12OSC (MODOSC、4.8MHz)周期。 我不理解您在 ADC 采样和 SMCLK 之间的关联。

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

    SMCLK 为16MHz 或2.048MHz 或2 ^20? 我在在线文档中找到了不同的数字!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    最大 SMCLK 为16MHz、但不是默认值。 对于1MHz、启动设置为 DCOFSEL = 6 (8MHz)和 DIVS/DIVM = 3 (/8)。

    此致、
    Ryan