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.
工具与软件:
我将使用 f28003x 的"adc ex1"示例、并尝试使用相同的 ePWM 触发器来触发另一个 ADC (A1)。
(表示:将多个 SOC 配置为使用同一触发器可使触发器生成转换序列。)
测试结果表明、即使未增加功率、ADC (A1)引脚也具有电压值。 (ADC (A0)同时具有3.3V 电压)
我想知道这是由哪一行程序设置引起的、还是不添加程序设置引起的?
请帮助我专家,谢谢。
代码:
//
//包含的文件
//
#include "F28x_PROJECT.h"
//
//定义
//
#define results_buffer_size 256
//
// Globals (全局变量)
//
uint16_t adcAResults[Results_buffer_size];// Buffer for Results
uint16_t index;//结果缓冲器索引
volatile uint16_t bufferFull;//表示缓冲区已满的标志
unsigned int ADC_A1;
悬空 ADC_A1_Voltage;
unsigned int ADC_A2;
悬空 ADC_A2_Voltage;
//
//函数原型
//
void initADC (void);
void initEPWM1 (void);
void initADCSOC (void);
_interrupt void adcA1ISR (void);
//
// Main (主菜单)
//
void main (void)
{
//
//初始化器件时钟和外设
//
InitSysCtrl();
//
//初始化 GPIO
//
InitGpio();
EALLOW;
GpioCtrlRegs.GPAPUD.bit.GPIO20=0;// Disable pull-up res. 引脚
GpioCtrlRegs.GPAMUX2.bit.GPIO20=0;
GpioCtrlRegs.GPADIR.bit.GPIO20=1;// Configure GPIO20 direction
EDIS;
//
//禁用 CPU 中断
//
颜色;
//
//将 PIE 控制寄存器初始化为默认状态。
//默认状态是禁用所有 PIE 中断并显示标志
//被清除。
//
InitPieCtrl();
//
//禁用 CPU 中断并清除所有 CPU 中断标志:
//
IER = 0x0000;
IFR = 0x0000;
//
//使用指向 shell 中断的指针初始化 PIE 矢量表
//服务例程(ISR)。
//
InitPieVectTable();
//
//映射 ISR 函数
//
EALLOW;
PieVectTable。 ADCA1_INT =&adcA1ISR;// ADCA 中断1的函数
EDIS;
//
//配置 ADC 并为其上电
//
initADC();
//
//配置 ePWM
//
initEPWM1();
//
//将 ADC 设置为通道1上的 EPWM 触发转换
//
initADCSOC();
//
//启用全局中断和更高优先级的实时调试事件:
//
IER |= M_INT1;//启用组1中断
EINT;//启用全局中断 INTM
erTM;//启用全局实时中断 DBGM
for (index = 0;index < results_buffer_size;index++)
{
adcAResults[index]= 0;
}
索引= 0;
bufferFull = 0;
//
//启用 PIE 中断
//
PieCtrlRegs.PIEIER1.bit.INTx1 = 1;
//
//同步 ePWM
//
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
//
//在循环中无限期地进行转换
//
while (1){
}
}
//
// initADC -用于配置 ADCA 并为其加电的函数。
//
void initADC (void){
//
//将 VREF 设置为内部
//
SetVREF (ADC_ADCA、ADC_INTERNAL、ADC_VREF3P3);
EALLOW;
//
//将 ADCCLK 分频器设置为/4
//
AdcaRegs.ADCCTL2.bit.prescale = 6;
//
//将脉冲位置设置为较晚
//
AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;
//
//给 ADC 上电、然后延迟1 ms
//
AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
EDIS;
DELAY_US (1000);
}
//
// initEPWM -用于配置 ePWM1以生成 SOC 的函数。
//
void initEPWM1 (void){
EALLOW;
//../../--------------- EPWM1 ------------------------------------------------------- //
//设置 GPIO ----------------------------------------------------------- //
GpioCtrlRegs.GPAPUD.bit.GPIO0=1;// Disable pull-up res. 引脚
GpioCtrlRegs.GPAMUX1.bit.GPIO0=1;//将 GPIO0配置为 EPWM1A
GpioCtrlRegs.GPAPUD.bit.GPIO1=1;// Disable pull-up res. 运行
GpioCtrlRegs.GPAMUX1.bit.GPIO1=1;//将 GPIO1配置为 EPWM1B
//设置时基(TB)子模块------------------------------------------------------- //
//配置 EPWM1的频率和占空比
EPwm1Regs.TBPRD = 1200;//设置周期计数
EPwm1Regs.CMPA.bit.CMPA = 0;//设置比较值
//设置 TBCLK
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;// Set TBCLKSYNC = 1
CpuSysRegs.PCLKCR2.bit.EPWM1 = 1;// Enable ePWM module clocks in the PCLKCRx register (在 PCLKCRx 寄存器中启用 ePWM 模块时钟)
// TBCLK = EPWMCLK /(HSPCLKDIV * CLKDIV)
EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0;
EPwm1Regs.TBCTL.bit.CLKDIV = 0;
//计数器模式
EPwm1Regs.TBCTL.bit.CTRMODE = 2;//(2) Count up-down
// ePWM 相位设置
EPwm1Regs.TBCTL.bit.PHSEN = 0;//(0) Disable phase loading (禁用相位加载)
EPwm1Regs.TBPHS.bit.TBPHS = 0;// Phase 为0
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
EPwm1Regs.TBCTR = 0;
//EPwm1Regs.EPWMSYNCOUTEN.bit.ZEROEN = 1;
//设置计数器-比较(CC)子模块------------------------------------------------------- //
EPwm1Regs.CMPCTL.bit.SHDWAMODE = 0;// Load registers every zero (加载寄存器每零一次)
EPwm1Regs.CMPCTL.bit.SHDWBMODE = 0;
EPwm1Regs.CMPCTL.bit.LOADAMODE = 0;
EPwm1Regs.CMPCTL.bit.LOADBMODE = 0;
//设置动作限定符(AQ)子模块------------------------------------------------------- //
EPwm1Regs.AQCTLA.bit.CAU = 2;//当 TBCTR = 0时执行操作;2:强制 EPWM1A 输出高电平。
EPwm1Regs.AQCTLA.bit.CAD = 1;//当 TBCTR = CMPA 时执行的操作;1:强制 EPWM1A 输出为低电平。
EPwm1Regs.AQCTLA.bit.CBU = 1;//当 TBCTR = CMPA 时执行的操作;2:强制 EPWM1B 输出高电平。
EPwm1Regs.AQCTLA.bit.CBD = 2;//当 TBCTR = CMPA 时执行的操作;1:强制 EPWM1B 输出为低电平。
//事件触发和中断(ET)子模块:
EPwm1Regs.ETSEL.bit.SOCAEN = 1;// Enable SOCA
EPwm1Regs.ETSEL.bit.SOCASEL = 1;// 001:启用等于零的事件时基计数器
EPwm1Regs.ETPS.bit.SOCAPRD = 1;//在发生第1个事件时生成脉冲
EDIS;
}
//
// initADCSOC -用于将 ADCA 的 SOC0配置为由 ePWM1触发的函数。
//
void initADCSOC (void){
//
//选择要转换的通道以及转换结束标志
//
EALLOW;
AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0;// SOC0将转换引脚 A0
// 0:A0 1:A1 2:A2 3:A3
// 4:A4 5:A5 6:A6 7:A7
// 8:A8 9:A9 A:A10 B:A11
// C:A12 D:A13 E:A14 F:A15
AdcaRegs.ADCSOC0CTL.bit.ACQPS = 9;//采样窗口为10个 SYSCLK 周期
AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5;// Trigger on ePWM1 SOCA
AdcaRegs.ADCSOC1CTL.bit.CHSEL = 1;// SOC0将转换引脚 A1
// 0:A0 1:A1 2:A2 3:A3
// 4:A4 5:A5 6:A6 7:A7
// 8:A8 9:A9 A:A10 B:A11
// C:A12 D:A13 E:A14 F:A15
AdcaRegs.ADCSOC1CTL.bit.ACQPS = 9;//采样窗口为10个 SYSCLK 周期
AdcaRegs.ADCSOC1CTL.bit.TRIGSEL = 5;// Trigger on ePWM1 SOCA
AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0;// SOC0 end of SOC0将设置 INT1标志
// AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 1;// SOC0 end of SOC0将设置 INT1标志
AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;// Enable INT1 flag (启用 INT1标志)
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//确保 INT1标志被清除
EDIS;
}
//
// adcA1ISR—ADC A 中断1 ISR
//
_interrupt void adcA1ISR (void){
//
//将最新结果添加到缓冲区
// ADCRESULT0是 SOC0的结果寄存器
GpioDataRegs.GPATOGGLE.bit.GPIO20 = 1;
DacaRegs.DACVALS.bit.DACVALS = 4095;
//
//如果缓冲区已满、则设置 bufferFull 标志
//
ADC_A1 = AdcaResultRegs。 ADCRESULT0;
ADC_A1_Voltage =(float)(ADC_A1/4095.0)* 3.3;
ADC_A2 = AdcaResultRegs。 ADCRESULT1;
ADC_A2_Voltage =(float)(ADC_A2/4095.0)* 3.3;
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;// Clear INT1 flag (清除 INT1标志)
PieCtrlRegs.PIEACK.all = PIEACK_Group1;//确认中断
}
//
//结束文件
//
蔡义轩
感谢您发布查询。
看一下我看到您正在 配置 DAC 的代码
DacaRegs.DACVALS.bit.DACVALS = 4095;
DACA 的输出来自 A0。 您是否可以尝试删除此内容并再次检查 A0输入。
我还可以知道您使用什么硬件来测试它、LaunchPad 或定制硬件吗?
谢谢!
Nilesh
InitGpio();
EALLOW;
GpioCtrlRegs.GPAPUD.bit.GPIO20=0;// Disable pull-up res. 引脚
GpioCtrlRegs.GPAMUX2.bit.GPIO20=0;
GpioCtrlRegs.GPADIR.bit.GPIO20=1;// Configure GPIO20 direction
EDIS;
ADC 引脚(A1、A2)模拟 GPIO 输入的配置位置是什么? 注意、我们可以为轮询或高优先级采样配置 ADC 输入优先级。
// set priority of SOCs ADC-SOC 11,12,13's ADC_setSOCPriority(obj->adcHandle[0], ADC_PRI_ALL_ROUND_ROBIN); //ADCA: ADC_PRI_ALL_HIPRI ADC_PRI_SOC11_HIPRI ADC_setSOCPriority(obj->adcHandle[1], ADC_PRI_ALL_ROUND_ROBIN); //ADCA: ADC_PRI_ALL_HIPRI ADC_PRI_SOC13_HIPRI ADC_setSOCPriority(obj->adcHandle[2], ADC_PRI_ALL_ROUND_ROBIN); //ADCB: ADC_PRI_ALL_HIPRI ADC_PRI_SOC12_HIPRI
尊敬的 Genatco:
感谢您的回复。
对不起,我不能理解你告诉我的一些事情。
上面复制的程序就是我用来显示 ADC 中断是否工作正常的程序。 (用于显示示波器的波形)
1.我知道 在配置 ADC 之前不需要配置 GPIO。 (如果我错了、请更正我。 或者我误解了...)
2.我尝试 在程序中配置 ADC 的优先级、但结果不正确。
此致。
蔡逸轩
尊敬的 Nilesh:
感谢您的回复。
1.程序"DacaRegs.DACVALS.bit.DACVALS = 4095;"可能不是 必需的。
我 删除了它并重试、但结果值 不正确。 (ADC_A2_Voltage 应为0)
2.我试图测试同一个触发条件(例如:PWM1)来触发 SOC 的序列(例如:SOC0、SOC1)。
但测试结果是 SOC0之后的值正确、但使用下面的 SOC1之后的值。
我真的想 知道问题在哪里。
"ADC_EX10_MULTIPLE SoC_EPWM"是我需要的函数、但程序表示法不是我需要的、我也无法在电路板上工作。
此致。
蔡逸轩
1. 我知道的功能是 在配置 ADC 之前不需要配置 GPIO。 (如果我错了、请更正我。 或者我误解了...)
正确、模拟多路复用器(检查 x39c TRM) ADC 输入与 Booster 接头上的 GPIO 和 SOC 相关、以确保正确的 ADC 通道。 SoC 配置必须指明与升压器接头引脚相关的输入通道编号。 检查 LaunchPad 引脚多路复用器卡和原理图、以确保信号针对 ADC 输入正确布线。
我想 C2000 TRM 在 POR 上指出了所有 GPIO 的默认输入。 然后、LaunchPad 上的开关会将一些 GPIO Booster 接头引脚重定向到特定外设。 如果输入端未使用分压器、并且同一 ADCx 上的某些 ADC 输入可能会悬空3V3、则可能需要在其中一个 ADC 输入上添加下拉电阻器。
我在您的代码中没有找到 ADC 通道的 SOC 中断源、只是配置了中断处理程序。 中断处理程序必须清除顶部的中断源、并在退出函数之前清除 ACK 组。
ADC_setInterruptSource (ADC_INT_BASE、ADC_INT_NUM、ADC_INT_SOC);
上面的 Nelish 指出中断处理程序中的 DACA 输出与 ADC A0输入争用。 模拟子系统表可能不同的 x39c TRM。
尊敬的 Genatco:
1.您告诉我的有关"如果输入端未使用分压器、则可能需要在其中一个 ADC 输入端添加下拉电阻、并且同一 ADCx 上的某些 ADC 输入端可能会悬空3V3"。 是 正确的!!!
我忘记了一些非常重要和简单的东西,这让我感到尴尬。
在使用下拉电阻器后、ADC 的值正确。
2.以及"ADC_setInterruptSource (ADC_INT_BASE、ADC_INT_NUM、ADC_INT_SOC);"
对应于我的程序上面的三行:
AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0;// SOC0 end of SOC0将设置 INT1标志
// AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 1;// SOC0 end of SOC0将设置 INT1标志
AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;// Enable INT1 flag (启用 INT1标志)
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//确保 INT1标志被清除
将
该值必须更改为1、因为 SOC 在 SOC1处结束
SOC1AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 1;
感谢您帮助我解决这个问题。
此致。
蔡逸轩