教授将 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值自动完成
}
有人可以帮助我吗?
提前感谢您。
考乌什