revised code

Dependencies:   mbed

ADC_input.cpp

Committer:
bcis93
Date:
2019-10-04
Revision:
1:9fa7cc80f1a7
Parent:
0:4fb921928934
Child:
2:64a34ae90bb1

File content as of revision 1:9fa7cc80f1a7:

/**----------------------------------------------------------------------------
 *
 *            \file frequency_detector.cpp
--                                                                           --
--              ECEN 5803 Mastering Embedded System Architecture             --
--                  Project 1 Module 4                                       --
--                Microcontroller Firmware                                   --
--                      frequency_detector.cpp                                           --
--                                                                           --
-------------------------------------------------------------------------------
--
--  Designed for:  University of Colorado at Boulder
--                
--                
--  Designed by:  Tim Scherr
--  Revised by:  Naved Maududi and Bryan Cisneros 
-- 
-- Version: 2.1
-- Date of current revision:  2017-09-25   
-- Target Microcontroller: Freescale MKL25ZVMT4 
-- Tools used:  ARM mbed compiler
--              ARM mbed SDK
--              Freescale FRDM-KL25Z Freedom Board
--               
--               
   Functional Description:  
   This file contains code that takes in quasi-sine wave ADC inputs from the flow meter
     From the ADC inputs, it calculates the frequency of that sine wave. The frequency is 
     important in determining the flow rate and velocity for the flowmeter that are outputed
     to the display. 
-- 
--      Copyright (c) 2015 Tim Scherr  All rights reserved.
*/


#include "shared.h" 


PinName const ch0 = PTB0;  // channel 0 (PTB0) to A/D pin VREFL
PinName const ch1 = PTB1; // channel 1 (PTB1) to J10_4 a virtual vortex frequency input,
PinName const ch2 = PTB2; // channel 2 (PTB2) to an actual internal TempSensor
    
#define ADC0_CFG1 (ADC0->CFG1)
#define ADC0_CFG2 (ADC0->CFG2)
#define ADC0_SC1A (ADC0->SC1[0]) // ADC0 to SC1A
#define ADC0_SC3 (ADC0->SC3)
#define SIM_SCGC6 (SIM->SCGC6)
#define CHANNEL_0               (0U)
#define CHANNEL_1               (1U)
#define CHANNEL_2               (2U)

uint16_t ADC_vortex_frequency_input = 0;
uint16_t Vrefl = 0;
uint16_t Vtemp = 0;

AnalogIn Vref_low(ch0);

AnalogIn vortex_frequency(ch1);

AnalogIn TempSensor(ch2);


void adc_calibration(void){
    
        // Enable clocks
    SIM_SCGC6 |= SIM_SCGC6_ADC0_MASK;   // ADC 0 clock

    // Configure ADC
    ADC0_CFG1 = 0; // Reset register
    

                 
    ADC0_CFG1 |= (ADC_CFG1_MODE(0)|   // 8 bit mode
                 ADC_CFG1_ADICLK(0)|   // Input Bus Clock for calibration
                 ADC_CFG1_ADIV(3));  // Long time sample configuration
                 
   ADC0_CFG1 = 0 & ADC_CFG1_ADLPC_MASK; // normal power configuration
   ADC0_CFG1 = 1 & ADC_CFG1_ADLSMP_MASK; // Long time sample configuration

    
  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
  ADC0_CFG2 =  0 & ADC_CFG2_ADLSTS_MASK;     // Default longest sample time; 20 extra ADCK cycles; 24 ADCK cycles total.
  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
    


    ADC0_SC3 = 1 & ADC_SC3_AVGE_MASK; // 1 High-speed conversion sequence, for calibration
    ADC0_SC3  = 3 & ADC_SC3_AVGS_MASK;      // Average of 32 samples, for calibration purposes
    ADC0_SC3 = 1 & ADC_SC3_CAL_MASK; // set to 1 for calibration of the ADC prior to completing conversions
    
  uint16_t PG_calibration = 0; //Initialize or clear a 16-bit variable in RAM.
    uint16_t MG_calibration = 0; //Initialize or clear a 16-bit variable in RAM.
    
    PG_calibration = (ADC0->CLP0)+(ADC0->CLP1)+(ADC0->CLP2)+(ADC0->CLP3)+(ADC0->CLP4)+(ADC0->CLPS); // Add the plus-side calibration results to the variable
    PG_calibration = PG_calibration/2; // Divide the variable by two
    PG_calibration = (PG_calibration & 0xFF00); //Set the MSB of the variable.
    ADC0->PG = (ADC0->CLP0)+PG_calibration; //Store the value in the plus-side gain calibration register PG.
    
    MG_calibration = (ADC0->CLM0)+(ADC0->CLM1)+(ADC0->CLM2)+(ADC0->CLM3)+(ADC0->CLM4)+(ADC0->CLMS); // Add the minus-side calibration results to the variable
    MG_calibration = MG_calibration/2; //Divide the variable by two
    MG_calibration = (MG_calibration & 0xFF00); //Set the MSB of the variable.
    ADC0->MG = (ADC0->CLM0)+MG_calibration; //Store the value in the plus-side gain calibration register MG.
    // END OF CALIBRATION
}




void read_ADC(uint8_t channel)
{
    if (channel==CHANNEL_0){
        // Enable clocks
    SIM_SCGC6 |= SIM_SCGC6_ADC0_MASK;   // ADC 0 clock

    // Configure ADC
    ADC0_CFG1 = 0; // Reset register

    ADC0_CFG1 |= (ADC_CFG1_MODE(0)|   // 8 bit mode
                  ADC_CFG1_ADICLK(0)|   // Input Bus Clock (20-25 MHz out of reset (FEI mode))
                  ADC_CFG1_ADIV(0)); // Clock divide by 1
    ADC0_CFG1 = 0 & ADC_CFG1_ADLPC_MASK;   // normal power configuration
    ADC0_CFG1  = 1 & ADC_CFG1_ADLSMP_MASK;  // Long time sample configuration
    
   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
   ADC0_CFG2 = 0 & ADC_CFG2_ADLSTS_MASK;     // Default longest sample time; 20 extra ADCK cycles; 24 ADCK cycles total.
   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
    

  ADC0_SC3 = 0 & ADC_SC3_ADCO_MASK; // set to 1 for continuious conversion, 0 for only 1 set of conversions
  
  ADC0_SC1A = 13 & ADC_SC1_ADCH_MASK; // ADC0_SE8 that is connected to PTB0
  ADC0_SC1A = 0& ADC_SC1_DIFF_MASK; //0 Single-ended conversions and input channels are selected.
                             
    Vrefl = (Vref_low.read_u16());
        
    } else if (channel==CHANNEL_1){
        
        // Enable clocks
    SIM_SCGC6 |= SIM_SCGC6_ADC0_MASK;   // ADC 0 clock

    // Configure ADC
    ADC0_CFG1 = 0; // Reset register
    
   ADC0_CFG1 |= (ADC_CFG1_MODE(3)|   // 8 bit mode
                  ADC_CFG1_ADICLK(0)|   // Input Bus Clock (20-25 MHz out of reset (FEI mode))
                  ADC_CFG1_ADIV(0)); // Clock divide by 1
    ADC0_CFG1 = 0 & ADC_CFG1_ADLPC_MASK;   // normal power configuration
    ADC0_CFG1  = 1 & ADC_CFG1_ADLSMP_MASK;  // Long time sample configuration

    
   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
   ADC0_CFG2 = 0 & ADC_CFG2_ADLSTS_MASK;     // Default longest sample time; 20 extra ADCK cycles; 24 ADCK cycles total.
   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
    

  ADC0_SC3 = 1 & ADC_SC3_ADCO_MASK; // set to 1 for continuious conversion, 0 for only 1 set of conversions

  ADC0_SC1A = 14 & ADC_SC1_ADCH_MASK; // ADC0_SE9 that is connected to PTB1
  ADC0_SC1A = 0 & ADC_SC1_DIFF_MASK; //0 Single-ended conversions and input channels are selected.
                              
    ADC_vortex_frequency_input = (vortex_frequency.read_u16());
        
    } else 
    {
        // Enable clocks
    SIM_SCGC6 |= SIM_SCGC6_ADC0_MASK;   // ADC 0 clock

    // Configure ADC
    ADC0_CFG1 = 0; // Reset register
    
   ADC0_CFG1 |= (ADC_CFG1_MODE(3)|   // 8 bit mode
                  ADC_CFG1_ADICLK(0)|   // Input Bus Clock (20-25 MHz out of reset (FEI mode))
                  ADC_CFG1_ADIV(0)); // Clock divide by 1
    ADC0_CFG1 = 0 & ADC_CFG1_ADLPC_MASK;   // normal power configuration
    ADC0_CFG1  = 1 & ADC_CFG1_ADLSMP_MASK;  // Long time sample configuration

    
   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
   ADC0_CFG2 = 0 & ADC_CFG2_ADLSTS_MASK;     // Default longest sample time; 20 extra ADCK cycles; 24 ADCK cycles total.
   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
    

  ADC0_SC3 = 1 & ADC_SC3_ADCO_MASK; // set to 1 for continuious conversion, 0 for only 1 set of conversions

  ADC0_SC1A = 26 & ADC_SC1_ADCH_MASK; // temperature sensor (reading in value from internal sensor) V
  ADC0_SC1A = 0 & ADC_SC1_DIFF_MASK; //0 Single-ended conversions and input channels are selected.
                      
    Vtemp =  (TempSensor.read_u16());
    }

    
}