请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
器件型号:LP-MSP430FR2476 主题中讨论的其他器件:TMP235
工具/软件:Code Composer Studio
您好!
我正在尝试使用 MSP430进行单通道转换、并将值发送到我的 PC、然后使用 MATLAB 绘制该值。 我使用连接到3V+、P1.1 (A1)、GND 的电表来测试我的代码。
我的问题是 ADC 结果卡在固定值(216)、但有时它开始实际读取类似于电表变化的内容。 我想我错误地设置了 A1、我读错了错误的引脚、但我在数据表或代码中找不到任何可能出错的东西。
#include
unsigned int adc_result;
void Init_gpio();
void Software_Trim (); //获取最佳 DCOFTRIM 值
#define MCLK_FREQ_MHz 的软件调整8. // MCLK = 8MHz
int main (void)
{
WDTCTL = WDTPW | WDTHOLD; //停止看门狗计时器
//配置 GPIO
Init_GPIO ();
//配置 GPIO
TA0CCTL0 |= CCIE; //启用 TACCR0中断
TA0CCR0 = 50000;
TA0CTL |= tassel_SMCLK | MC__Continuous; // SMCLK、连续模式
PM5CTL0 &=~LOCKLPM5; //禁用 GPIO 上电默认高阻抗模式
//激活先前配置的1个端口设置
__bis_SR_register (SCG0); //禁用 FLL
CSCTL3 |= SELREF_REFOCLK; //将 REFO 设置为 FLL 基准源
CSCTL1 = DCOFTRIMEN_1 | DCOFTRIM0 | DCOFTRIM1 | DCORSEL_3;// DCOFTRIM = 3、DCO 范围= 8MHz
CSCTL2 = FLLD_0 + 243; // DCODIV = 8MHz
__delay_cycles (3);
__BIC_SR_register (SCG0); //启用 FLL
Software_Trim (); //软件调整以获得最佳 DCOFTRIM 值
CSCTL4 = SELMS_DCOCLKDIV | SELA_REFOCLK;//将默认 REFO (~32768Hz)设置为 ACLK 源,ACLK = 32768Hz
//默认 DCODIV 作为 MCLK 和 SMCLK 源
//配置 UART 引脚
P1SEL0 |= BIT4 | BIT5; //将2-UART 引脚设置为第二功能
//配置 ADC A1引脚
P1SEL0 |= BIT1;
P1SEL1 |= BIT1;
//配置 UART
UCA0CTLW0 |= UCSWRST;
UCA0CTLW0 |= UCSS9600_SMCLK;
//波特率计算
// 8000000 =
小数/4000000
= 517/用户指南: UCBRSx = 0x49
// UCBRFx = int ((52.083-52)*16)= 1
UCA0BR0 = 52; // 8000000/16/9600
UCA0BR1 = 0x00;
UCA0MCTLW = 0x4900 | UCOS16 | UCBRF_1;
UCA0CTLW0 &=~UCSWRST; //初始化 eUSCI
UCA0IE |= UCRXIE; //启用 USCI_A0 RX 中断
//配置 ADC12
ADCCTL0 |= ADCSHT_2 | ADCON; // ADCON,S&H=16 ADC CLKS
ADCCTL1 |= ADCSHP; // ADCCLK = MODOSC;采样计时器
ADCCTL2 &=~ADCRES; //清除 ADCCTL
ADCCTL2中的 ADCRES |= ADCRES_2; // 12位转换结果
ADCMCTL0 |= ADCINCH_1; // A1 ADC 输入选择;Vref=DVCC
ADCIE |= ADCIE0; //启用 ADC 转换完成中断
while (1)
{
ADCCTL0 |= ADCENC | ADCSC; //采样和转换开始
_bis_SR_register (LPM0_bits | GIE); // LPM0、ADC_ISR 将强制退出
__no_operation(); //仅用于调试
如果(ADC_RESULT < 0x7FF)
P1OUT &=~BIT0; //清除 P1.0 LED 关闭
其他
P1OUT |= BIT0; //将 P1.0 LED 设置为打开
__DELAY_CYCLLES (5000);
}
//
计时器 A0中断服务例程
#if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
#pragma vector = TIMER0_A0_Vector
__interrupt void Timer_A (void)
#Elif Defined (__GNU__)
_ TIMER0_RATOR
(void)(void Timer_A)(void Timer_error)(void Timer_)(void Timer_timer 0_interrupt)(void Timer_)(void Timer_)(
#endif
{
UCA0TXBUF=ADC_Result;
_delay_cycles (5000);
UCA0TXBUF=ADC_RESULT<<8;
TA0CCR0 = 50000; //将偏移添加到 TACCR0
}
void Software_Trim ()
{
unsigned int oldDcotTap = 0xFFFF;
unsigned int newDcoTap = 0xFFFF;
unsigned int newDcoDelta = 0xFFFF;
unsigned int bestDcoDelta = 0xFFFF;
unsigned int csCtl0Copy = 0;
unsigned int csCtl1Copy = 0;
无符号 int csCtl0Read = 0;
无符号 int csCtl1Read = 0;
unsigned int dcoFreqTrim = 3;
unsigned char endLoop = 0;
操作
{
CSCTL0 = 0x100; // DCO 抽头= 256
操作
{
CSCTL7 &=~DCOFFG; //清除 DCO 故障标志
} while (CSCTL7 & DCOFFG); //测试 DCO 故障标志
__DELAY_CYCLLES ((unsigned int) 3000 * MCLK_FREQ_MHz);//等待 FLL 锁定状态(FLLUNLOCK)保持稳定
//建议等待24个经过分频的 FLL 参考时钟周期
while (((CSCTL7 &(FLLUNLOCK0 | FLLUNLOCK1))和&((CSCTL7 & DCOFFG)= 0));
CSCCtl0Read = CSCTL0; //读取 CSCTL0
CSCCtl1Read = CSCTL1; //读取 CSCTL1
oldDcoTap = newDcoTap; //记录上次的 DCOTAP 值
NewDcoTap = csCtl0Read & 0x01ff; //获取此次的 DCOTAP 值
dcoFreqTrim =(csCtl1Read & 0x0070)>>4;//获取 DCOFTRIM 值
if (newDcoTap < 256) // DCOTAP < 256
{
newDcoDelta = 256 - newDcoTap; // DCPTAP 和256之间的增量值
if ((oldDcotap!= 0xFFFF)&&(oldDcotap >= 256)// DCOTAP 交叉256
endLoop = 1; //停止 while 循环
其他
{
dcoFreqTrim --;
CSCTL1 =(csCtl1Read &(~DCOFTRIM))|(dcoFreqTrim<4);
}
}
其他 // DCOTAP >= 256
{
newDcoDelta = newDcoTap - 256; // DCPTAP 和256之间的增量值
if (oldDcoTap < 256) // DCOTAP 交叉256
endLoop = 1; //停止 while 循环
其他
{
dcoFreqTrim++;
CSCTL1 =(csCtl1Read &(~DCOFTRIM))|(dcoFreqTrim<4);
}
}
if (newDcoDelta < bestDcoDelta) //记录最接近256的 DCOTAP
{
csCtl0Copy = csCtl0Read;
csCtl1Copy = csCtl1Read;
bestDcoDelta = newDcoDelta;
}
}while (endLoop =0); //轮询直至 endLoop = 1
CSCTL0 = csCtl0Copy; //重新加载锁定的 DCOTAP
CSCTL1 = csCtl1Copy; //重新加载锁定的 DCOFTRIM
while (CSCTL7 &(FLLUNLOCK0 | FLLUNLOCK1));//轮询直到 FLL 被锁定
}
void Init_GPIO ()
{
P1DIR = 0xFF;P2DIR = 0xFF;
P1REN = 0xFF;P2REN = 0xFF;
P1OUT = 0x00;P2OUT = 0x00;
}
// ADC 中断服务例程
#if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
#pragma vector=ADC_vector
__interrupt void ADC_ISR (void)
#Elif defined (__GNU_)
_ define (__ENTI_COMPRESSIR_)#_ERROR (void ADC_COMPLETOR
)(void)(void)(void)(void ADC_ERROR)(void!
#endif
{
switch (__evo_in_range (ADCIV、ADCIV_ADCIFG))
{
案例 ADCIV_NONE:
中断;
ADCIV_ADCOVIFG 案例:
中断;
案例 ADCIV_ADCTOVIFG:
中断;
ADCIV_ADCHIIFG 案例:
中断;
ADCIV_ADCLOIFG 案例:
中断;
ADCIV_ADCINIFG 案例:
中断;
ADCIV_ADCIFG 案例:
ADC_RESULT = ADCMEM0;
_BIC_SR_REGISTER_ON_EXIT (LPM0_BITS); //从 LPM0清除 CPUOFF 位
中断;
默认值:
中断;
}
}
MATLAB 代码:
清除所有
CLC;
如果~IsEmpty (instrfind)
fclose (instrfind);
delete (instrfind);
end
s = serial ('COM5'、'baudate'、9600、'timeout'、10、'Terminal'、'lf');
fopen (s);
n=1:1000;
y=1:1000;
shg
(1
:1:1000)、yclose (i)(1:1:1:1:1)(
1)(1)(yclose)(1:1)、yout (1:1)(1)(1:1)(1)(1)(1)(1:1)(1)(1)(yclose)(1)(1:1)(1)(1)(1