📄 hw_trig_test.c
字号:
/*
* File: hw_trig_test.c
* Purpose: Demo adc triggered by PDB module
*/
#include "common.h"
#include "adc_demo.h"
#include "hw_trig_test.h"
#include "adc16.h"
#include "dsp.h" // just for the dsp capabilities..such as u32.
// Global filtered output for ADC1 used by ISR and by demo code print routine
u32 exponentially_filtered_result1 = 0 ;
extern tADC_Config Master_Adc_Config;
static int8_t cycle_flags=0;
volatile static unsigned result0A,result0B,result1A,result1B;
// **********************************************************
//
// The folowing code demonstrates the hardware trigger capability of the two ADCs.
// For each ADC there are two hardware trigger channels, therefore the two status&control "SC1" registers
// and two result registers are tested.
//
// [Why does each ADC need two sets of some registers? So that while one is in use, the other set can be used.
// It alows a ping-pong approach that will be demonstrated here.]
//
// A total of four triggering signals are generated from the PDB hardware
// and the code causes every one of those to be routed to the correct ADC trigger channel.
// The PDB is set in continuous, software triggered mode , counting from 0 to 0xFFFF
// from a frequency slow enough to allow a very long cycle during which
// there is printed something about the four ADc trigger events.
// A PDB interrupt is setup at the beginning of each PDB cycle ( PDB_IDLY = 0 ).
// It is set to signal by toggling "PIN", at the beginning of each cycle.
// This will be visible as an LED.
// These four PDB delays will trigger two triggers on ADC0 and two on ADC1.
// Each ADC, for each "trigger-SC1x-result" group, will generate an end of conversion interrupt and set a bit
// in a global variable to flag execution of that trigger.
// Background code will check for all the four triggers and conversions to end,
// Then the printf on a single line the four results from adc is shown.
// The effect of an exponential filter is shown on subsequent lines.
// Both the filtered, and unfiltered conversion results are displayed.
// The filter is a simple exponential filter that decays an impulse exponentially.
// Upon the execution of each trigger,
// each ADC interrupt ( adc0 and adc1)
// will signal the "A" trigger with a high on a dedicated pin
// and a "B" trigger via a low level on same pin.
// Again, each ADC, ADC0 and ADC1, has a set of A registers and a set of B registers
// for those items that benefit from ping-ponging (double buffering).
// "PIN1" will be used by ADC0 isr and "PIN2" for ADC1 isr.
// By resetting both marking pins in the initial PDB and having
// "A" trigger happen before "B" the sequences can be seen.
/********************************************************************/
uint8_t Hw_Trig_Test(void)
{
// Notes:
// PDB settings : continous mode, started by sotware trigger.
// This means that once the software "pulls the trigger" by setting a certain bit, the PDB starts counting
// and handing out four triggers per cycle of its counter.
// PDB settings: CH0_DLY0, CH0_DLY1 , CH1_DLY0, CH1_DLY1
// set to different values to distinguish effect on ADCx_Ry register
// need to provide 4 different voltages to convert at two ADC0 and two ADC1 input channels
// PDB counter clock prescaled to allow time for printf's and slow down things to they are visible, each trigger.
// Using adiclk= BUS , and adidiv/4 to get 12,5MHz on Tower demonstration.
// visibility of PDB start trigger is obtained by generating a toggling edge on
// GPIOxx with PDBisr set to trigger immediatly at zero value of PDB counter.
// Conversion end of each ADC and channel within the ADC ( A,B ) will be done by
// toggling second GPIO pin inside ADCisr ( this pin is also reset by PDB isr )
// GPIO PIN to low voltage .. this macro sets the PIN low.
PIN_LOW
// Initialize PIN1 and PIN2 GPIO outputs
Init_Gpio2();
// Disable ADC and PDB interrupts
disable_irq(ADC0_irq_no) ; // not ready for this interrupt yet. Plug vector first.
disable_irq(ADC1_irq_no) ; // not ready for this interrupt yet. Plug vector first.
disable_irq(PDB_irq_no) ; // not ready for this interrupt yet. Plug vector first.
// The System Integration Module largely determines the role of the different ball map locations on Kinetis.
// When an external pin is used, the System Integration Module should be consulted and invoked as needed.
// System integration module registers start with SIM_
// Turn on the ADC0 and ADC1 clocks as well as the PDB clocks to test ADC triggered by PDB
SIM_SCGC6 |= (SIM_SCGC6_ADC0_MASK );
SIM_SCGC3 |= (SIM_SCGC3_ADC1_MASK );
SIM_SCGC6 |= SIM_SCGC6_PDB_MASK ;
// Configure System Integration Module for defaults as far as ADC
SIM_SOPT7 &= ~(SIM_SOPT7_ADC1ALTTRGEN_MASK | // selects PDB not ALT trigger
SIM_SOPT7_ADC1PRETRGSEL_MASK |
SIM_SOPT7_ADC0ALTTRGEN_MASK | // selects PDB not ALT trigger
SIM_SOPT7_ADC0ALTTRGEN_MASK) ;
SIM_SOPT7 = SIM_SOPT7_ADC0TRGSEL(0); // applies only in case of ALT trigger, in which case
// PDB external pin input trigger for ADC
SIM_SOPT7 = SIM_SOPT7_ADC1TRGSEL(0); // same for both ADCs
/////////////////////////////////////////////////////////////////////////////////////////
//PDB configured below
// Configure the Peripheral Delay Block (PDB):
// enable PDB, pdb counter clock = busclock / 20 , continous triggers, sw trigger , and use prescaler too
PDB0_SC = PDB_SC_CONT_MASK // Contintuous, rather than one-shot, mode
| PDB_SC_PDBEN_MASK // PDB enabled
| PDB_SC_PDBIE_MASK // PDB Interrupt Enable
| PDB_SC_PRESCALER(0x5) // Slow down the period of the PDB for testing
| PDB_SC_TRGSEL(0xf) // Trigger source is Software Trigger to be invoked in this file
| PDB_SC_MULT(2); // Multiplication factor 20 for the prescale divider for the counter clock
// the software trigger, PDB_SC_SWTRIG_MASK is not triggered at this time.
PDB0_IDLY = 0x0000; // need to trigger interrupt every counter reset which happens when modulus reached
PDB0_MOD = 0xffff; // largest period possible with the slections above, so slow you can see each conversion.
// channel 0 pretrigger 0 and 1 enabled and delayed
PDB0_CH0C1 = PDB_C1_EN(0x01)
| PDB_C1_TOS(0x01)
| PDB_C1_EN(0x02)
| PDB_C1_TOS(0x02) ;
PDB0_CH0DLY0 = ADC0_DLYA ;
PDB0_CH0DLY1 = ADC0_DLYB ;
// channel 1 pretrigger 0 and 1 enabled and delayed
PDB0_CH1C1 = PDB_C1_EN(0x01)
| PDB_C1_TOS(0x01)
| PDB_C1_EN(0x02)
| PDB_C1_TOS(0x02) ;
PDB0_CH1DLY0 = ADC1_DLYA ;
PDB0_CH1DLY1 = ADC1_DLYB ;
PDB0_SC = PDB_SC_CONT_MASK // Contintuous, rather than one-shot, mode
| PDB_SC_PDBEN_MASK // PDB enabled
| PDB_SC_PDBIE_MASK // PDB Interrupt Enable
| PDB_SC_PRESCALER(0x5) // Slow down the period of the PDB for testing
| PDB_SC_TRGSEL(0xf) // Trigger source is Software Trigger to be invoked in this file
| PDB_SC_MULT(2) // Multiplication factor 20 for the prescale divider for the counter clock
| PDB_SC_LDOK_MASK; // Need to ok the loading or it will not load certain regsiters!
// the software trigger, PDB_SC_SWTRIG_MASK is not triggered at this time.
//PDB configured above
/////////////////////////////////////////////////////////////////////////////////////////
//ADC configured below
// setup the initial ADC default configuration
Master_Adc_Config.CONFIG1 = ADLPC_NORMAL
| ADC_CFG1_ADIV(ADIV_4)
| ADLSMP_LONG
| ADC_CFG1_MODE(MODE_16)
| ADC_CFG1_ADICLK(ADICLK_BUS);
Master_Adc_Config.CONFIG2 = MUXSEL_ADCA
| ADACKEN_DISABLED
| ADHSC_HISPEED
| ADC_CFG2_ADLSTS(ADLSTS_20) ;
Master_Adc_Config.COMPARE1 = 0x1234u ; // can be anything
Master_Adc_Config.COMPARE2 = 0x5678u ; // can be anything
// since not using
// compare feature
Master_Adc_Config.STATUS2 = ADTRG_HW
| ACFE_DISABLED
| ACFGT_GREATER
| ACREN_ENABLED
| DMAEN_DISABLED
| ADC_SC2_REFSEL(REFSEL_EXT);
Master_Adc_Config.STATUS3 = CAL_OFF
| ADCO_SINGLE
| AVGE_ENABLED
| ADC_SC3_AVGS(AVGS_32);
Master_Adc_Config.PGA = PGAEN_DISABLED
| PGACHP_NOCHOP
| PGALP_NORMAL
| ADC_PGA_PGAG(PGAG_64);
Master_Adc_Config.STATUS1A = AIEN_OFF | DIFF_SINGLE | ADC_SC1_ADCH(31);
Master_Adc_Config.STATUS1B = AIEN_OFF | DIFF_SINGLE | ADC_SC1_ADCH(31);
// Configure ADC as it will be used, but becuase ADC_SC1_ADCH is 31,
// the ADC will be inactive. Channel 31 is just disable function.
// There really is no channel 31.
ADC_Config_Alt(ADC0_BASE_PTR, &Master_Adc_Config); // config ADC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -