Dependencies:   mbed

Committer:
nmaududi
Date:
Fri Oct 04 21:09:15 2019 +0000
Revision:
0:4fb921928934
Child:
1:9fa7cc80f1a7
rev A;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nmaududi 0:4fb921928934 1 /**----------------------------------------------------------------------------
nmaududi 0:4fb921928934 2 *
nmaududi 0:4fb921928934 3 * \file frequency_detector.cpp
nmaududi 0:4fb921928934 4 -- --
nmaududi 0:4fb921928934 5 -- ECEN 5803 Mastering Embedded System Architecture --
nmaududi 0:4fb921928934 6 -- Project 1 Module 4 --
nmaududi 0:4fb921928934 7 -- Microcontroller Firmware --
nmaududi 0:4fb921928934 8 -- frequency_detector.cpp --
nmaududi 0:4fb921928934 9 -- --
nmaududi 0:4fb921928934 10 -------------------------------------------------------------------------------
nmaududi 0:4fb921928934 11 --
nmaududi 0:4fb921928934 12 -- Designed for: University of Colorado at Boulder
nmaududi 0:4fb921928934 13 --
nmaududi 0:4fb921928934 14 --
nmaududi 0:4fb921928934 15 -- Designed by: Tim Scherr
nmaududi 0:4fb921928934 16 -- Revised by: Naved Maududi and Bryan Cisneros
nmaududi 0:4fb921928934 17 --
nmaududi 0:4fb921928934 18 -- Version: 2.1
nmaududi 0:4fb921928934 19 -- Date of current revision: 2017-09-25
nmaududi 0:4fb921928934 20 -- Target Microcontroller: Freescale MKL25ZVMT4
nmaududi 0:4fb921928934 21 -- Tools used: ARM mbed compiler
nmaududi 0:4fb921928934 22 -- ARM mbed SDK
nmaududi 0:4fb921928934 23 -- Freescale FRDM-KL25Z Freedom Board
nmaududi 0:4fb921928934 24 --
nmaududi 0:4fb921928934 25 --
nmaududi 0:4fb921928934 26 Functional Description:
nmaududi 0:4fb921928934 27 This file contains code that takes in quasi-sine wave ADC inputs from the flow meter
nmaududi 0:4fb921928934 28 From the ADC inputs, it calculates the frequency of that sine wave. The frequency is
nmaududi 0:4fb921928934 29 important in determining the flow rate and velocity for the flowmeter that are outputed
nmaududi 0:4fb921928934 30 to the display.
nmaududi 0:4fb921928934 31 --
nmaududi 0:4fb921928934 32 -- Copyright (c) 2015 Tim Scherr All rights reserved.
nmaududi 0:4fb921928934 33 */
nmaududi 0:4fb921928934 34
nmaududi 0:4fb921928934 35
nmaududi 0:4fb921928934 36 #include "shared.h"
nmaududi 0:4fb921928934 37
nmaududi 0:4fb921928934 38
nmaududi 0:4fb921928934 39 PinName const ch0 = PTB0; // channel 0 (PTB0) to A/D pin VREFL
nmaududi 0:4fb921928934 40 PinName const ch1 = PTB1; // channel 1 (PTB1) to J10_4 a virtual vortex frequency input,
nmaududi 0:4fb921928934 41 PinName const ch2 = PTB2; // channel 2 (PTB2) to an actual internal TempSensor
nmaududi 0:4fb921928934 42
nmaududi 0:4fb921928934 43 #define ADC0_CFG1 (ADC0->CFG1)
nmaududi 0:4fb921928934 44 #define ADC0_CFG2 (ADC0->CFG2)
nmaududi 0:4fb921928934 45 #define ADC0_SC1A (ADC0->SC1[0]) // ADC0 to SC1A
nmaududi 0:4fb921928934 46 #define ADC0_SC3 (ADC0->SC3)
nmaududi 0:4fb921928934 47 #define SIM_SCGC6 (SIM->SCGC6)
nmaududi 0:4fb921928934 48 #define CHANNEL_0 (0U)
nmaududi 0:4fb921928934 49 #define CHANNEL_1 (1U)
nmaududi 0:4fb921928934 50 #define CHANNEL_2 (2U)
nmaududi 0:4fb921928934 51
nmaududi 0:4fb921928934 52 AnalogIn Vref_low(ch0);
nmaududi 0:4fb921928934 53
nmaududi 0:4fb921928934 54 AnalogIn vortex_frequency(ch1);
nmaududi 0:4fb921928934 55
nmaududi 0:4fb921928934 56 AnalogIn TempSensor(ch2);
nmaududi 0:4fb921928934 57
nmaududi 0:4fb921928934 58
nmaududi 0:4fb921928934 59 void adc_calibration(void){
nmaududi 0:4fb921928934 60
nmaududi 0:4fb921928934 61 // Enable clocks
nmaududi 0:4fb921928934 62 SIM_SCGC6 |= SIM_SCGC6_ADC0_MASK; // ADC 0 clock
nmaududi 0:4fb921928934 63
nmaududi 0:4fb921928934 64 // Configure ADC
nmaududi 0:4fb921928934 65 ADC0_CFG1 = 0; // Reset register
nmaududi 0:4fb921928934 66
nmaududi 0:4fb921928934 67
nmaududi 0:4fb921928934 68
nmaududi 0:4fb921928934 69 ADC0_CFG1 |= (ADC_CFG1_MODE(0)| // 8 bit mode
nmaududi 0:4fb921928934 70 ADC_CFG1_ADICLK(0)| // Input Bus Clock for calibration
nmaududi 0:4fb921928934 71 ADC_CFG1_ADIV(3)); // Long time sample configuration
nmaududi 0:4fb921928934 72
nmaududi 0:4fb921928934 73 ADC0_CFG1 = 0 & ADC_CFG1_ADLPC_MASK; // normal power configuration
nmaududi 0:4fb921928934 74 ADC0_CFG1 = 1 & ADC_CFG1_ADLSMP_MASK; // Long time sample configuration
nmaududi 0:4fb921928934 75
nmaududi 0:4fb921928934 76
nmaududi 0:4fb921928934 77 ADC0_CFG2 = 0 & ADC_CFG2_ADHSC_MASK; // 1 High-speed conversion sequence, 0 for normal coversion, zero as sampling is 10 usec, bus clock is good enought
nmaududi 0:4fb921928934 78 ADC0_CFG2 = 0 & ADC_CFG2_ADLSTS_MASK; // Default longest sample time; 20 extra ADCK cycles; 24 ADCK cycles total.
nmaududi 0:4fb921928934 79 ADC0_CFG2 = 0 & ADC_CFG2_ADACKEN_MASK; // Asynchronous clock output disabled; Asynchronous clock is enabled only if selected by ADICLK and a conversion is active. low power configuration
nmaududi 0:4fb921928934 80
nmaududi 0:4fb921928934 81
nmaududi 0:4fb921928934 82
nmaududi 0:4fb921928934 83 ADC0_SC3 = 1 & ADC_SC3_AVGE_MASK; // 1 High-speed conversion sequence, for calibration
nmaududi 0:4fb921928934 84 ADC0_SC3 = 3 & ADC_SC3_AVGS_MASK; // Average of 32 samples, for calibration purposes
nmaududi 0:4fb921928934 85 ADC0_SC3 = 1 & ADC_SC3_CAL_MASK; // set to 1 for calibration of the ADC prior to completing conversions
nmaududi 0:4fb921928934 86
nmaududi 0:4fb921928934 87 uint16_t PG_calibration = 0; //Initialize or clear a 16-bit variable in RAM.
nmaududi 0:4fb921928934 88 uint16_t MG_calibration = 0; //Initialize or clear a 16-bit variable in RAM.
nmaududi 0:4fb921928934 89
nmaududi 0:4fb921928934 90 PG_calibration = (ADC0->CLP0)+(ADC0->CLP1)+(ADC0->CLP2)+(ADC0->CLP3)+(ADC0->CLP4)+(ADC0->CLPS); // Add the plus-side calibration results to the variable
nmaududi 0:4fb921928934 91 PG_calibration = PG_calibration/2; // Divide the variable by two
nmaududi 0:4fb921928934 92 PG_calibration = (PG_calibration & 0xFF00); //Set the MSB of the variable.
nmaududi 0:4fb921928934 93 ADC0->PG = (ADC0->CLP0)+PG_calibration; //Store the value in the plus-side gain calibration register PG.
nmaududi 0:4fb921928934 94
nmaududi 0:4fb921928934 95 MG_calibration = (ADC0->CLM0)+(ADC0->CLM1)+(ADC0->CLM2)+(ADC0->CLM3)+(ADC0->CLM4)+(ADC0->CLMS); // Add the minus-side calibration results to the variable
nmaududi 0:4fb921928934 96 MG_calibration = MG_calibration/2; //Divide the variable by two
nmaududi 0:4fb921928934 97 MG_calibration = (MG_calibration & 0xFF00); //Set the MSB of the variable.
nmaududi 0:4fb921928934 98 ADC0->MG = (ADC0->CLM0)+MG_calibration; //Store the value in the plus-side gain calibration register MG.
nmaududi 0:4fb921928934 99 // END OF CALIBRATION
nmaududi 0:4fb921928934 100 }
nmaududi 0:4fb921928934 101
nmaududi 0:4fb921928934 102
nmaududi 0:4fb921928934 103
nmaududi 0:4fb921928934 104
nmaududi 0:4fb921928934 105 void read_ADC(uint8_t channel)
nmaududi 0:4fb921928934 106 {
nmaududi 0:4fb921928934 107 if (channel==CHANNEL_0){
nmaududi 0:4fb921928934 108 // Enable clocks
nmaududi 0:4fb921928934 109 SIM_SCGC6 |= SIM_SCGC6_ADC0_MASK; // ADC 0 clock
nmaududi 0:4fb921928934 110
nmaududi 0:4fb921928934 111 // Configure ADC
nmaududi 0:4fb921928934 112 ADC0_CFG1 = 0; // Reset register
nmaududi 0:4fb921928934 113
nmaududi 0:4fb921928934 114 ADC0_CFG1 |= (ADC_CFG1_MODE(0)| // 8 bit mode
nmaududi 0:4fb921928934 115 ADC_CFG1_ADICLK(0)| // Input Bus Clock (20-25 MHz out of reset (FEI mode))
nmaududi 0:4fb921928934 116 ADC_CFG1_ADIV(0)); // Clock divide by 1
nmaududi 0:4fb921928934 117 ADC0_CFG1 = 0 & ADC_CFG1_ADLPC_MASK; // normal power configuration
nmaududi 0:4fb921928934 118 ADC0_CFG1 = 1 & ADC_CFG1_ADLSMP_MASK; // Long time sample configuration
nmaududi 0:4fb921928934 119
nmaududi 0:4fb921928934 120 ADC0_CFG2 = 0 & ADC_CFG2_ADHSC_MASK; // 1 High-speed conversion sequence, 0 for normal coversion, zero as sampling is 10 usec, bus clock is good enought
nmaududi 0:4fb921928934 121 ADC0_CFG2 = 0 & ADC_CFG2_ADLSTS_MASK; // Default longest sample time; 20 extra ADCK cycles; 24 ADCK cycles total.
nmaududi 0:4fb921928934 122 ADC0_CFG2 = 0 & ADC_CFG2_ADACKEN_MASK; // Asynchronous clock output disabled; Asynchronous clock is enabled only if selected by ADICLK and a conversion is active. low power configuration
nmaududi 0:4fb921928934 123
nmaududi 0:4fb921928934 124
nmaududi 0:4fb921928934 125 ADC0_SC3 = 0 & ADC_SC3_ADCO_MASK; // set to 1 for continuious conversion, 0 for only 1 set of conversions
nmaududi 0:4fb921928934 126
nmaududi 0:4fb921928934 127 ADC0_SC1A = 13 & ADC_SC1_ADCH_MASK; // ADC0_SE8 that is connected to PTB0
nmaududi 0:4fb921928934 128 ADC0_SC1A = 0& ADC_SC1_DIFF_MASK; //0 Single-ended conversions and input channels are selected.
nmaududi 0:4fb921928934 129
nmaududi 0:4fb921928934 130 Vrefl = (Vref_low.read_u16());
nmaududi 0:4fb921928934 131
nmaududi 0:4fb921928934 132 } else if (channel==CHANNEL_1){
nmaududi 0:4fb921928934 133
nmaududi 0:4fb921928934 134 // Enable clocks
nmaududi 0:4fb921928934 135 SIM_SCGC6 |= SIM_SCGC6_ADC0_MASK; // ADC 0 clock
nmaududi 0:4fb921928934 136
nmaududi 0:4fb921928934 137 // Configure ADC
nmaududi 0:4fb921928934 138 ADC0_CFG1 = 0; // Reset register
nmaududi 0:4fb921928934 139
nmaududi 0:4fb921928934 140 ADC0_CFG1 |= (ADC_CFG1_MODE(3)| // 8 bit mode
nmaududi 0:4fb921928934 141 ADC_CFG1_ADICLK(0)| // Input Bus Clock (20-25 MHz out of reset (FEI mode))
nmaududi 0:4fb921928934 142 ADC_CFG1_ADIV(0)); // Clock divide by 1
nmaududi 0:4fb921928934 143 ADC0_CFG1 = 0 & ADC_CFG1_ADLPC_MASK; // normal power configuration
nmaududi 0:4fb921928934 144 ADC0_CFG1 = 1 & ADC_CFG1_ADLSMP_MASK; // Long time sample configuration
nmaududi 0:4fb921928934 145
nmaududi 0:4fb921928934 146
nmaududi 0:4fb921928934 147 ADC0_CFG2 = 0 & ADC_CFG2_ADHSC_MASK; // 1 High-speed conversion sequence, 0 for normal coversion, zero as sampling is 10 usec, bus clock is good enought
nmaududi 0:4fb921928934 148 ADC0_CFG2 = 0 & ADC_CFG2_ADLSTS_MASK; // Default longest sample time; 20 extra ADCK cycles; 24 ADCK cycles total.
nmaududi 0:4fb921928934 149 ADC0_CFG2 = 0 & ADC_CFG2_ADACKEN_MASK; // Asynchronous clock output disabled; Asynchronous clock is enabled only if selected by ADICLK and a conversion is active. low power configuration
nmaududi 0:4fb921928934 150
nmaududi 0:4fb921928934 151
nmaududi 0:4fb921928934 152 ADC0_SC3 = 1 & ADC_SC3_ADCO_MASK; // set to 1 for continuious conversion, 0 for only 1 set of conversions
nmaududi 0:4fb921928934 153
nmaududi 0:4fb921928934 154 ADC0_SC1A = 14 & ADC_SC1_ADCH_MASK; // ADC0_SE9 that is connected to PTB1
nmaududi 0:4fb921928934 155 ADC0_SC1A = 0 & ADC_SC1_DIFF_MASK; //0 Single-ended conversions and input channels are selected.
nmaududi 0:4fb921928934 156
nmaududi 0:4fb921928934 157 ADC_vortex_frequency_input = (vortex_frequency.read_u16());
nmaududi 0:4fb921928934 158
nmaududi 0:4fb921928934 159 } else
nmaududi 0:4fb921928934 160 {
nmaududi 0:4fb921928934 161 // Enable clocks
nmaududi 0:4fb921928934 162 SIM_SCGC6 |= SIM_SCGC6_ADC0_MASK; // ADC 0 clock
nmaududi 0:4fb921928934 163
nmaududi 0:4fb921928934 164 // Configure ADC
nmaududi 0:4fb921928934 165 ADC0_CFG1 = 0; // Reset register
nmaududi 0:4fb921928934 166
nmaududi 0:4fb921928934 167 ADC0_CFG1 |= (ADC_CFG1_MODE(3)| // 8 bit mode
nmaududi 0:4fb921928934 168 ADC_CFG1_ADICLK(0)| // Input Bus Clock (20-25 MHz out of reset (FEI mode))
nmaududi 0:4fb921928934 169 ADC_CFG1_ADIV(0)); // Clock divide by 1
nmaududi 0:4fb921928934 170 ADC0_CFG1 = 0 & ADC_CFG1_ADLPC_MASK; // normal power configuration
nmaududi 0:4fb921928934 171 ADC0_CFG1 = 1 & ADC_CFG1_ADLSMP_MASK; // Long time sample configuration
nmaududi 0:4fb921928934 172
nmaududi 0:4fb921928934 173
nmaududi 0:4fb921928934 174 ADC0_CFG2 = 0 & ADC_CFG2_ADHSC_MASK; // 1 High-speed conversion sequence, 0 for normal coversion, zero as sampling is 10 usec, bus clock is good enought
nmaududi 0:4fb921928934 175 ADC0_CFG2 = 0 & ADC_CFG2_ADLSTS_MASK; // Default longest sample time; 20 extra ADCK cycles; 24 ADCK cycles total.
nmaududi 0:4fb921928934 176 ADC0_CFG2 = 0 & ADC_CFG2_ADACKEN_MASK; // Asynchronous clock output disabled; Asynchronous clock is enabled only if selected by ADICLK and a conversion is active. low power configuration
nmaududi 0:4fb921928934 177
nmaududi 0:4fb921928934 178
nmaududi 0:4fb921928934 179 ADC0_SC3 = 1 & ADC_SC3_ADCO_MASK; // set to 1 for continuious conversion, 0 for only 1 set of conversions
nmaududi 0:4fb921928934 180
nmaududi 0:4fb921928934 181 ADC0_SC1A = 26 & ADC_SC1_ADCH_MASK; // temperature sensor (reading in value from internal sensor) V
nmaududi 0:4fb921928934 182 ADC0_SC1A = 0 & ADC_SC1_DIFF_MASK; //0 Single-ended conversions and input channels are selected.
nmaududi 0:4fb921928934 183
nmaududi 0:4fb921928934 184 Vtemp = (TempSensor.read_u16());
nmaududi 0:4fb921928934 185 }
nmaududi 0:4fb921928934 186
nmaududi 0:4fb921928934 187
nmaududi 0:4fb921928934 188 }
nmaududi 0:4fb921928934 189
nmaududi 0:4fb921928934 190