📄 hw_trig_test.c
字号:
// Calibrate the ADC in the configuration in which it will be used:
ADC_Cal(ADC0_BASE_PTR); // do the calibration
// The structure still has the desired configuration. So restore it.
// Why restore it? The calibration makes some adjustments to the
// configuration of the ADC. The are now undone:
// config the ADC again to desired conditions
ADC_Config_Alt(ADC0_BASE_PTR, &Master_Adc_Config);
// REPEAT for BOTH ADC's. However we will only 'use' the results from
// the ADC wired to the Potentiometer on the Kinetis Tower Card.
// Repeating for ADC1:
ADC_Config_Alt(ADC1_BASE_PTR, &Master_Adc_Config); // config ADC
ADC_Cal(ADC1_BASE_PTR); // do the calibration
// ADC_Read_Cal(ADC1_BASE_PTR,&CalibrationStore[0]); // store the cal
// config the ADC again to default conditions
ADC_Config_Alt(ADC1_BASE_PTR, &Master_Adc_Config);
// *****************************************************************************
// ADC0 and ADC1 using the PDB trigger in ping pong
// *****************************************************************************
// use interrupts, single ended mode, and real channel numbers now:
Master_Adc_Config.STATUS1A = AIEN_ON | DIFF_SINGLE | ADC_SC1_ADCH(ADC0_CHANA);
Master_Adc_Config.STATUS1B = AIEN_ON | DIFF_SINGLE | ADC_SC1_ADCH(ADC0_CHANB);
ADC_Config_Alt(ADC0_BASE_PTR, &Master_Adc_Config); // config ADC0
Master_Adc_Config.STATUS1A = AIEN_ON | DIFF_SINGLE | ADC_SC1_ADCH(ADC1_CHANA);
Master_Adc_Config.STATUS1B = AIEN_ON | DIFF_SINGLE | ADC_SC1_ADCH(ADC1_CHANB);
ADC_Config_Alt(ADC1_BASE_PTR, &Master_Adc_Config); // config ADC1
// Note that three different balls are being sampled:
// ADC0_CHANA not used in this demo, but readings are shown
// ADC0_CHANB not used in this demo, but readings are shown
// ADC1_CHANA POT channel set the same as the following for demo: 20
// ADC1_CHANB POT channel set the same as the above for demo: 20
// The potentiometer is only on ADC1. That is the one used
// to calculate the change of the potentiometer below.
//while(char_present()) in_char(); // flush terminal buffer
printf ("\n\n\n");
printf("********************************************************\n");
printf("* Running ADC0 & ADC1 HARDWARE TRIGGER by PDB *\n");
printf("* The one PDB is triggering both ADC0 and ADC1 *\n");
printf("* ADC1 A,B is the POT. Vary the POT setting. *\n");
printf("* Hit any key to exit (ADC0 readings not used) *\n");
printf("********************************************************\n");
printf ("\n\n");
// Enable the ADC and PDB interrupts in NVIC
enable_irq(ADC0_irq_no) ; // ready for this interrupt.
enable_irq(ADC1_irq_no) ; // ready for this interrupt.
enable_irq(PDB_irq_no) ; // ready for this interrupt.
// In case previous test did not end with interrupts enabled, enable used ones.
EnableInterrupts ;
cycle_flags=0;
PDB0_SC |= PDB_SC_SWTRIG_MASK ; // kick off the PDB - just once
//The system is now working!!!! The PDB is *continuously* triggering ADC
// conversions. Now, to display the results! The line above
// was the SOFTWARE TRIGGER...
// The demo will continue as long as no character is pressed on the terminal.
while(!char_present()) // as long as no operater intervention, keep running this:
{
while( cycle_flags != ( ADC0A_DONE | ADC0B_DONE | ADC1A_DONE | ADC1B_DONE )); // wait for one complete cycle
printf("R0A=%6d R0B=%6d R1A=%6d R1B=%6d POT=%6d\r",
result0A,result0B,result1A,result1B, exponentially_filtered_result1);
}
// disable the PDB
PDB0_SC = 0 ;
// Disable the ADC and PDB interrupts in NVIC
disable_irq(ADC0_irq_no) ; // through with this interrupt.
disable_irq(ADC1_irq_no) ; // through with this interrupt.
disable_irq(PDB_irq_no) ; // through with this interrupt.
printf ("\n\n\n");
printf("********************************************************\n");
printf("* Demonstration ended at operator request *\n");
printf("* ADC0 & ADC1 PDB TRIGGER DEMO COMPLETE *\n");
printf("********************************************************\n");
printf ("\n\n");
return 0;
}
/******************************************************************************
* pdb_isr(void)
*
* use to signal PDB counter has restarted counting
*
* In: n/a
* Out: n/a
******************************************************************************/
void pdb_isr(void)
{
PIN_TOGGLE // do this asap - show start of PDB cycle
PDB0_SC &= ~PDB_SC_PDBIF_MASK ; // clear interrupt mask
PIN1_LOW
PIN2_LOW
cycle_flags = 0;
return;
}
/******************************************************************************
* adc0_isr(void)
*
* use to signal ADC0 end of conversion
* In: n/a
* Out: n/a
******************************************************************************/
void adc0_isr(void)
{
if (( ADC0_SC1A & ADC_SC1_COCO_MASK ) == ADC_SC1_COCO_MASK)
{ // check which of the two conversions just triggered
PIN1_HIGH // do this asap
result0A = ADC0_RA; // this will clear the COCO bit that is also the interrupt flag
cycle_flags |= ADC0A_DONE ; // mark this step done
}
else if (( ADC0_SC1B & ADC_SC1_COCO_MASK ) == ADC_SC1_COCO_MASK)
{
PIN1_LOW
result0B = ADC0_RB;
cycle_flags |= ADC0B_DONE ;
}
return;
}
/******************************************************************************
* adc1_isr(void)
*
* use to signal ADC1 end of conversion
* In: n/a
* Out: exponentially filtered potentiometer reading!
* The ADC1 is used to sample the potentiometer on the A side and the B side:
* ping-pong. That reading is filtered for an agregate of ADC1 readings: exponentially_filtered_result1
* thus the filtered POT output is available for display.
******************************************************************************/
void adc1_isr(void)
{
if (( ADC1_SC1A & ADC_SC1_COCO_MASK ) == ADC_SC1_COCO_MASK) { // check which of the two conversions just triggered
PIN2_HIGH // do this asap
result1A = ADC1_RA; // this will clear the COCO bit that is also the interrupt flag
// Begin exponential filter code for Potentiometer setting for demonstration of filter effect
exponentially_filtered_result1 += result1A;
exponentially_filtered_result1 /= 2 ;
// Spikes are attenuated 6dB, 12dB, 24dB, .. and so on untill they die out.
// End exponential filter code.. add f*sample, divide by (f+1).. f is 1 for this case.
cycle_flags |= ADC1A_DONE ; // mark this step done
}
else if (( ADC1_SC1B & ADC_SC1_COCO_MASK ) == ADC_SC1_COCO_MASK) {
PIN2_LOW
result1B = ADC1_RB;
// Begin exponential filter code for Potentiometer setting for demonstration of filter effect
exponentially_filtered_result1 += result1B;
exponentially_filtered_result1 /= 2 ;
// Spikes are attenuated 6dB, 12dB, 24dB, .. and so on untill they die out.
// End exponential filter code.. add f*sample, divide by (f+1).. f is 1 for this case.
cycle_flags |= ADC1B_DONE ;
}
return;
}
/******************************************************************************/
//******************************************************************************
// setup additional two output pins to indirectly observe adc status changes
//
//******************************************************************************
void Init_Gpio2(void){
// setup PTA28 and PTA11 for output - yellow and orange leds on the Tower K60
PORTA_PCR28 = PORT_PCR_MUX(1) ; // select GPIO function
GPIOA_PCOR = 0x01 << 28 ; // initial out low
GPIOA_PDDR |= 0x01 << 28 ; // output enable NOTE OR
PORTA_PCR11 = PORT_PCR_MUX(1) ; // select GPIO function
GPIOA_PCOR = 0x01 << 11 ; // initial out low
GPIOA_PDDR |= 0x01 << 11 ; // output enable NOTE OR
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -