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.

[参考译文] MSP430F2013:代码错误帮助

Guru**** 2390735 points
Other Parts Discussed in Thread: MSP430F2013

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/591017/msp430f2013-code-bug-help

器件型号:MSP430F2013

教授将 MSP430F2013用作 ADU。 他 对下面的代码有问题。

SD16用于数字化两个通道:P1.1和 P1.2上的值。 结果将不时通过 SPI 获取。 它原则上起作用。 但是:有时(估计10%的样本)值错误或为0。 代码是否有问题?

//将 MSP430F2013用作 ADU
//数据传输与2个16位字的块(Int16)一起工作
//新值从 ADU 以977Hz 的节律传递

#include "msp430x20x3.h"
unsigned int flag=4; //4=inch_4、P1.1;1=inch_1、P1.2
unsigned int 值[4];
//values[0];
//values[1]=0;              // P1.1上的值、要传输的值
//values[2]= 0;            // P1.2上的值,要传输的值
//values[3]=0;

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 &=~BIT4;                                           //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_2;                //divider through 4;1MHz --> 250kHz 对于 ADU,两个分频器的结果均为250kHz
 SD16INCTL0 = SD16INTDLY_0;                                   //第4个采样时的中断
 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;                    低通滤波器250kHz/256=977Hz 采样率的//过采样率

 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 |= BIT0;                                                                   //P1.0通过 P1.0启用中断
 P1IES |= BIT0;                    //选择 P1.0用于具有下降沿的中断-->在 ISR 中,CS 用于 SPI
 P1IFG = P1IFG &(~BIT0);                                           //清除中断标志

 _BIS_SR (GIE);                                                                 //启用所有中断

 while (1)
 {
    USISR=VALUE[1];         //将 P1.1上的值写入 SPI 寄存器;如果出现 SPI 请求、将加载第二个值(来自 P1.2)
   P1IE = P1IE | BIT0;                                      //启用中断 P1.0
    SD16CCTL0 |= SD16SC;                             //开始转换
 }

#pragma vector=Port1_vector
_interrupt void Port_1 (void)

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

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

     P1OUT ^= BIT7;                                          //如果一个新值已被转移、则切换 P1.7
 }
P1IFG = P1IFG &(~BIT0);                                //清除中断标志
//P1IE = P1IE | BIT0;                                          //启用中断;在 main ()中生成


#pragma vector = SD16_vector
 _interrupt void SD16ISR (void)

   //SD16CCTL0 &=~SD16SC;        //停止转换;由于单次转换模式:转换自动停止
   如果(flag == 4)
   {
     Value[1]=SD16MEM0;                              //保存值以通过 SPI 从 P1.1传输值
     标志= 1;                                                           //下一个值的开关来自 P1.2
     SD16INCTL0=SD16INCH_1;                       //下一个值的开关从 P1.2开始
   }
   其他
   {
     Value[2]= SD16MEM0;                             //保存值以通过 SPI 从 P1.2传输值
     标志= 4;                                                          //下一个值的开关来自 P1.1
     SD16INCTL0=SD16INCH_4;                       //下一个值的开关来自 P1.1
   }
  // SD16CCTL0 &=~SD16IFG;     //清除中断标志;通过捕捉 SD16MEM0值自动完成

有人可以帮助我吗?

提前感谢您。

考乌什

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    主循环和中断处理程序之间存在竞态条件;端口中断发生时不能保证新值可用。

    当第一个 USISR 值可用时、即、在 ADC 中断处理程序中写入该值。

    并且没有错误处理;当您通过清除 SD16SC 中止了转换并且在下一个端口中断发生时、下一个转换尚未完成时、可以获得随机值。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我同意 Clemens、主循环无效、因为在重新启动序列之前、无法确保转换已完成。 这可以通过轮询 SD16IFG 或使用 LPM0来解决、可以重新评估 TI 提供的代码示例以进一步了解这一点。

    此致、
    Ryan