Kinetis K60N512 ADC

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Kinetis K60N512 ADC

Jump to solution
1,429 Views
syedr
Contributor I

Hello,

I am trying to work with the ADC module on the K60 board. I have run through the available demos to understand the working of the ADC module, but unable to fully understand how the code is working. I have tried to find any related documentation that would allow to me make some simple measurements using the ADC. Could anyone point me to any good documentation that allows me to set up the ADC using Processor Expert without having to use the interrupt service, or at least gives a overview of how the module needs to be setup to take measurements.

Thanks

Tags (3)
1 Solution
457 Views
JimDon
Senior Contributor III

First of all, this code was test on the KL25, however I looked over the K60 Reference Manual (RM) (which you should have if you don't already) and the ADC looked to same. You may need to adjust the code for you situation.

Here is a high level over view of what must be done:

1. Set the PCR Mux value to 0 for the pin you are going to use. When the Mux Value is 0, "analog function" is selected.

For Port B Bit 0 :

    PORTB_BASE_PTR->PCR[0] &= ~PORT_PCR_MUX(0x07);

2. We need to gate the clock to the ADC0 module:

 SIM_SCGC6 |= SIM_SCGC6_ADC0_MASK;                                           

3. Set the ADC clock and the mode to single ended 16 bit and other settings. Search on ADC0_CFG1, ADC0_CFG2,ADC0_SC2  in the RM pdf and confirm these setting apply to you clocks and prefrences.

    
ADC0_CFG1 = ADC_CFG1_ADIV(0x2) |  (ADC_CFG1_MODE(0x03) | ADC_CFG1_ADICLK(0x01));           
ADC0_CFG2 &= ~(ADC_CFG2_ADACKEN_MASK | ADC_CFG2_ADHSC_MASK | ADC_CFG2_ADLSTS(0x03));     
ADC0_SC2 = 0; 

4. Clear the calibration flag:

    ADC0_SC3 = ADC_SC3_CALF_MASK; 

Finally, this function will read the channel:

int analogRead(int ch)
{
     
     // 28.3.7 Status and Control Register 3 (ADCx_SC3)
     // Set single conversion, no averaging.
    ADC_SC3_REG(ADC0_BASE_PTR) &= (uint32_t) ~(ADC_SC3_ADCO_MASK | ADC_SC3_AVGE_MASK | ADC_SC3_AVGS_MASK );
    // 28.3.6 Status and Control Register 2 (ADCx_SC2)
    // Set software trigger, disable compare function, disable DMA.
    ADC_SC2_REG(ADC0_BASE_PTR) &= (uint32_t)~(ADC_SC2_ADTRG_MASK | ADC_SC2_ACFE_MASK | ADC_SC2_DMAEN_MASK);
    
    
    
    // Start a conversion by writing the channel number
    ADC_SC1_REG(ADC0_BASE_PTR, 0U) =    (uint32_t)_adc[ch].chan_no;
    // Wait for it to complete.
    // 28.3.6 Status and Control Register 2 (ADCx_SC2)
    while( ((ADC_SC2_REG(ADC0_BASE_PTR) & ADC_SC2_ADACT_MASK) ) != 0U)
       ;
    return  (int)(ADC_R_REG(ADC0_BASE_PTR,0));
 }
 

View solution in original post

2 Replies
458 Views
JimDon
Senior Contributor III

First of all, this code was test on the KL25, however I looked over the K60 Reference Manual (RM) (which you should have if you don't already) and the ADC looked to same. You may need to adjust the code for you situation.

Here is a high level over view of what must be done:

1. Set the PCR Mux value to 0 for the pin you are going to use. When the Mux Value is 0, "analog function" is selected.

For Port B Bit 0 :

    PORTB_BASE_PTR->PCR[0] &= ~PORT_PCR_MUX(0x07);

2. We need to gate the clock to the ADC0 module:

 SIM_SCGC6 |= SIM_SCGC6_ADC0_MASK;                                           

3. Set the ADC clock and the mode to single ended 16 bit and other settings. Search on ADC0_CFG1, ADC0_CFG2,ADC0_SC2  in the RM pdf and confirm these setting apply to you clocks and prefrences.

    
ADC0_CFG1 = ADC_CFG1_ADIV(0x2) |  (ADC_CFG1_MODE(0x03) | ADC_CFG1_ADICLK(0x01));           
ADC0_CFG2 &= ~(ADC_CFG2_ADACKEN_MASK | ADC_CFG2_ADHSC_MASK | ADC_CFG2_ADLSTS(0x03));     
ADC0_SC2 = 0; 

4. Clear the calibration flag:

    ADC0_SC3 = ADC_SC3_CALF_MASK; 

Finally, this function will read the channel:

int analogRead(int ch)
{
     
     // 28.3.7 Status and Control Register 3 (ADCx_SC3)
     // Set single conversion, no averaging.
    ADC_SC3_REG(ADC0_BASE_PTR) &= (uint32_t) ~(ADC_SC3_ADCO_MASK | ADC_SC3_AVGE_MASK | ADC_SC3_AVGS_MASK );
    // 28.3.6 Status and Control Register 2 (ADCx_SC2)
    // Set software trigger, disable compare function, disable DMA.
    ADC_SC2_REG(ADC0_BASE_PTR) &= (uint32_t)~(ADC_SC2_ADTRG_MASK | ADC_SC2_ACFE_MASK | ADC_SC2_DMAEN_MASK);
    
    
    
    // Start a conversion by writing the channel number
    ADC_SC1_REG(ADC0_BASE_PTR, 0U) =    (uint32_t)_adc[ch].chan_no;
    // Wait for it to complete.
    // 28.3.6 Status and Control Register 2 (ADCx_SC2)
    while( ((ADC_SC2_REG(ADC0_BASE_PTR) & ADC_SC2_ADACT_MASK) ) != 0U)
       ;
    return  (int)(ADC_R_REG(ADC0_BASE_PTR,0));
 }
 
457 Views
DavidS
NXP Employee
NXP Employee

Hi Syed,

Great place to start the education process is:

http://www.freescale.com/infocenter/

In the search window type "kinetis ADC".

Also goto a specific Kinetis device product page and click on the "Documentation" to see many appnotes.

On demand online training:

Past training at our FTF Americas show:

http://www.freescale.com/webapp/sps/site/overview.jsp?code=FTF_OLLTABLE

Regards,

David

0 Kudos