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.
工具/软件:Code Composer Studio
您好!
我的项目的目标是使用 MSP430的 PWM 和集成的12 b ADC 实现0-1A 的可编程电流吸收、以完成控制环路。
我最近能够重新创建我的仿真(附加)和下面的代码、以便在 INA250上输出正确的电压、从而测量通过负载电阻器的电流。
我对将 INA250的电压读取到 ADC 有疑问。 当我使用外部直流电源独立运行代码时、ADC 能够读取引脚上的电压。
尽管当我将 INA 250 EVM 的输出连接到 ADC 的输入(使用 DMM 验证电压是否正确)时、ADCMEM0中的电压不正确。
粘贴的代码以及外部电路的 TINA 仿真。
#include
float ADC_val;
int Current_add;
所需的浮点电压;
float CURRENT_SET;
float CURRENT_t;
浮点 Duty_Cycle;
float CURRENT_val;
int PWM_UP;
浮点 Voltage_val;
浮点 ADC (空)
{
WDTCTL = WDTPW | WDTHOLD;//停止 WDT
// GPIO 设置
P4OUT &=~BIT6;//清除 LED 以启动
P4DIR |= BIT6;//将 P1.0/LED 设置为输出
P1SEL1 |= BIT5;//为 ADC 配置 P1.1
P1SEL0 |= BIT5;
//禁用 GPIO 上电默认高阻抗模式以激活
//先前配置的端口设置
PM5CTL0 &=~LOCKLPM5;
//配置 ADC12
ADC12CTL0 = ADC12SHT0_2 | ADC12ON;//采样时间、S&H=16、ADC12打开
ADC12CTL1 = ADC12SHP;//使用采样计时器
ADC12CTL2 |= ADC12RES_2;// 12位转换结果
ADC12MCTL0 |= ADC12INCH_5;// A1 ADC 输入选择;Vref=AVCC
ADC12IER0 |= ADC12IE0;//启用 ADC 转换完成中断
while (1)
{
_delay_cycles (5000);
ADC12CTL0 |= ADC12ENC | ADC12SC;//开始采样/转换
_bis_SR_register (LPM0_bits | GIE);// LPM0、ADC12_ISR 将强制退出
__no_operation();//用于调试器
}
}
int main (空)
{
WDTCTL = WDTPW | WDTHOLD;//停止 WDT
//配置 GPIO
P1DIR |= BIT0 | BIT1;// P1.0和 P1.1输出
P1SEL0 |= BIT0 | BIT1;// P1.0和 P1.1选项选择
// P1IES |= 0x00;
//禁用 GPIO 上电默认高阻抗模式以激活
//先前配置的端口设置
PM5CTL0 &=~LOCKLPM5;
CSCTL0_H = CSKEY >> 8;//解锁 CS 寄存器
CSCTL1 = DCOFSEL_6;//设置 DCO = 8MHz
CSCTL2 = SELA_VLOCLK | SELM_DCOCLK | SELM_DCOCLK;//设置 ACLK=VLO SMCLK=DCO
CSCTL3 = DIVA__2 | DIVM__2;//设置所有分频器
CSCTL0_H = 0;//锁定 CS 寄存器
//配置 Timer0_A
TA0CCR0 = 2000;// PWM 周期
TA0CCTL1 = OUTMOD_7;// CCR1复位/置位
TA0CCR1 = 666;// CCR1 PWM 占空比
TA0CCTL0 = CCIE;// CPC intetupt
TA0CTL = tassel_SMCLK | MC__UP | TACLR;// SMCLK、向上计数模式、清除 TAR
//_bis_SR_register (LPM0_bits);//输入 LPM0
adc ();
}
#if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
#pragma vector = ADC12_vector
_interrupt void ADC12_ISR (void)
#Elif defined (_GNU_)
void __attribute__((interrupt (ADC12_vector)) ADC12_ISR (void)
其他
错误编译器不受支持!
#endif
{
switch (__evo_in_range (ADC12IV、ADC12IV_ADC12RDYIFG))
{
情况 ADC12IV_NONE:break;//向量0:无中断
案例 ADC12IV_ADC12OVIFG:中断;//向量2:ADC12MEMx 溢出
情况 ADC12IV_ADC12TOVIFG:中断;//矢量4:转换时间溢出
ADC12IV_ADC12HIIFG 案例:中断;//向量6:ADC12BHI
案例 ADC12IV_ADC12LOIFG:中断;//向量8:ADC12BLO
ADC12IV_ADC12INIFG 案例:中断;//向量10:ADC12BIN
情况 ADC12IV_ADC12IFG0://向量12:ADC12MEM0中断
CURRENT_SET = 0.03125
;
VOLTGET_DESKLET = CURRENT_SET *2;
ADC_val = ADC12MEM0;
VOLTGE_VAL =(ADC_VAL *3.6)/4096;
Current_val = Voltage_val;
Duty_Cycle =(Voltage_val*2000)/3;
如果(Voltage_val!= Voltage_desired)
{
Duty_Cycle =(Voltage_desired *2000)/3;
}
其他
{
Duty_Cycle = TA0CCR1;
}
TA0CCR1 = Duty_Cycle;
}
}
#if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
#pragma vector = TIMER0_A0_vector
_interrupt void Timer0_A0_ISR (void)
#Elif defined (_GNU_)
void __attribute__((中断(TIMER0_A0_Vector)) Timer0_A0_ISR (void)
其他
错误编译器不受支持!
#endif
{
如果(PWM_UP = 1)
TA0CCR1 = x;
PWM_UP = 0;
}
感谢您的支持!
Connor Connaughton
你好 Connor
您可以使用我们的演示代码来查看 ADC 是否可以像 http://dev.ti.com/tirex/explore/node?node=AM6OnzaAOO6rktD8QJ1WwQ__IOGqZri__LATEST 这样获得正确的结果
您可以首先使用万用表测量电压。
输出电压是否稳定? 您能否用示波器测量它?
此致
Gary
您如何知道电压不正确? 您是在引脚上测量还是使用调试器?
我这里没有 TINA 的副本、因此我无法对原理图进行评论。 但是、看起来您使用 ADC 作为反馈来设置特定的 PWM 输出。
按照编码、这个程序将只执行一个 ADC 采样(曾经执行过)、这是因为我看不到一个唤醒来允许 main 请求一个第二个采样。
两个 float-s 之间还有一个"!="比较,这在很大程度上是可以保证的。 因此、PWM 占空比将根据常数(0.3125)设置为2%(约70mV)、这将保持不变、因为不会再有任何 ADC 样本。 我猜(?) 这将改变引脚上的实际电压。
我怀疑这不是您的预期工作方式、但我不确定建议什么、因为我不知道所有常量的含义。
Bruce、
感谢你的答复。
我一直使用示波器在读取 ADC (引脚1.5)的位置进行测量、然后读取 ADCMEM0以获得 ADC 十进制值、在这里我通过执行(3.6*ADC)/4096转换为可读电压。
正确的、我必须创建一个简单的控制环路、该环路从 INA 250获取 ADC 电压、并根据我设置的电压分别更改占空比。
您能否澄清一下"看不到唤醒"对 ADC 的意义?
至于对浮点数进行比较、是的、谢谢您的回答。 我比较浮点数的原因是为了确保我可以获得 ADC 的1.75V 输入、并将其转换为其各自的占空比。
变量定义:
CURRENT_SET =设置我希望输出到负载电阻器的电流
VOLTGET_REGLET =所需的实际电压
ADC_val = ADC12MEM0;
VOLTGE_Val =(ADC_VAL*3.6)/4096 =进入 ADC 的电压
Current_val = Voltage_val;
Duty_Cycle =(Voltage_val*2000)/3;
如果您有任何其他问题、请告诉我。
感谢您的支持!
Connor Connaughton
我希望在您的 ADC ISR 中看到类似"LPM0_EXIT"的内容来唤醒 ADC()。 否则、它将永远处于 LPM 中、永远不会启动另一个 ADC 转换。
您在引脚上测量了什么电压、您在 MEM0中看到了什么值?
未经请求:您正在 ISR 中执行大量的浮点算术运算、这意味着在(估计)几十毫秒内不会运行任何其他运算。 目前、您的程序没有其他要做的事情、因此它不会妨碍您的工作。 但是、当您添加到程序时、这将无法很好地进行扩展。 我建议您将算术移动到 adc ()。
Bruce、
谢谢! 我添加了__BIC_SR_REGISTER_ON_EXIT (LPM0_BITS);//在 ADC_ISR 结束时退出活动 CPU,它运行正常!
至于 ISR 中的算术、这是我真正需要的唯一函数、因此我现在要将其保留在 ISR 中、因为我不会添加到程序中、
感谢您的帮助!
Connor Connaughton