📄 f31x_adc0_externalinput_mux.c
字号:
// P0.4 - UART TX (push-pull)
// P0.5 - UART RX
//
// P1.0 - analog input (ADC0)
// P1.1 - analog input (ADC0)
// P1.2 - analog input (ADC0)
// P1.3 - analog input (ADC0)
// P1.4 - analog input (ADC0)
// P1.5 - analog input (ADC0)
//
//-----------------------------------------------------------------------------
void Port_Init (void)
{
P1SKIP = 0x3F; // Skip all analog pins
XBR0 = 0x01; // UART0 TX and RX pins enabled
XBR1 = 0x40; // Enable crossbar and weak pull-ups
P0MDOUT |= 0x10; // Enable TX0 as a push-pull output
P1MDIN &= ~0x3F; // Set desired pins as analog inputs
}
//-----------------------------------------------------------------------------
// Timer2_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// Configure Timer2 to 16-bit auto-reload and generate an interrupt at 10 us
// intervals. Timer2 overflows automatically triggers ADC0 conversion.
//
//-----------------------------------------------------------------------------
void Timer2_Init (void)
{
TMR2CN = 0x00; // Stop Timer2; Clear TF2;
// use SYSCLK as timebase, 16-bit
// auto-reload
CKCON |= 0x10; // Select SYSCLK for timer 2 source
TMR2RL = 65535 - (SYSCLK / 10000); // Init reload value for 10 us
TMR2 = 0xffff; // Set to reload immediately
ET2 = 1; // Enable Timer2 interrupts
TR2 = 1; // Start Timer2
}
//-----------------------------------------------------------------------------
// ADC0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// Configures ADC0 to make single-ended analog measurements on Port 1 according
// to the values of <ANALOG_INPUTS> and <PIN_TABLE>.
//
//-----------------------------------------------------------------------------
void ADC0_Init (void)
{
ADC0CN = 0x02; // ADC0 disabled, normal tracking,
// conversion triggered on TMR2 overflow
REF0CN = 0x0A; // Enable VREF
AMX0P = PIN_TABLE[0]; // ADC0 initial positive input = P1.0
AMX0N = 0x1F; // ADC0 negative input = GND
// i.e., single ended mode
ADC0CF = ((SYSCLK/3000000)-1)<<3; // Set SAR clock to 3MHz
ADC0CF |= 0x00; // Right-justify results
EIE1 |= 0x08; // Enable ADC0 EOC interrupt
AD0EN = 1; // Enable ADC0
}
//-----------------------------------------------------------------------------
// UART0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// Configure the UART0 using Timer1, for <BAUDRATE> and 8-N-1.
//
//-----------------------------------------------------------------------------
void UART0_Init (void)
{
SCON0 = 0x10; // SCON0: 8-bit variable bit rate
// level of STOP bit is ignored
// RX enabled
// ninth bits are zeros
// clear RI0 and TI0 bits
if (SYSCLK/BAUDRATE/2/256 < 1) {
TH1 = -(SYSCLK/BAUDRATE/2);
CKCON |= 0x08; // T1M = 1; SCA1:0 = xx
} else if (SYSCLK/BAUDRATE/2/256 < 4) {
TH1 = -(SYSCLK/BAUDRATE/2/4);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 01
CKCON |= 0x01;
} else if (SYSCLK/BAUDRATE/2/256 < 12) {
TH1 = -(SYSCLK/BAUDRATE/2/12);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 00
} else if (SYSCLK/BAUDRATE/2/256 < 48) {
TH1 = -(SYSCLK/BAUDRATE/2/48);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 10
CKCON |= 0x02;
} else {
while (1); // Error. Unsupported baud rate
}
TL1 = TH1; // Init Timer1
TMOD &= ~0xF0; // TMOD: timer 1 in 8-bit autoreload
TMOD |= 0x20;
TR1 = 1; // START Timer1
TI0 = 1; // Indicate TX0 ready
}
//-----------------------------------------------------------------------------
// Interrupt Service Routines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Timer2_ISR
//-----------------------------------------------------------------------------
//
// This routine changes to the next Analog MUX input whenever Timer2 overflows
// for the next ADC sample. This allows the ADC to begin setting on the new
// input while converting the old input.
//
//-----------------------------------------------------------------------------
void Timer2_ISR (void) interrupt 5
{
TF2H = 0; // Clear Timer2 interrupt flag
// Set up the AMUX for the next ADC input
// ADC0 positive input = P1.<PIN_TABLE[AMUX_INPUT+1]>
// ADC0 negative input = GND
// i.e., single ended mode
if (AMUX_INPUT == (ANALOG_INPUTS - 1))
{
AMX0P = PIN_TABLE[0];
}
else
{
AMX0P = PIN_TABLE[AMUX_INPUT+1];
}
}
//-----------------------------------------------------------------------------
// ADC0_ISR
//-----------------------------------------------------------------------------
//
// This ISR averages <INT_DEC> samples for each analog MUX input then prints
// the results to the terminal. The ISR is called after each ADC conversion,
// which is triggered by Timer2.
//
//-----------------------------------------------------------------------------
void ADC0_ISR (void) interrupt 10
{
static unsigned int_dec = INT_DEC; // Integrate/decimate counter
// A new result is posted when
// int_dec is 0
// Integrate accumulator for the ADC samples from input pins
static long accumulator[ANALOG_INPUTS] = 0x00000000;
unsigned char i; // Loop counter
AD0INT = 0; // Clear ADC conversion complete
// overflow
accumulator[AMUX_INPUT] += ADC0; // Read the ADC value and add it to the
// running total
// Reset sample counter <int_dec> and <AMUX_INPUT> if the final input was
// just read
if(AMUX_INPUT == (ANALOG_INPUTS - 1))
{
int_dec--; // Update decimation counter
// when the last of the analog inputs
// is sampled
if (int_dec == 0) // If zero, then post the averaged
{ // results
int_dec = INT_DEC; // Reset counter
// Copy each averaged ADC0 value into the RESULT array
for(i = 0; i < ANALOG_INPUTS; i++)
{
// Copy averaged values into RESULT
RESULT[i] = accumulator[i] / int_dec;
// Reset accumulators
accumulator[i] = 0x00000000;
}
}
AMUX_INPUT = 0; // Reset input index back to P1.0
}
// Otherwise, increment the AMUX channel counter
else
{
AMUX_INPUT++; // Step to the next analog mux input
}
}
//-----------------------------------------------------------------------------
// Support Subroutines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Timer0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters :
// 1) int ms - number of milliseconds to wait
// range is positive range of an int: 0 to 32767
//
// This function configures the Timer0 as a 16-bit timer, interrupt enabled.
// Using the internal osc. at 24.5MHz with a prescaler of 1:8 and reloading the
// T0 registers with TIMER0_RELOAD_HIGH/LOW, it will wait for <ms>
// milliseconds.
// Note: The Timer0 uses a 1:12 prescaler
//-----------------------------------------------------------------------------
void Timer0_wait(int ms)
{
TH0 = TIMER0_RELOAD_HIGH; // Init Timer0 High register
TL0 = TIMER0_RELOAD_LOW ; // Init Timer0 Low register
TMOD |= 0x01; // Timer0 in 16-bit mode
CKCON &= 0xFC; // Timer0 uses a 1:12 prescaler
TR0 = 1; // Timer0 ON
while(ms)
{
TF0 = 0; // Clear flag to initialize
while(!TF0); // Wait until timer overflows
ms--; // Decrement ms
}
TR0 = 0; // Timer0 OFF
}
//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -