Other Parts Discussed in Thread: TMS320F28379D
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:
- Unable to get the ADC interrupt (specifically
adcA1ISR
) to trigger. - The goal is to make the following code snippet work as expected:
c code
while(ADC_getInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1) == false) { }
SCISendData("ADC conversion complete\r\n");
- Unable to get the ADC interrupt (specifically
-
Attempts Made:
- Checked and ensured correct interrupt number
INT_ADCA1
. - Included the ADC initialization and configuration in the code.
- Registered the interrupt using
Interrupt_register(INT_ADCA1, adcA1ISR);
and enabled it withInterrupt_enable(INT_ADCA1);
. - Added global interrupt enable with
EINT;
. - Included SCI print statements within
adcA1ISR
to confirm if it's being triggered, which it isn't. - Examined potential issues related to interrupt priority and nesting.
- Checked and ensured correct interrupt number
Despite these efforts, the ADC interrupt service routine does not seem to trigger, and I am unable to identify the cause.
Additional Context:
- Using Texas Instruments' Code Composer Studio for development.
- ADC is expected to read temperature values.
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++);
}
}