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/MSP430F6736:使用6条模拟输入线路

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/715761/ccs-msp430f6736-use-6-analog-input-lines

器件型号:MSP430F6736

工具/软件:Code Composer Studio

大家好、

我想为 msp430f6736 (100引脚)使用6条模拟输入线路。 A0-A5的输入。

我已经介绍了使用3条输入线路的示例代码。 以下是示例代码:

#include 

unsigned char adc_result[3]; // 8位 ADC 转换结果数组

int main (void)
{
WDTCTL = WDTPW | WDTHOLD; //停止 WDT

//设置 P1.2 A0、1.1 A1、1.0 A2
P1SEL |= BIT0 | BIT1 | BIT2; //将 P1.0、.1、.2设置为非 IO
_disable_interrupt (); //禁用中断;端口映射配置
PMAPKEYID = PMAPKEY; //启用访问端口映射寄存器
P1MAP2 = PM_ANALOG; //启用 A0
P1MAP1 = PM_ANALOG; //启用 A1
P1MAP0 = PM_ANALOG; //启用 A2
PMAPKEYID = 0; //禁用访问端口映射寄存器
_enable_interrupt (); //重新启用所有中断

//设置 ADC10
ADC10CTL0 = ADC10SHT_2 | ADC10MSC | ADC10ON;// 16ADCclks、MSC、ADC 打开
ADC10CTL1 = ADC10SHP | ADC10CONSEQ_1; //脉冲采样模式,点序
ADC10CTL2 &=~ADC10RES; // 8位分辨率
ADC10MCTL0 = ADC10INCH_2; // A0、A1、A2 (EOS)、AVCC 基准

//设置 DMA0 (ADC10IFG 触发)
DMACTL0 = DMA0TSEL_24; // ADC10IFG 触发
DMA0SZ = 0x03; // 3次转换
__data16_write_addr ((unsigned short)&DMA0SA、(unsigned long)&ADC10MEM0);
//源单个地址
__data16_write_addr ((无符号短整型)&DMA0DA、(无符号长整型)&ADC_Result [0]);
//目标数组地址
DMA0CTL = DMADT_4 | DMADSTINCR_3 | DMASRCBYTE | DMADSTBYTE | DMAEN | DMAIE;
//重复单次传输
//递增目的
//字节访问
//启用转换序列后的 int
while (1)
{
while (ADC10CTL1 & ADC10BUSY); //等待 ADC10内核处于活动状态
ADC10CTL0 |= ADC10ENC | ADC10SC; //采样和转换开始

_bis_SR_register (LPM0_bits | GIE); //输入 LMP0,带中断
_delay_cycles (5000); //序列转换之间的延迟
__no_operation(); //断点;查看 ADC_Result
}
}

#if defined (__TI_Compiler_version__)|| defined (__IAR_systems_icc_)
#pragma vector=DMA_vector
__interrupt void DMA0_ISR (void)
#elif defined (__GNU__)
void __attribute__((interrupt (DMA_vector))) DMA0_ISR (void

编译器#else!
#endif
{
开关(__evo_in_range (DMAIV、16))
{
案例 DMAIV_NONE:break; //无中断
案例 DMAIV_DMA0IFG: // DMA0IFG = DMA 通道0
//转换序列完成
_BIC_SR_REGISTER_ON_EXIT (LPM0_BITS);//返回时退出 LPM0
中断;
案例 DMAIV_DMA1IFG:中断; // DMA1IFG = DMA 通道1
案例 DMAIV_DMA2IFG:中断; // DMA2IFG = DMA 通道2
案例8:中断; //保留
案例10:中断; //保留
案例12:中断; //保留
案例14:中断; //保留
案例16:中断; //保留
默认值:break;
}
} 

我尝试通过设置断点来打印所有3个输入的输出。 我获得了相对于8位分辨率的输出。

我尝试并更改了:  

ADC10CTL2 &=~ADC10RES;                      // 8位分辨率

更改为 ADC10CTL2 |= ADC10RES;                      // 10位分辨率

但它没有更改为10位分辨率。

我需要更改什么才能获得10位分辨率?

模拟输入 A3-A5位于端口9上。  

如何将这些输入添加到此代码中、以便能够获得屏幕上所有6个模拟输入的输出?

可以帮我解决这个问题吗?

谢谢、

评估

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    此示例代码使用 DMA 控制器将 ADC 结果复制到数组中。
    要获得更大的结果、必须对 ADC_Result 数组使用16位类型、并告知 DMA 控制器(在 DMA0CTL 中)将字用于源和目的。

    ADC10INCH 域为转换序列选择最高的通道。 您还必须告诉 DMA 控制器(在 DMA0SZ 中)复制更多的值并适当地配置引脚(PxSEL、PxMAP)。

    您必须阅读用户指南的第11、12、13和27章以及数据表中的表63、64和78、以了解其工作原理。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    大家好、Clemens、

    我想使用8个模拟输入(SD24转换器输入除外)。 我已经配置了提供的6个输入 A0-A6。
    msp430f6736数据表显示、它有8条用于 ADC10的模拟输入线(6条外部、2条内部)。 我使用了6个外部输入。

    如何访问剩余的2个 int 输入?

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

    F6736数据表第一页显示:

    多达6个外部通道、2个内部通道、包括温度传感器

    两个内部通道(10、11)连接到温度传感器和电池监控器。

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

    大家好、Clemens、

    //设置 P1.2 A0、1.1 A1、1.0 A2
    P1SEL |= BIT0 | BIT1 | BIT2; //将 P1.0、.1、.2设置为非 IO
    P9SEL |= BIT1 | BIT2 | BIT3; //将 P9.1、.2、.3设置为非 IO
    
    
    P6DIR |= BIT0 | BIT1; //为多路复用器启用线路
    P6OUT &=~BIT0;
    P6OUT &=~BIT1;
    
    
    P5DIR |= BIT0 | BIT1 | BIT2 | BIT3; //选择多路复用器的线路
    
    
    _disable_interrupt (); //禁用中断;端口映射配置
    PMAPKEYID = PMAPKEY; //启用访问端口映射寄存器
    P1MAP2 = PM_ANALOG; //启用 A0
    P1MAP1 = PM_ANALOG; //启用 A1
    P1MAP0 = PM_ANALOG; //启用 A2
    PMAPKEYID = 0; //禁用访问端口映射寄存器
    _enable_interrupt (); //重新启用所有中断
    
    
    //设置 ADC10
    ADC10CTL0 = ADC10SHT_3 | ADC10MSC | ADC10ON;// 16 ADCclks、MSC、ADC 开启
    ADC10CTL1 = ADC10SHP | ADC10CONSEQ_1; //脉冲采样模式、单序列
    ADC10CTL2 |= ADC10RES; // 10位分辨率
    ADC10MCTL0 = ADC10INCH_2; // A0、A1、A2 (EOS)、AVCC 基准
    ADC10MCTL0 = ADC10INCH_5; // A3、A4、A5 
    //设置 DMA0 (ADC10IFG 触发) DMACTL0 = DMA0TSEL_24; // ADC10IFG 触发 DMA0SZ = 0x06; // 6次转换
    __data16_write_addr ((unsigned short)&DMA0SA、(unsigned long)& ADC10MEM0); //源单个地址 __data16_write_addr ((无符号短整型)&DMA0DA、(无符号长整型)& ADC_Result [0]); //目标数组地址
    DMA0CTL = DMADT_4 | DMADSTINCR_3 | DMAEN | DMAIE; DMA0CTL ~DMASRCBYTE; DMA0CTL &=~DMADSTBYTE;

    我已将端口配置为使用6条模拟输入线路、如上所示。 但是我没有得到准确的结果。  

    我是否正确配置了端口? 您可以查看一下吗?

    谢谢、

    评估

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    "准确"的具体含义是什么?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我有时会得到0。
    有时、我甚至会获得比预期更高的值。
    我提供的输入模拟信号范围为0-1V。

    为了解释我所做的确切工作:

    我将单元(具有保险丝的 DUT)连接到多路复用器输入线路。
    我已将多路复用器输出(6 16:1多路复用器- CD4067B)连接到微控制器的模拟输入线路。
    我已将多路复用器的选择线路和抑制线路连接到 MCU 的 I/O 线路(我已将所有多路复用器的选择线路和抑制线路连接在一起)。 我逐个增加所选行、这样多路复用器就可以选择不同的单位。

    当我增加信号时、我为连接到多路复用器的单元获得不需要的值(0、3V、不需要)。 通过 DUT 的电压使用连接到 DUT 保险丝的差分放大器进行测量。

    在选择两条线之间是否会产生时序问题、这可能会导致读数出错?

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

    大家好、Clemens、

    这是我使用的代码:

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    unsigned int results[3]; //SD24转换器结果数组
    unsigned int adc_result[6]; // 8位 ADC 转换结果数组
    
    float A0、A1、A2、A3、A4、A5、A6、A7、A8; //模拟电压结果寄存
    器 float a0、A1、A2、A3、A4、A5、A6、A7、A8; //用于存储结果值
    的临时寄存器 float I0、I1、I2、I3、I4、i5、I6、i7、I8; //当前结果寄存
    器 unsigned int sig=0x00;
    
    time_t curry_time;
    char *c_time_string;
    
    /*单位编号显示的计数器*/
    unsigned int c1=1;
    unsigned int c2=17;
    unsigned int c3=33;
    unsigned int c4=49;
    unsigned int c5=65;
    unsigned int C6=1;
    unsigned int C7=17;
    unsigned int C8=33;
    unsigned int C9=49;
    unsigned int C10=65;
    
    int main (void)
    {
    
    WDTCTL = WDTPW | WDTHOLD; //停止 WDT
    
    
    //file * fp;
    
    //设置 P1.2 A0、1.1 A1、1.0 A2
    P1SEL |= BIT0 | BIT1 | BIT2; //将 P1.0、.1、.2设置为非 IO
    P9SEL |= BIT1 | BIT2 | BIT3; //将 P9.1、.2、.3设置为非 IO
    
    
    P6DIR |= BIT0 | BIT1; //为多路复用器启用线路
    P6OUT &=~BIT0;
    P6OUT &=~BIT1;
    
    
    P5DIR |= BIT0 | BIT1 | BIT2 | BIT3; //选择多路复用器的线路
    
    
    
    _disable_interrupt (); //禁用中断;端口映射配置
    PMAPKEYID = PMAPKEY; //启用访问端口映射寄存器
    P1MAP2 = PM_ANALOG; //启用 A0
    P1MAP1 = PM_ANALOG; //启用 A1
    P1MAP0 = PM_ANALOG; //启用 A2
    PMAPKEYID = 0; //禁用访问端口映射寄存器
    _enable_interrupt (); //重新启用所有中断
    
    
    //设置 ADC10
    ADC10CTL0 = ADC10SHT_3 | ADC10MSC | ADC10ON; // 16个 ADCclks、MSC、ADC 打开
    ADC10CTL1 = ADC10SHP | ADC10CONSEQ_1 | ADC10SSEL_3; //脉冲采样模式、单序列
    //ADC10CTL1 = ADC10SSEL_2;
    ADC10CTL2 |= ADC10RES; //10位分辨率
    //ADC10MCTL0 = ADC10INCH_2;
    ADC10MCTL0 = ADC10INCH_5; //A5、A4、A3、A2、A0、A1、A2 (EOS)、AVCC 基准
    
    //设置 DMA0 (ADC10IFG 触发)
    DMACTL0 = DMA0TSEL_24; // ADC10IFG 触发
    DMA0SZ = 0x06; // 6次转换
    
    __data16_write_addr ((unsigned short)&DMA0SA、(unsigned long)& ADC10MEM0);
    //源单个地址
    __data16_write_addr ((无符号短整型)&DMA0DA、(无符号长整型)& ADC_Result [0]);
    //目标数组地址
    
    DMA0CTL = DMADT_4 | DMADSTINCR_3 | DMAEN | DMAIE;
    DMA0CTL ~DMASRCBYTE;
    DMA0CTL &=~DMADSTBYTE;
    //重复单次传输
    //递增目的
    //字节访问
    //启用转换序列后的 int
    
    
    
    //SD24转换器设置
    SD24BCTL0 |= SD24SSEL_1; //选择内部 REF
    SD24BCTL0 |= SD24REFS; //选择 SMCLK 作为 SD24_B 时钟源
    
    SD24BCCTL0 |= SD24SNGL;
    //SD24BCCTL0 |= SD24ALGN;
    SD24BCCTL0 |= SD24DF0;
    SD24BCCTL0 |= SD24SCS_5; //单次转换,组1
    
    SD24BCCTL1 |= SD24SNGL;
    //SD24BCCTL1 |= SD24ALGN;
    SD24BCCTL1 |= SD24DF0;
    SD24BCCTL1 |= SD24SCS_5; //单次转换,组1
    
    SD24BCCTL2 |= SD24SNGL;
    //SD24BCCTL2 |= SD24ALGN;
    SD24BCCTL2 |= SD24DF0;
    SD24BCCTL2 |= SD24SCS_5; //单次转换,组1
    
    SD24BIE |= SD24IE2;//| SD24IE1 | SD24IE0; //启用通道2中断
    
    SD24BOSR0 = 0x0195;
    SD24BOSR1 = 0x0195;
    SD24BOSR2 = 0x0195;
    
    _DELAY_CYCLES (0x5000); 1.5V REF 启动的//延迟
    
    
    
    
    while (1)
    {
    
    
    _delay_cycles (15000);
    
    //__delay_cycles (2000);
    
    如果(sig = 0x10)
    {
    sig = 0x00;
    P5OUT = SIG;
    printf ("选择行=%d \n"、sig);
    }
    
    其他
    {
    printf ("选择行=%d \n"、sig);
    P5OUT = SIG;
    }
    
    //时间设置
    time_t = time (NULL);
    struct tm *tm = localtime(&T);
    char s[64];
    strfttime (s、sizeof (s)、"%c"、TM);
    
    
    
    while (ADC10CTL1 & ADC10BUSY); //等待 ADC10内核处于活动状态
    ADC10CTL0 |= ADC10ENC | ADC10SC; //采样和转换开始
    
    _bis_SR_register (LPM0_bits | GIE);//输入 LPM0、带中断
    _delay_cycles (5000); //序列转换之间的延迟
    __no_operation(); //断点;查看 ADC_Result
    
    //ADC_10电压和电流显示
    A5=ADC_Result [5];
    A5=(A5*3.03*200)/(1023);
    i5=(A5)/2.43;
    
    A4=ADC_Result [4];
    A4=(A4*3.03*200)/(1023);
    I4=(A4)/2.43;
    
    A3=ADC_Result [3];
    A3=(A3*3.03*200)/(1023);
    I3=(A3)/2.43;
    
    A2=ADC_Result [2];
    A2=(A2*3.03*200)/(1023);
    I2=(A2)/2.43;
    
    a1=ADC_Result [1];
    a1=(A1*3.03*200)/(1023);
    I1=(A1)/2.43;
    
    A0=ADC_RESULT[0];
    A0=(A0*3.03*200)/(1023);
    I0=(A0)/2.43;
    
    
    //IF (A5 > 9和 A5 < 12)
    //{
    printf (V1 supply、unit %d、%g mV、%g mA、、、%s\n"、C6、A5、i5、s);
    //}
    
    /*else
    {
    printf ("V1 supply、unit %d、no unit or fuse buln or faulty unit\n"C6);
    }*/
    
    如果(C6==16)
    {
    C6=1;
    }
    其他
    {
    C6++;
    }
    
    
    //if (A4 > 9.00和 A4 < 12)
    //{
    printf (V1 supply、unit %d:、%g、%g mA、、、%s\n"、C7、A4、I4、s);
    //}
    
    /*else
    {
    printf ("V1 supply、unit %d、no unit or fuse buln or faulty unit\n"C5);
    }*/
    
    如果(C7 = 32)
    {
    C7=17;
    }
    其他
    {
    C7 ++;
    }
    
    
    //if (A3 > 9和 A3 < 12)
    //{
    printf (V1 supply、unit %d、%g mV、%g mA、、、%s\n"、C8、A3、I3、s);
    //}
    
    /*else
    {
    printf ("V1 supply、unit %d、no unit or fuse buln or faulty unit\n"C4);
    }*/
    
    如果(C8==48)
    {
    C8=33;
    }
    其他
    {
    C8++;
    }
    
    
    //if (A2 > 9 && A2 < 12)
    //{
    printf (V1 supply、unit %d:、%g mV、%g mA、、、、%s\n"、C9、A2、I2、s);
    //}
    
    /*else
    {
    printf ("V1 supply、unit %d、no unit or fuse buln or faulty unit\n"C3);
    }*/
    
    如果(C9==64)
    {
    C9=49;
    }
    其他
    {
    C9++;
    }
    
    
    //if (A1 > 9 && A1 < 12)
    //{
    printf (V1 supply、unit %d:、%g mV、%g mA、、、、%s\n"、C10、A1、I1、s);
    //}
    
    /*else
    {
    printf ("V1 supply、unit %d、no unit or fuse buln or faulty unit \n"C2);
    }*/
    
    
    
    
    如果(C10=80)
    {
    C10=65;
    }
    其他
    {
    C10++;
    }
    
    
    //if (A0 > 9 && A0 < 12)
    //{
    printf ("v8 supply、unit %d、%g mV、%g mA、、、、%s\n"、c1、A0、I0、s);
    //}
    
    /*else
    {
    printf ("v8 supply、unit %d、no unit or fuse buln or faulty unit\n"C1);
    }*/
    
    
    
    如果(c1==16)
    {
    C1=1;
    }
    其他
    {
    C1++;
    }
    
    
    
    
    //__delay_cycles (1000);
    
    
    SD24BCTL1 |= SD24GRP1SC; //将位设置为开始转换
    _bis_SR_register (LPM0_bits | GIE);//输入 LPM0、带中断
    
    SD24BCTL1 &=~SD24GRP1SC; //清除位以进行下一次转换
    //__delay_cycles (2000);
    __no_operation(); //在此处设置断点
    
    
    //SD24转换器电压和电流显示
    A6=(结果[0]);
    A6=(A6*3.03*200)/(1020);
    I6=(A6)/2.43;
    
    A7=(结果[1]);
    A7=(A7*3.03*200)/(1020);
    I7=(A7)/2.43;
    
    A8 =(结果[2]);
    A8=(A8*3.03*200)/(1020);
    I8=(A8)/2.43;
    
    
    
    
    //IF (A8 > 9和& A8 < 12)
    //{
    printf ("v8 supply、unit %d、%g mV、%g mA、、、、%s\n"、C2、A8、I8、s);
    
    //}
    
    /*else
    {
    printf ("v8 supply、unit %d、no unit or fuse buln or faulty unit \n"c9);
    }*/
    
    如果(c2==32)
    {
    C2=17;
    }
    其他
    {
    C2++;
    }
    
    
    
    //IF (A7 > 9和& A7 < 12)
    //{
    printf ("v8 supply、unit %d、%g mV、%g mA、、、、%s\n"、C3、A7、i7、s);
    //}
    
    /*else
    {
    printf ("v8 supply、unit %d、no unit or fuse buln or faulty unit \n"C8);
    }*/
    
    
    如果(C3==48)
    {
    C3=33;
    }
    其他
    {
    C3++;
    }
    
    
    //if (A6 > 9 & A6 < 12)
    //{
    printf ("v8 supply、unit %d、%g mV、%g mA、、、、%s\n"、C4、A6、I6、s);
    //}
    
    /*else
    {
    printf ("v8 supply、unit %d、no unit or fuse buln or faulty unit \n"C7);
    }*/
    
    
    如果(C4==64)
    {
    C4=49;
    }
    其他
    {
    C4++;
    }
    
    
    
    //_delay_cycles (10000);
    SIG++;
    
    //__delay_cycles (10000);
    }
    }
    
    #if defined (__TI_Compiler_version__)|| defined (__IAR_systems_icc_)
    #pragma vector=SD24B_vector
    __interrupt void SD24BISR (void)
    #Elif defined (__GNU__)
    void __attribute__((interrupt (SD24B_vector))) SD24BISR (void
    
    编译器#error!)不支持!
    #endif
    {
    开关(SD24BIV)
    {
    案例 SD24BIV_SD24OVIFG: // SD24MEM 溢出
    中断;
    案例 SD24BIV_SD24TRGIFG: // SD24触发 IFG
    中断;
    案例 SD24BIV_SD24IFG0: // SD24MEM0 IFG
    中断;
    SD24BIV_SD24IFG1案例: // SD24MEM1 IFG
    中断;
    SD24BIV_SD24IFG2案例: // SD24MEM2 IFG
    结果[0]= SD24BMEMH0; //保存 CH0结果(清除 IFG)
    结果[1]= SD24BMEMH1; //保存 CH1结果(清除 IFG)
    结果[2]= SD24BMEMH2; //保存 CH2结果(清除 IFG)
    中断;
    }
    
    __BIC_SR_REGISTER_ON_EXIT (LPM0_BITS);//退出 LPM0
    }
    
    
    
    #if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
    #pragma vector=DMA_vector
    __interrupt void DMA0_Compiler (void)
    #Elif definef ISR (__GISR_ICS_ICC_
    )(void)(nvoid)#define_transl_(n_transl_)(void)(void)(void)(nat_transl_ tma_ tager_)(void
    
    
    #endif
    {
    开关(__evo_in_range (DMAIV、16))
    {
    案例 DMAIV_NONE:break; //无中断
    案例 DMAIV_DMA0IFG: // DMA0IFG = DMA 通道0
    //转换序列完成
    _BIC_SR_REGISTER_ON_EXIT (LPM0_BITS);//返回时退出 LPM0
    中断;
    案例 DMAIV_DMA1IFG:中断; // DMA1IFG = DMA 通道1
    案例 DMAIV_DMA2IFG:中断; // DMA2IFG = DMA 通道2
    案例8:中断; //保留
    案例10:中断; //保留
    案例12:中断; //保留
    案例14:中断; //保留
    案例16:中断; //保留
    默认值:break;
    }
    }
    

    代码中是否有任何错误?

    您能看一下 ADC10和 DMA 寄存器的设置配置吗?

    谢谢、

    评估

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

    如果您怀疑多路复用输入尚未稳定、请尝试在 P5OUT 写入后插入一个短延迟。