📄 adc_ctrl.c
字号:
//
g_usAnalogInputVoltage =
(((unsigned long)g_pusFilteredData1[0] * 3000 * 240) / 140) / 1024;
}
//*****************************************************************************
//
//! Handles the ADC sample sequence two interrupt.
//!
//! This function is called when sample sequence two asserts an interrupt. It
//! handles clearing the interrupt, processing any sequence overflow
//! conditions, and processing the new ADC data in the FIFO. This sequence is
//! used to measure the linear Hall sensor inputs. This sequence is only
//! enabled when the Hall sensors are enabled and configured as linear Hall
//! sensors. The linear Hall data is read and converted to an equivalent
//! "digital" Hall data value. When change in the "digital" Hall state is
//! detected, the speed calculation routines are run if a complete electical
//! revolution has occurred.
//!
//! \return None.
//
//*****************************************************************************
void
ADC2IntHandler(void)
{
unsigned long ulIdx;
unsigned short pusADCData[3];
static unsigned long ulLinearCount = 0;
unsigned long ulNewTime, ulTime;
//
// Get the time for this interrupt.
//
ulNewTime = UIGetTicks();
//
// Clear the ADC interrupt.
//
HWREG(ADC_BASE + ADC_O_ISC) = ADC_ISC_IN2;
//
// Reset the sequence if an overflow has occurred.
//
if(HWREG(ADC_BASE + ADC_O_OSTAT) & ADC_OSTAT_OV2)
{
//
// Disable the sequence.
//
HWREG(ADC_BASE + ADC_O_ACTSS) &= ~ADC_ACTSS_ASEN2;
//
// Drain the Sequence FIFO.
//
while(!(HWREG(ADC_BASE + ADC_O_SSFSTAT2) & ADC_SSFSTAT2_EMPTY))
{
//
// Read the next sample.
//
pusADCData[0] = HWREG(ADC_BASE + ADC_O_SSFIFO2);
}
//
// Clear any overflow/underflow conditions that might exist.
//
HWREG(ADC_BASE + ADC_O_OSTAT) = ADC_OSTAT_OV2;
HWREG(ADC_BASE + ADC_O_USTAT) = ADC_USTAT_UV2;
//
// Renable the sequence and return.
//
HWREG(ADC_BASE + ADC_O_ACTSS) = ADC_ACTSS_ASEN2;
return;
}
//
// Read the samples from the ADC FIFO.
//
ulIdx = 0;
while(!(HWREG(ADC_BASE + ADC_O_SSFSTAT2) & ADC_SSFSTAT2_EMPTY) &&
(ulIdx < 3))
{
//
// Read the next sample.
//
pusADCData[ulIdx] = HWREG(ADC_BASE + ADC_O_SSFIFO2);
//
// Increment the count of samples read.
//
ulIdx++;
}
//
// See if three samples were read.
//
if(ulIdx != 3)
{
//
// Since there were not precisely three samples in the FIFO, it is not
// known what analog signal is represented by each sample. Therefore,
// return without doing any processing on these samples.
//
return;
}
//
// Expand the Linear Hall Sensor data to full 10-bit range.
//
for(ulIdx = 0, ulLinearCount++; ulIdx < 3; ulIdx++)
{
unsigned short usRange, usMin;
//
// Adjust the min/max values inward to keep the values dynamic.
//
if(((ulLinearCount % 2000) == 0) && MainIsRunning())
{
g_pusLinearHallMax[ulIdx]--;
g_pusLinearHallMin[ulIdx]++;
}
//
// Find max/min hall sensor values.
//
if(pusADCData[ulIdx] > g_pusLinearHallMax[ulIdx])
{
g_pusLinearHallMax[ulIdx] = pusADCData[ulIdx];
}
if(pusADCData[ulIdx] < g_pusLinearHallMin[ulIdx])
{
g_pusLinearHallMin[ulIdx] = pusADCData[ulIdx];
}
//
// Adjust the ADC values to full-scale 10-bit ADC values.
//
usRange = g_pusLinearHallMax[ulIdx];
usRange -= g_pusLinearHallMin[ulIdx];
if(!usRange)
{
usRange++;
}
usMin = g_pusLinearHallMin[ulIdx];
g_pusLinearHallSensor[ulIdx] = (unsigned short)
(((unsigned long)(pusADCData[ulIdx] - usMin) * 1023) / usRange);
}
//
// Convert Linear Hall data to a Hall Sensor Value (A)
//
if(g_pusLinearHallSensor[0] > 614)
{
g_ulLinearHallValue |= 0x01;
}
else if (g_pusLinearHallSensor[0] < 410)
{
g_ulLinearHallValue &= ~0x01;
}
//
// Convert Linear Hall data to a Hall Sensor Value (B)
//
if(g_pusLinearHallSensor[1] > 614)
{
g_ulLinearHallValue |= 0x02;
}
else if (g_pusLinearHallSensor[1] < 410)
{
g_ulLinearHallValue &= ~0x02;
}
//
// Convert Linear Hall data to a Hall Sensor Value (C)
//
if(g_pusLinearHallSensor[2] > 614)
{
g_ulLinearHallValue |= 0x04;
}
else if (g_pusLinearHallSensor[2] < 410)
{
g_ulLinearHallValue &= ~0x04;
}
//
// Compute the new speed from the time between edges if the Hall
// state value has changed and the motor has completed one electrical
// revolution.
//
if((g_ulLinearHallValue != g_ulLinearLastHall) &&
(g_ulLinearHallValue == 5))
{
//
// Set the flag to indicate that we have seen an edge.
//
HWREGBITW(&g_ulADCFlags, FLAG_EDGE_BIT) = 1;
//
// See if this edge should be skipped.
//
if(HWREGBITW(&g_ulADCFlags, FLAG_SKIP_LINEAR_BIT))
{
//
// This edge should be skipped, but an edge time now exists so the
// next edge should not be skipped.
//
HWREGBITW(&g_ulADCFlags, FLAG_SKIP_LINEAR_BIT) = 0;
//
// Save the time of the current edge.
//
g_ulLinearSpeedPrevious = ulNewTime;
//
// Save the current linear hall value.
//
g_ulLinearLastHall = g_ulLinearHallValue;
//
// There is nothing further to be done.
//
return;
}
//
// Compute the time between this edge and the previous edge.
//
ulTime = ulNewTime - g_ulLinearSpeedPrevious;
//
// Save the time of the current edge.
//
g_ulLinearSpeedPrevious = ulNewTime;
//
// Compute the new speed from the time between edges, running it
// through a low pass filter with a coefficient of .875.
//
g_ulLinearRotorSpeed = ((g_ulLinearRotorSpeed * 7) +
(((unsigned long)SYSTEM_CLOCK * (unsigned long)60) /
(ulTime * (g_sParameters.ucNumPoles + 1)))) / 8;
}
//
// Save the current linear Hall state value.
//
g_ulLinearLastHall = g_ulLinearHallValue;
}
//*****************************************************************************
//
//! Handles the ADC sample sequence three interrupt.
//!
//! This function is called when sample sequence three asserts an interrupt.
//! It handles clearing the interrupt, processing any sequence overflow
//! conditions, and processing the new ADC data in the FIFO. This sequence is
//! used to process the Back EMF input data. The Back EMF data is monitored
//! to detect crossing of the 0.5 DC Bus Voltage point. When this occurs, an
//! equivalent "digital" Hall state value is generated. Speed is also
//! calculated when a complete electrical revolution has occured.
//!
//! \return None.
//
//*****************************************************************************
void
ADC3IntHandler(void)
{
unsigned short usADCData;
volatile unsigned long ulTemp;
static unsigned long ulLastPWMEnable = 0;
unsigned long ulPWMEnable;
unsigned long ulNewTime, ulTime;
//
// Clear the ADC interrupt.
//
HWREG(ADC_BASE + ADC_O_ISC) = ADC_ISC_IN3;
//
// Reset the sequence if an overflow has occurred.
//
if(HWREG(ADC_BASE + ADC_O_OSTAT) & ADC_OSTAT_OV3)
{
//
// Disable the sequence.
//
HWREG(ADC_BASE + ADC_O_ACTSS) &= ~ADC_ACTSS_ASEN3;
//
// Drain the Sequence FIFO.
//
while(!(HWREG(ADC_BASE + ADC_O_SSFSTAT3) & ADC_SSFSTAT3_EMPTY))
{
//
// Read the next sample.
//
ulTemp = HWREG(ADC_BASE + ADC_O_SSFIFO3);
}
//
// Clear any overflow/underflow conditions that might exist.
//
HWREG(ADC_BASE + ADC_O_OSTAT) = ADC_OSTAT_OV3;
HWREG(ADC_BASE + ADC_O_USTAT) = ADC_USTAT_UV3;
//
// Renable the sequence and return.
//
HWREG(ADC_BASE + ADC_O_ACTSS) = ADC_ACTSS_ASEN3;
return;
}
//
// Reset/Reconfigure the sequence if a change in PWM output drive
// state is detected.
//
ulPWMEnable = HWREG(PWM_BASE + PWM_O_ENABLE) |
HWREG(PWM_BASE + PWM_O_INVERT);
if(ulPWMEnable != ulLastPWMEnable)
{
unsigned long ulBEMF;
//
// Disable the sequence.
//
HWREG(ADC_BASE + ADC_O_ACTSS) &= ~ADC_ACTSS_ASEN3;
//
// Drain the Sequence FIFO.
//
while(!(HWREG(ADC_BASE + ADC_O_SSFSTAT3) & ADC_SSFSTAT3_EMPTY))
{
//
// Read the next sample.
//
usADCData = HWREG(ADC_BASE + ADC_O_SSFIFO3);
}
//
// Clear any overflow/underflow conditions that might exist.
//
HWREG(ADC_BASE + ADC_O_OSTAT) = ADC_OSTAT_OV3;
HWREG(ADC_BASE + ADC_O_USTAT) = ADC_USTAT_UV3;
//
// Save the PWM output state.
//
ulLastPWMEnable = ulPWMEnable;
//
// Based on the new PWM output state, determine which Back EMF
// detection state we should be in.
//
// Forward Reverse
// B+ C- ==> Rising A (0) ==> Falling B (3)
// B- C+ ==> Falling A (1) ==> Rising B (2)
// A- C+ ==> Rising B (2) ==> Falling C (5)
// A+ C- ==> Falling B (3) ==> Rising C (4)
// A+ B- ==> Rising C (4) ==> Falling A (1)
// A- B+ ==> Falling C (5) ==> Rising A (0)
//
if((ulPWMEnable & 0x03) == 0)
{
ulBEMF = PIN_VBEMFA;
g_ucBEMFState = ((ulPWMEnable & 0x0C) == 0x08) ? 1 : 0 ;
g_bBEMFEdge = false;
}
else if((ulPWMEnable & 0x0C) == 0)
{
ulBEMF = PIN_VBEMFB;
g_ucBEMFState = ((ulPWMEnable & 0x03) == 0x02) ? 2 : 3 ;
g_bBEMFEdge = false;
}
else
{
ulBEMF = PIN_VBEMFC;
g_ucBEMFState = ((ulPWMEnable & 0x03) == 0x02) ? 5 : 4 ;
g_bBEMFEdge = false;
}
if(MainIsReverse())
{
static const unsigned char ucRevTable[] = {3, 2, 5, 4, 1, 0};
g_ucBEMFState = ucRevTable[g_ucBEMFState];
}
//
// Reprogram the sequence to read Back EMF voltage first (with the
// PWM Pulse Active) and 5 Phase current readings to follow.
//
ADCSequenceStepConfigure(ADC_BASE, 3, 0,
ADC_CTL_END | ADC_CTL_IE | ulBEMF);
//
// Enable the sequence and return.
//
HWREG(ADC_BASE + ADC_O_ACTSS) |= ADC_ACTSS_ASEN3;
return;
}
//
// Read the sample from the ADC FIFO.
//
usADCData = HWREG(ADC_BASE + ADC_O_SSFIFO3);
//
// If motor drive is in the stopped state (i.e. not running), then return.
//
if(!MainIsRunning())
{
return;
}
//
// If Back EMF trigger point has been found, return.
//
if(g_bBEMFEdge)
{
return;
}
//
// Check for Back EMF Trigger Point.
//
ulNewTime = UIGetTicks();
switch(g_ucBEMFState)
{
//
// Forward Reverse
// B+ C- ==> Rising A (0) ==> Falling B (3)
// B- C+ ==> Falling A (1) ==> Rising B (2)
// A- C+ ==> Rising B (2) ==> Falling C (5)
// A+ C- ==> Falling B (3) ==> Rising C (4)
// A+ B- ==> Rising C (4) ==> Falling A (1)
// A- B+ ==> Falling C (5) ==> Rising A (0)
//
case 0:
if(usADCData < (g_pusFilteredData1[1] / 2))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -