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.

[参考译文] CCS/MSP430F2013:MSP430F2013中的 SD16 ADU

Guru**** 2524460 points
Other Parts Discussed in Thread: MSP430F2013, TLC5951

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/597646/ccs-msp430f2013-sd16-adu-from-msp430f2013

器件型号:MSP430F2013
主题中讨论的其他器件: TLC5951

工具/软件:Code Composer Studio

请参阅下面的我的代码。 我使用 MSP430F2013中的 SD16将两个模拟值捕捉到两个单独的16位整数中。 现在、我只对 LMP0中的外设 ADC 和 SPI 执行此操作(因为 Kaustuh Kulkarni 先生的暗示)。 但是、这些值仍然会跳转。 在 P1.1上、该值恒定为170mV、在 P1.2上、该值为零(GND)。
对于 P1.1、我得到介于19561和18399之间的值。
对于 P1.2、该值从0跳到437。
这是正常的、还是我的代码中仍然有问题?

此致

Franz Peter Zantis

//将 MSP430F2013用作 ADU
/23. MAI 2017、F.P.Zantis
//数据传输与2个16位字的块(Int16)一起工作
//new values are delivered from the ADU in the rhythm of 1954Hz/20
#include "msp430x20x3.h"
unsigned int flag=4;    //4=inch_4、P1.1;1=inch_1、P1.2
unsigned int 计数器;
unsigned int valP11;   // P1.1上的值,要传输的值
unsigned int valP12;   // P1.2上的值,要传输的值
      来自 ADC 的无符号 int val;//电流值
无符号 int valP1x;   //来自10个 ADC 值的结果
unsigned int trash;      //如果出现错误数据

int main( void )

 WDTCTL = WDTPW + WDTHOLD;    //停止看门狗计时器以防止超时复位
 BCSCTL1 = CALBC1_16MHz;      //时钟 SMCLK=16MHz
 DCOCTL = CALDCO_16MHz;       //使用内部 DCO 作为时钟

 P1DIR &=~BIT2;                      //P1.2至输入;电压采样
 P1DIR &=~BIT1;                      //P1.1至输入;电流采样

 P1DIR |= BIT4;                       //P1.4至输出方向
 P1SEL |= BIT4;                       //SMCLK 至 P1.4

 P1DIR |= BIT3;                       //P1.3至输出方向
 P1SEL |= BIT3;                       //UREF 至 P1.3

 P1DIR |= BIT7;                          //P1.7至输出方向(LED)
 P1OUT &=~BIT7;                   //LED 关闭

 P2SEL &=~BIT7;                      //选择 P2.7作为输入/输出-使用
 P2DIR |= BIT7;                      //P2.7至输出方向

 //init ADC SD16
 SD16CTL = SD16REFON;                 //激活基准1.2V
 SD16CTL |= SD16SSEL_1;               // ADU 的时钟为 SMCLK
 SD16CTL |= SD16XDIV_2;               //通过16  16MHz --> 1MHz 进行分频
 SD16CTL |= SD16DIV_1;                //分频器通过2;1MHz --> 500kHz 两个分频器的结果对于 ADU 为500kHz
 SD16INCTL0 = SD16INCH_4;             //通过 A4+、P1.1、引脚3的默认输入
 SD16AE &=~SD16AE1;                  //通过 A4+、P1.1、引脚3、A4-至 GND 的单极输入
 SD16AE &=~SD16AE2;                  //通过 A1+、P1.2、引脚4的单极输入;A1-到 GND
 SD16CCTL0 &=~SD16SNGL;             //连续转换
 SD16CCTL0 |= SD16UNI;                //16位无符号
 SD16CCTL0 |= SD16IE;                 //为 ADU 启用中断
 SD16CCTL0 &=~SD16XOSR;              //设置过采样率选择器
 SD16CCTL0 |= SD16OSR_256;            //低通滤波器的过采样率500kHz/256=1954Hz 采样率
 SD16CCTL0 |= SD16SC;                 //开始转换

 USICTL0 &=~μ s USISWRST;                //USI 被释放以运行
 USICTL1 &=~USII2C;                  //清除 I²C 位以将 USI 切换到 SPI 模式
 USICTL0 &=~USIMST;                  //将 Masterbit 重置为 SPI-Slave
 USICTL0 |= USIPE5;                   //SPI-CLOCK Via PIN7 (来自勇士56)
 USICTL0 |= USIPE6;                   //SDO 端口被启用;PIN8
 USICTL0 &=~USIPE7;                  //SDI-Port 被禁用;引脚9可被用于正常输入/输出
 USICTL0 &=~USILSB;                  //MSB 优先
 USICKCTL &=~μ A USICKPL;                //空闲时钟为低电平
 USICTL1 &=~USICKPH;                 //get data on the first edge
 USICTL0 |= USIOE;                    //激活输出(数据从 MSP 传输到勇士56
 USICNT |= USI16B;                    //初始化16位数据的加载计数器

 //---- 用于数据交换的初始化-------------------------------------------------------
 针对作为 CS 的 P1.0的//init 中断
 P1DIR &=~BIT0;     //P1.0用于输入
 P1REN |= BIT0;      //P1.0上拉
 P1IE = P1IE | BIT0;   //P1.0通过 P1.0启用中断
 P1IES |= BIT0;      //选择 P1.0用于具有下降沿的中断-->在 ISR 中,CS 用于 SPI
 P1IFG = P1IFG &(~BIT0); //清除中断标志

 _BIS_SR (LPM0_Bits + GIE);  //使用中断输入 LPM0




#pragma vector=Port1_vector
_interrupt void Port_1 (void)

//ISR、如果 P1.0的电平从高电平跳到低电平
//如果((P1IFG & BIT0)&!(P2IN & BIT7))检查 P1的位0是否相关并且额外的 P2.7不是高电平
 如果(P1IFG 和 BIT0)         //检查 P1的位0是否相关
 {
    SD16CCTL0 &=~SD16IE;        针对 ADU 的//中断禁用;为了确保没有 ADU-INTERRUPT 会停止这个当前中断
    //USISR=valP11;               //将 P1.1上的值写入 SPI 寄存器;已经在 SD16_ISR 中完成
     USICNT |= 16;                  //加载计数器并使用16位字开始传输
     while (!(USIIFG & USICTL1));    //等待数据传送

     USISR=valP12;               //将 P1.2上的值写入 SPI 寄存器
     USICNT |= 16;                  //加载计数器并使用16位字开始传输
     while (!(USIIFG & USICTL1));    //等待数据传送

     P1OUT ^= BIT7;              //如果已转移新值,则切换 P1.7
 }
 P1IFG = P1IFG &(~BIT0);  //清除 P1的中断标志
 SD16CCTL0 |= SD16IE;      //为 ADU 启用中断




#pragma vector = SD16_vector
 _interrupt void SD16ISR (void)

    开关(SD16IV)
    {
        案例2:         //SD16MEM 溢出
           垃圾桶= SD16MEM0;
           中断;
        案例4:         //SD16MEM0 IFG
          Val = SD16MEM0;
          如果(val > valP1x)
          {
              valP1x= val;
          }
          // SD16CCTL0 &=~SD16IFG;   //清除中断标志;通过捕捉 SD16MEM0值自动完成
          COUNTER++;
          如果(counter>9)         //获取最高值9
          {
              SD16CCTL0 &=~SD16SC;     //因为切换通道而停止转换
              如果(flag == 4)             //值到 A4+
              {
                valP11=valP1x;
                USISR=valP1x;
                标志= 1;               //下一个值的开关来自 P1.2
                SD16INCTL0 = SD16INCH_1;  //下一个值的开关来自 P1.2
              }
              其他                   //值到 A1+
              {
                valP12=valP1x;
                标志= 4;               //下一个值的开关来自 P1.1
                SD16INCTL0 = SD16INCH_4;  //下一个值的开关来自 P1.1
              }
              计数器=0;
              valP1x=0;
             SD16CCTL0 |= SD16SC;       //开始转换
          }
    }


  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    请允许我花些时间浏览您的代码、然后我会返回给您。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我认为我发现了一个问题。 它具有引脚配置。

    我发现的第一个问题是:

    SD16AE &=~SD16AE1; //通过 A4+、P1.1、引脚3、A4-至 GND
    SD16AE &=~SD16AE2的单极输入; //通过 A1+、P1.2、引脚4的单极输入;A1-到 GND 

    这不是单极位。 这是模拟使能。 您将这些引脚禁用为模拟引脚。 您需要执行完全相反的操作。

    第二期:

    SD16CCTL0 |= SD16UNI; //16位无符号数 

    这不是16位无符号位。 这是单极与双极模式。 在这种情况下、代码是意外正确的、但值得指出。

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

    尊敬的 Nima:

    非常感谢! 但是:我现在已经更改了 SD16ISR 中的代码。 但是没有什么不同的-奇怪! P1.1中的值从22000跳到22800 (大约舍入)。 P1.1的电压电平为直流电。

    #pragma vector = SD16_vector
     _interrupt void SD16ISR (void)

        开关(SD16IV)
        {
            案例2:         //SD16MEM 溢出
               垃圾桶= SD16MEM0;
               中断;
            案例4:         //SD16MEM0 IFG
              Val = SD16MEM0;
              如果(val > valP1x)
              {
                  valP1x= val;
              }
              // SD16CCTL0 &=~SD16IFG;   //清除中断标志;通过捕捉 SD16MEM0值自动完成
              COUNTER++;
              如果(counter>9)         //获取最高值9
              {
                  SD16CCTL0 &=~SD16SC;     //因为切换通道而停止转换
                  如果(flag == 4)             //Value at P1.1至 A4+
                  {
                    valP11=valP1x;
                    标志= 1;                  //下一个值的开关来自 P1.2
                    SD16INCTL0 = SD16INCH_1;     //下一个值的开关来自 P1.2 (A1+)
                    SD16AE = SD16AE2;
                  }
                  其他                      //Value at P1.2 Through A1+
                  {
                    valP12=valP1x;
                    标志= 4;                  //下一个值的开关来自 P1.1
                    SD16INCTL0 = SD16INCH_4;  //下一个值的开关来自 P1.1 (A4+)
                    SD16AE = SD16AE1;
                  }
                  计数器=0;
                  valP1x=0;
                 SD16CCTL0 |= SD16SC;       //开始转换
              }
        }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我将在我的硬件上测试此代码以进一步对其进行调试。 我会再来的。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    #include 
    
    int main (void)
    {
    WDTCTL = WDTPW + WDTHOLD; //停止看门狗计时器
    P1DIR |= 0x01; //将 P1.0设置为输出方向
    SD16CTL = SD16REFON + SD16SSEL_1; // 1.2V ref、SMCLK
    SD16INCTL0 = SD16INCH_1; // a1+/-
    SD16CCTL0 = SD16UNI + SD16IE; // 256OSR、单极、中断使能
    SD16AE = SD16AE2; // P1.1 A1+、A1-= VSS
    SD16CCTL0 |= SD16SC; //将位设置为开始转换
    
    __bis_SR_register (LPM0_bits + GIE);
    }
    
    #if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
    #pragma vector = SD16_vector
    __interrupt void SD16ISR (void)
    #Elif defined (__GSDISR_ICM_
    )(void
    
    )(void SD16_)(void)(void)(void)(void SD16ISR (void)(void)(void)(nu_ vector)(void)(vo
    #endif
    {
    int result = SD16MEM0;
    //放置断点并读取数据
    }
    

    您可以运行这个简单的示例来测试 ADC 吗? 在 int 结果= SD16MEM0上放置一个断点、然后查看结果是否符合预期。 正在使用 A1通道。

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

    不,很抱歉。 它没有得到解决。 目前我正与 TLC5951一起处理一个紧急案件。 我很快就会回到这个问题。

    弗朗茨·彼得