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.
Hi guys~
I am working on a project using the TMS320F28379D microcontroller and facing an issue where the ADC interrupt is not being triggered as expected. Below is a brief overview of the problem and the steps I've taken to troubleshoot:
Problem Statement:
adcA1ISR
) to trigger.while(ADC_getInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1) == false) { }
SCISendData("ADC conversion complete\r\n");
Attempts Made:
INT_ADCA1
.Interrupt_register(INT_ADCA1, adcA1ISR);
and enabled it with Interrupt_enable(INT_ADCA1);
.EINT;
.adcA1ISR
to confirm if it's being triggered, which it isn't.Despite these efforts, the ADC interrupt service routine does not seem to trigger, and I am unable to identify the cause.
Additional Context:
Any insights or suggestions on resolving this issue would be greatly appreciated.
#include "F2837xD_Ipc_drivers.h" #include "driverlib.h" #include "device.h" #include "stdio.h" #include "string.h" #include "led.h" #include "key.h" #include "sci.h" #include "micro_printf.h" #include "board.h" #include "spi_test_v1.h" #define delay_s(x) SysCtl_delay(((((long double)(x)) / (1.0L / \ (long double)DEVICE_SYSCLK_FREQ)) - 9.0L) / 5.0L) #define delay_ms(x) SysCtl_delay(((((long double)(x)) / (1000.0L / \ (long double)DEVICE_SYSCLK_FREQ)) - 9.0L) / 5.0L) #define delay_us(x) SysCtl_delay(((((long double)(x)) / (1000000.0L / \ (long double)DEVICE_SYSCLK_FREQ)) - 9.0L) / 5.0L) uint16_t KEY_Value = 0; //int aaa =9876; //uint32_t ccc =0; //float bbb =22.22; void main(void) { //确定运行模式 #ifdef _STANDALONE #ifdef _FLASH IPCBootCPU2(C1C2_BROM_BOOTMODE_BOOT_FROM_FLASH); #else IPCBootCPU2(C1C2_BROM_BOOTMODE_BOOT_FROM_RAM); #endif #endif //设备初始化 关闭了大部分外设,需要用到再去开 Device_init(); //GPIO初始化 Device_initGPIO(); initADC(); Interrupt_initModule();//初始化PIE并清除PIE寄存器。禁用CPU中断。 Interrupt_initVectorTable();//用指向shell Interrupt的指针初始化PIE向量表 Board_init(); Interrupt_register(INT_ADCA1, adcA1ISR); // 确保使用与您的硬件相匹配的中断号(for test) // 使能ADC中断并确认 Interrupt_enable(INT_ADCA1); //for test EINT; // SCISendData("ADC Interrupt enabled\r\n"); // SCISendData("Interrupt registered\r\n"); // Interrupt_enableMaster(); //开启总中断 //开启总中断 // Interrupt_enableMaster(); //LED初始化函数 LED_Init(); //KEY初始化 KEY_Init(); //按键初始化函数 spi_initController(); // 调用spi_test.c中的初始化函数 SCISendData("3.System initialization complete\r\n"); LED1_OFF; LED2_OFF; while(1) { //ccc = Float_to_u32(bbb); //micro_print("hello %d %f\r\n",aaa,ccc); spi_updateController(); // 更新 SPI 控制器状态 // 获取当前温度 // short currentTemperature = read_current_temperature(); // 打印温度和其他信息 // micro_print("Temperature: %d %f\r\n", currentTemperature); delay_ms(1000); LED2_TOGGLE; KEY_Value = KEY_Scan(1); if(KEY_Value == KEY1_PRES) { LED1_ON; LED2_OFF; } else if(KEY_Value == KEY2_PRES) { LED2_ON; LED1_OFF; } } }
#include "driverlib.h"
#include "device.h"
#include "board.h"
#include <stdio.h>
// 添加您的其他必要的头文件
#define MAX_DAC_VALUE 4095 // 假设DAC是12位的
#define MIN_DAC_VALUE 0
//__interrupt void sciaTXFIFOISR(void);
//__interrupt void sciaRXFIFOISR(void);
uint16_t adcResult;
float temperature;
void SPI_GPIO_Init();
void spi_init();
void spi_TX(uint16_t data);
uint16_t calculate_DAC_value(float voltage);
short read_current_temperature();
void initADC();
void initADCSOC();
void initEPWM();
//__interrupt void adcA1ISR();
//void initSCI(void);
void SCISendData(const char *string);
// PI Controller Variables
volatile short tsvo_pg, tsvo_ig; // Proportional Gain (PG) and Integral Gain (IG)
volatile short tsvo_setpoint, tsvo_err, tsvo_out;
volatile long tsvo_acc, tsvo_mem;
void spi_initController() {
Device_init();
Device_initGPIO();
//initSCI(); // 初始化SCI
initADC();
initADCSOC(); // 初始化ADC
initEPWM(); // 初始化ePWM
DINT;
SPI_GPIO_Init();
spi_init();
// 初始化PI控制器的参数
tsvo_pg = 2000; // Proportional Gain
tsvo_ig = 200; // Integral Gain
tsvo_mem = 0; // Integral memory initialization
float target_temperature = 60.0; // 目标温度60°C
tsvo_setpoint = calculate_DAC_value(target_temperature); // 设定点
}
void spi_updateController() {
// short read_current_temperature = 59;
short currentTemperature = read_current_temperature();
tsvo_err = tsvo_setpoint - read_current_temperature();
tsvo_acc = tsvo_err * tsvo_pg;
tsvo_acc += tsvo_mem;
tsvo_out = tsvo_acc >> 16;
if (tsvo_out > MAX_DAC_VALUE) tsvo_out = MAX_DAC_VALUE;
if (tsvo_out < MIN_DAC_VALUE) tsvo_out = MIN_DAC_VALUE;
spi_TX(tsvo_out);
tsvo_mem += tsvo_err * tsvo_ig;
// 打印当前温度
char tempStr[32];
// sprintf(tempStr, "Current Temp: %d\r\n", currentTemperature);
sprintf(tempStr, "Temperature: %d\r\n", currentTemperature);
// sprintf(tempStr, "Temperature: 60\r\n");
SCISendData(tempStr);
//SCISendData("Hello World\r\n");
// 检查SCI接收缓冲区
//if(SCI_getRxFIFOStatus(SCIA_BASE) > SCI_FIFO_RX0) {
//char receivedChar = SCI_readCharNonBlocking(SCIA_BASE);
// 处理接收到的字符
// 例如:回显接收到的字符
//char echoStr[2] = {receivedChar, '\0'};
//SCISendData(echoStr);
//}
DEVICE_DELAY_US(40000);
}
void SPI_GPIO_Init() {
// GPIO配置代码保持不变
}
void spi_init() {
// SPI配置代码保持不变
}
void spi_TX(uint16_t data) {
// SPI发送代码保持不变
}
uint16_t calculate_DAC_value(float voltage) {
float maxVoltage = 3.7; // 最大电压为3.7伏特
// 确保输入电压不超出范围
if (voltage < 0) {
voltage = 0;
} else if (voltage > maxVoltage) {
voltage = maxVoltage;
}
// 将电压值映射到DAC值
uint16_t dacValue = (uint16_t)((voltage / maxVoltage) * MAX_DAC_VALUE);
return dacValue;
}
short read_current_temperature() {
// 触发ADC转换
ADC_forceSOC(ADCA_BASE, ADC_SOC_NUMBER0);
SCISendData("4.ADC conversion triggered\r\n");
// 等待转换完成
while(ADC_getInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1) == false) {
}
SCISendData("5.ADC conversion complete\r\n");
// 读取ADC转换结果
adcResult = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER0);
char adcResultStr[50];
sprintf(adcResultStr, "ADC Result: %d\r\n", adcResult);
SCISendData(adcResultStr);
// 将ADC结果转换为温度值
temperature = ADC_getTemperatureC(adcResult, 3.0f);
// 将温度值转换为DAC值
return calculate_DAC_value(temperature);
}
void initADC()
{
// SCISendData("1Starting ADC initialization\r\n");
//
// Set ADCDLK divider to /4
//
ADC_setPrescaler(ADCA_BASE, ADC_CLK_DIV_4_0);
//
// Set resolution and signal mode (see #defines above) and load
// corresponding trims.
//
ADC_setMode(ADCA_BASE, ADC_RESOLUTION_12BIT, ADC_MODE_SINGLE_ENDED);
//
// Set pulse positions to late
//
ADC_setInterruptPulseMode(ADCA_BASE, ADC_PULSE_END_OF_CONV);
//
// Power up the ADC and then delay for 1 ms
//
ADC_enableConverter(ADCA_BASE);
DEVICE_DELAY_US(1000);
SCISendData("1.ADC initialization complete\r\n");
}
void initADCSOC() {
// SCISendData("3Starting ADC SOC initialization\r\n");
// ADC SOC配置代码
// 从adc_ex3_temp_sensor.c文件中复制对应的配置代码
ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM1_SOCA, ADC_CH_ADCIN13, 140);
// char message[100];
// sprintf(message, "ADC_SOC_NUMBER0: %d, ADC_TRIGGER_EPWM1_SOCA: %d, ADC_CH_ADCIN13: %d\r\n", ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM1_SOCA, ADC_CH_ADCIN13);
// SCISendData(message);
// SCISendData("ADC SOC setup complete\r\n");
ADC_setInterruptSource(ADCA_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER0);
// SCISendData("ADC interrupt source set\r\n");
ADC_enableInterrupt(ADCA_BASE, ADC_INT_NUMBER1);
// SCISendData("ADC interrupt enabled\r\n");
ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);
// SCISendData("ADC interrupt status cleared\r\n");
SCISendData("2.ADC SOC initialization complete\r\n");
}
void initEPWM() {
// ePWM初始化代码
// 从adc_ex3_temp_sensor.c文件中复制对应的配置代码
EPWM_disableADCTrigger(EPWM1_BASE, EPWM_SOC_A);
EPWM_setADCTriggerSource(EPWM1_BASE, EPWM_SOC_A, EPWM_SOC_TBCTR_U_CMPA);
EPWM_setADCTriggerEventPrescale(EPWM1_BASE, EPWM_SOC_A, 1);
EPWM_setCounterCompareValue(EPWM1_BASE, EPWM_COUNTER_COMPARE_A, 1000);
EPWM_setTimeBasePeriod(EPWM1_BASE, 1999);
EPWM_setClockPrescaler(EPWM1_BASE, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1);
EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_STOP_FREEZE);
}
__interrupt void adcA1ISR()
{
//
// Read the raw result
//
SCISendData("ADC ISR triggered\r\n");
adcResult = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER0);
//
// Convert the result to a temperature in degrees C
//
temperature = ADC_getTemperatureC(adcResult, 3.0f);
//
// Clear the interrupt flag
//
ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);
//
// Check if overflow has occurred
//
if(true == ADC_getInterruptOverflowStatus(ADCA_BASE, ADC_INT_NUMBER1))
{
ADC_clearInterruptOverflowStatus(ADCA_BASE, ADC_INT_NUMBER1);
ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);
}
//
// Acknowledge the interrupt
//
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
}
void SCISendData(const char *string) {
// 使用FIFO发送数据
while (*string != '\0') {
SCI_writeCharBlockingFIFO(SCIA_BASE, *string++);
}
}
for now, sci print is
"1.ADC initialization complete
2.ADC SOC initialization complete
3.System initialization complete
4.ADC conversion triggered
"
SCISendData("5.ADC conversion complete\r\n"); -----》 fail
Hi,
Are you able to zip and send your complete project so I can try to replicate your issue?
Also, could you try using SysConfig to set up your ADC ISR? Since there are several steps for setting up the ADC ISR, it is easy to make a mistake. SysConfig will simplify the process. Please see this lab for the steps needed to setup your ADC ISR with SysConfig: https://dev.ti.com/tirex/explore/node?node=A__AVSjOwDYHkfv9LUHQuulzA__C2000-ACADEMY__3H1LnqB__LATEST
Best Regards,
Ben Collier
//############################################################################# // // FILE: adc_ex3_temp_sensor.c // // TITLE: Sample temperature sensor and convert to temperature // //! \addtogroup driver_example_list //! <h1>ADC Temperature Sensor Conversion</h1> //! //! This example sets up the ePWM to periodically trigger the ADC. The //! ADC converts the internal connection to the temperature sensor, //! which is then interpreted as a temperature by calling the //! ADC_getTemperatureC() function. //! //! \b Watch \b Variables \n //! - \b sensorSample - The raw reading from the temperature sensor //! - \b sensorTemp - The interpretation of the sensor sample as a temperature //! in degrees Celsius. // //############################################################################# // // $Release Date: $ // $Copyright: // Copyright (C) 2013-2023 Texas Instruments Incorporated - http://www.ti.com/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // $ //############################################################################# // // // Included Files // #include "driverlib.h" #include "device.h" // // Globals // uint16_t sensorSample; int16_t sensorTemp; // // Function Prototypes // void initADC(void); void initEPWM(void); void initADCSOC(void); __interrupt void adcA1ISR(void); // // Main // void main(void) { // // Initialize device clock and peripherals // Device_init(); // // Disable pin locks and enable internal pullups. // Device_initGPIO(); // // Initialize PIE and clear PIE registers. Disables CPU interrupts. // Interrupt_initModule(); // // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // Interrupt_initVectorTable(); // // Interrupts that are used in this example are re-mapped to ISR functions // found within this file. // Interrupt_register(INT_ADCA1, &adcA1ISR); // // Set up the ADC and the ePWM and initialize the SOC // initADC(); initEPWM(); initADCSOC(); // // Enable the temperature sensor and give it 500 us to power up // ASysCtl_enableTemperatureSensor(); DEVICE_DELAY_US(500); // // Enable ADC interrupt // Interrupt_enable(INT_ADCA1); // // Enable Global Interrupt (INTM) and realtime interrupt (DBGM) // EINT; ERTM; // // Start ePWM1, enabling SOCA and putting the counter in up-count mode // EPWM_enableADCTrigger(EPWM1_BASE, EPWM_SOC_A); EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_UP); // // Loop indefinitely // while(1) { ; } } // // initADC - Function to configure and power up ADCA. // void initADC(void) { // // Set ADCDLK divider to /4 // ADC_setPrescaler(ADCA_BASE, ADC_CLK_DIV_4_0); // // Set resolution and signal mode (see #defines above) and load // corresponding trims. // ADC_setMode(ADCA_BASE, ADC_RESOLUTION_12BIT, ADC_MODE_SINGLE_ENDED); // // Set pulse positions to late // ADC_setInterruptPulseMode(ADCA_BASE, ADC_PULSE_END_OF_CONV); // // Power up the ADC and then delay for 1 ms // ADC_enableConverter(ADCA_BASE); DEVICE_DELAY_US(1000); } // // initEPWM - Function to configure ePWM1 to generate the SOC. // void initEPWM(void) { // // Disable SOCA // EPWM_disableADCTrigger(EPWM1_BASE, EPWM_SOC_A); // // Configure the SOC to occur on the first up-count event // EPWM_setADCTriggerSource(EPWM1_BASE, EPWM_SOC_A, EPWM_SOC_TBCTR_U_CMPA); EPWM_setADCTriggerEventPrescale(EPWM1_BASE, EPWM_SOC_A, 1); // // Set the compare A value to 1000 and the period to 1999 // Assuming ePWM clock is 100MHz, this would give 50kHz sampling // 50MHz ePWM clock would give 25kHz sampling, etc. // The sample rate can also be modulated by changing the ePWM period // directly (ensure that the compare A value is less than the period). // EPWM_setCounterCompareValue(EPWM1_BASE, EPWM_COUNTER_COMPARE_A, 1000); EPWM_setTimeBasePeriod(EPWM1_BASE, 1999); // // Set the local ePWM module clock divider to /1 // EPWM_setClockPrescaler(EPWM1_BASE, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1); // // Freeze the counter // EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_STOP_FREEZE); } // // initADCSOC - Function to configure ADCA's SOC0 to be triggered by ePWM1. // void initADCSOC(void) { // // Configure SOC0. The temperature sensor is internally connected to A13 // and requires an acquisition time of at least 700 ns. // ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM1_SOCA, ADC_CH_ADCIN13, 140); // // Set SOC0 to set the interrupt 1 flag. Enable the interrupt and make // sure its flag is cleared. // ADC_setInterruptSource(ADCA_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER0); ADC_enableInterrupt(ADCA_BASE, ADC_INT_NUMBER1); ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1); } // // adcA1ISR - ADC A Interrupt 1 ISR // __interrupt void adcA1ISR(void) { // // Read the raw result // sensorSample = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER0); // // Convert the result to a temperature in degrees C // sensorTemp = ADC_getTemperatureC(sensorSample, 3.0f); // // Clear the interrupt flag // ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1); // // Check if overflow has occurred // if(true == ADC_getInterruptOverflowStatus(ADCA_BASE, ADC_INT_NUMBER1)) { ADC_clearInterruptOverflowStatus(ADCA_BASE, ADC_INT_NUMBER1); ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1); } // // Acknowledge the interrupt // Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1); }
In your project, you are using the TI LAUNCHXL-F28379D microcontroller board to control the MAX1978 development board for temperature regulation. The MAX1978 is a thermoelectric cooler (TEC) controller, capable of heating or cooling the TEC. Key components of your project involve Serial Communication Interface (SCI), Serial Peripheral Interface (SPI), Analog-to-Digital Converter (ADC), and Digital-to-Analog Converter (DAC). The TEC control principle relies on the TEC device, which adjusts temperature through varying electric currents. The MAX1978 controller specifically manages the TEC by providing bidirectional current control for precise temperature adjustments. The LAUNCHXL-F28379D microcontroller acts as the central control unit, processing data, executing programs, and controlling the MAX1978, with communication facilitated through SPI and SCI interfaces. SCI is potentially used for communication with external devices or computer systems, while SPI is for interfacing with the MAX1978 or other SPI devices. ADC is utilized to read analog signals, like temperature sensor data, and DAC might be used to generate analog signals to control the MAX1978. Your provided code is likely to contain control logic for initializing hardware interfaces of the microcontroller, reading sensor data, and adjusting the TEC based on temperature feedback. The overall process involves the microcontroller reading temperature data from sensors via ADC, calculating the required heating or cooling based on set and actual temperatures, and adjusting the MAX1978 output through DAC or direct digital controls to regulate the TEC's temperature, with SCI and SPI interfaces for communication with the MAX1978 and other peripherals. Further insights into your code, especially how SPI and SCI interfaces are used, as well as how ADC readings and DAC outputs are handled, would enable more specific assistance.
hope this helpful lol
Part Number: LAUNCHXL-F28379D
Hi guys~
In my project, I am using the TI LAUNCHXL-F28379D microcontroller board to manage a MAX1978 thermoelectric cooler (TEC) controller for accurate temperature control. I employ Serial Communication Interface (SCI) and Serial Peripheral Interface (SPI) for communication, along with Analog-to-Digital Converters (ADC) to read temperature data and Digital-to-Analog Converters (DAC) for adjusting the TEC. My code primarily involves setting up these interfaces, processing sensor information, and regulating the TEC's temperature based on the data received.
I am working on a project using the TMS320F28379D microcontroller and facing an issue where the ADC interrupt is not being triggered as expected. Below is a brief overview of the problem and the steps I've taken to troubleshoot:
Problem Statement:
adcA1ISR
) to trigger.while(ADC_getInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1) == false) { }
SCISendData("ADC conversion complete\r\n"); //no work
Attempts Made:
INT_ADCA1
.Interrupt_register(INT_ADCA1, adcA1ISR);
and enabled it with Interrupt_enable(INT_ADCA1);
.EINT;
.adcA1ISR
to confirm if it's being triggered, which it isn't.Despite these efforts, the ADC interrupt service routine does not seem to trigger, and I am unable to identify the cause.
Additional Context:
Any insights or suggestions on resolving this issue would be greatly appreciated.
ADC module using this example
//############################################################################# // // FILE: adc_ex3_temp_sensor.c // // TITLE: Sample temperature sensor and convert to temperature // //! \addtogroup driver_example_list //! <h1>ADC Temperature Sensor Conversion</h1> //! //! This example sets up the ePWM to periodically trigger the ADC. The //! ADC converts the internal connection to the temperature sensor, //! which is then interpreted as a temperature by calling the //! ADC_getTemperatureC() function. //! //! \b Watch \b Variables \n //! - \b sensorSample - The raw reading from the temperature sensor //! - \b sensorTemp - The interpretation of the sensor sample as a temperature //! in degrees Celsius. // //############################################################################# // // $Release Date: $ // $Copyright: // Copyright (C) 2013-2023 Texas Instruments Incorporated - http://www.ti.com/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // $ //############################################################################# // // // Included Files // #include "driverlib.h" #include "device.h" // // Globals // uint16_t sensorSample; int16_t sensorTemp; // // Function Prototypes // void initADC(void); void initEPWM(void); void initADCSOC(void); __interrupt void adcA1ISR(void); // // Main // void main(void) { // // Initialize device clock and peripherals // Device_init(); // // Disable pin locks and enable internal pullups. // Device_initGPIO(); // // Initialize PIE and clear PIE registers. Disables CPU interrupts. // Interrupt_initModule(); // // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // Interrupt_initVectorTable(); // // Interrupts that are used in this example are re-mapped to ISR functions // found within this file. // Interrupt_register(INT_ADCA1, &adcA1ISR); // // Set up the ADC and the ePWM and initialize the SOC // initADC(); initEPWM(); initADCSOC(); // // Enable the temperature sensor and give it 500 us to power up // ASysCtl_enableTemperatureSensor(); DEVICE_DELAY_US(500); // // Enable ADC interrupt // Interrupt_enable(INT_ADCA1); // // Enable Global Interrupt (INTM) and realtime interrupt (DBGM) // EINT; ERTM; // // Start ePWM1, enabling SOCA and putting the counter in up-count mode // EPWM_enableADCTrigger(EPWM1_BASE, EPWM_SOC_A); EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_UP); // // Loop indefinitely // while(1) { ; } } // // initADC - Function to configure and power up ADCA. // void initADC(void) { // // Set ADCDLK divider to /4 // ADC_setPrescaler(ADCA_BASE, ADC_CLK_DIV_4_0); // // Set resolution and signal mode (see #defines above) and load // corresponding trims. // ADC_setMode(ADCA_BASE, ADC_RESOLUTION_12BIT, ADC_MODE_SINGLE_ENDED); // // Set pulse positions to late // ADC_setInterruptPulseMode(ADCA_BASE, ADC_PULSE_END_OF_CONV); // // Power up the ADC and then delay for 1 ms // ADC_enableConverter(ADCA_BASE); DEVICE_DELAY_US(1000); } // // initEPWM - Function to configure ePWM1 to generate the SOC. // void initEPWM(void) { // // Disable SOCA // EPWM_disableADCTrigger(EPWM1_BASE, EPWM_SOC_A); // // Configure the SOC to occur on the first up-count event // EPWM_setADCTriggerSource(EPWM1_BASE, EPWM_SOC_A, EPWM_SOC_TBCTR_U_CMPA); EPWM_setADCTriggerEventPrescale(EPWM1_BASE, EPWM_SOC_A, 1); // // Set the compare A value to 1000 and the period to 1999 // Assuming ePWM clock is 100MHz, this would give 50kHz sampling // 50MHz ePWM clock would give 25kHz sampling, etc. // The sample rate can also be modulated by changing the ePWM period // directly (ensure that the compare A value is less than the period). // EPWM_setCounterCompareValue(EPWM1_BASE, EPWM_COUNTER_COMPARE_A, 1000); EPWM_setTimeBasePeriod(EPWM1_BASE, 1999); // // Set the local ePWM module clock divider to /1 // EPWM_setClockPrescaler(EPWM1_BASE, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1); // // Freeze the counter // EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_STOP_FREEZE); } // // initADCSOC - Function to configure ADCA's SOC0 to be triggered by ePWM1. // void initADCSOC(void) { // // Configure SOC0. The temperature sensor is internally connected to A13 // and requires an acquisition time of at least 700 ns. // ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM1_SOCA, ADC_CH_ADCIN13, 140); // // Set SOC0 to set the interrupt 1 flag. Enable the interrupt and make // sure its flag is cleared. // ADC_setInterruptSource(ADCA_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER0); ADC_enableInterrupt(ADCA_BASE, ADC_INT_NUMBER1); ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1); } // // adcA1ISR - ADC A Interrupt 1 ISR // __interrupt void adcA1ISR(void) { // // Read the raw result // sensorSample = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER0); // // Convert the result to a temperature in degrees C // sensorTemp = ADC_getTemperatureC(sensorSample, 3.0f); // // Clear the interrupt flag // ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1); // // Check if overflow has occurred // if(true == ADC_getInterruptOverflowStatus(ADCA_BASE, ADC_INT_NUMBER1)) { ADC_clearInterruptOverflowStatus(ADCA_BASE, ADC_INT_NUMBER1); ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1); } // // Acknowledge the interrupt // Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1); }
Hello Nero,
It looks like this is still related to the post you linked here, I will join it with the original since we don't allow duplicate threads to be created (which are already actively being supported).
I use CCS's debug tool, An error was found when trying to run the "short read_current_temperature() {" function using" step into "will point to
"/ / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
//
// Error handling function to be called when an ASSERT is violated
//
/ / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
void __error__(const char *filename, uint32_t line)
{
//
// An ASSERT condition was evaluated as false. You can use the filename and
// line parameters to determine what went wrong.
//
ESTOP0;
}"
Nero,
I am a little confused by the structure of your project. It looks like you have copied many of the driverlib files into your own folder (3.device). Also it looks like you used SysConfig to generate board.h then removed your sysconfig file.
I stepped through your ADC initialization functions and it looks like none of the driverlib ADC functions are working correctly. None of the ADC registers are being written. My guess is that problems are being caused by the driverlib files having been manually copied and pasted in your project. I also do not think that you included the driverlib.lib file.
My suggestion would be to start from the adc_ex3_temp_sensor example (or the lab I linked above if you want to use SysConfig), then slowly add in your code/files. I would not mess with the files listed under "Includes", "device" or the driverlib.lib file unless you have to.
In general, I would suggest that you add to the existing project structure instead of removing things and creating your own, if possible.
Best Regards,
Ben Collier
I apologize for any inconvenience this has given you. I started with a SCI template project provided by a classmate. I'm not familiar with many configurations because I'm new to CCS. The major program I worked on was spi_test_v1.c. The debugging tool reveals that there is an issue with the interrupt.
“void initADC(),void initADCSOC(), void initEPWM() ”work well, but __interrupt void adcA1ISR() fail
Because both two of our senior workers are on leave, working on growth alone is a little difficult. lol
Nero,
It looks like the correct functions to set up the interrupt have been called in the user generated files, but the issue is deeper than a problem with setting up the interrupt. If driverlib functions are not working as expected, then your clocks may not be set up correctly, and peripherals may not be set up correctly.
I have observed that the SOC setup functions are not doing anything. All ADCA registers are still reading only 0. No ADC conversions are ever being done. I am not exactly sure why, but I think it's due to problems with driverlib that are being caused by the project structure. I just checked the EPWM registers and these are not being written as well.
You will need to address the root cause of this issue, which is likely the misbehaving driverlib functions, which is somehow being caused by the project structure. Again, I recommend that you start from a known good example, then add your code.
Best Regards,
Ben Collier
Thank you very much; I agree with you and am attempting to resolve the driverlib issue.