ADC in KL03 config sample code

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

ADC in KL03 config sample code

Jump to solution
1,441 Views
raff5184
Contributor II

Has anyone a guide/sample code of how to initialize/configure the ADC  receiving a voltage input from PTA12?

I'm having a hard time understanding:

1. How to configure the PTA12 in this case;

2. if, for the ADC, I need to initialize something else apart from ADC0_CFG1, ADC0_CFG2, ADC0_SC1A (?), ADC0_SC2

3. Where exactly in the code I am supposed to configure the ADC

Thank you

0 Kudos
1 Solution
1,106 Views
mjbcswitzerland
Specialist V

Hi

Attached is a binary file for the FRDM-KL03Z which reads the PTA12 ADC input and prints the value to the VCOM UART output.

You can build this by taking the (Free) Open Source uTasker project on GIT hub [https://github.com/uTasker/uTasker-Kinetis] and setting the main define in config.h to the FRDM_KL03Z (or any other board). In ADC_Timers.h enable TEST_ADC and set
adc_setup.int_adc_bit = ADC_SE0_SINGLE; // ADC input on PTA12 pin
to select this ADC input be be tested.

Build in any IDE and in Visual Studio to simulate the KL03 and its ADC. The code shows how to calibrate, configure and read and its API is documented at http://www.utasker.com/docs/uTasker/uTaskerADC.pdf where it also shows how to use its automatic input range interrupts etc.

Regards

Mark


Kinetis: http://www.utasker.com/kinetis.html
Kinetis KL03:
- http://www.utasker.com/kinetis/FRDM-KL03Z.html

Professional Kinetis support, one-on-one training and complete fast-track project solutions: http://www.utasker.com/support.html

Freightened of uTasker? See Video at https://www.youtube.com/watch?v=K8ScSgpgQ6M&t=311s and have complete KDS project working in 15 minutes.

pastedImage_6.png

View solution in original post

8 Replies
1,106 Views
Robin_Shen
NXP TechSupport
NXP TechSupport

Hi raff5184,

Please download the SDK_2.3.0_FRDM-KL03Z and refer the adc16 interrupt.

You just need to modify the DEMO_ADC16_USER_CHANNEL.

If you are using FRDM-KL03Z board, notice that the PTA12 was connect with ACCEL_INT of MMA8451Q.

ADC0_SE0 PTA12 SDK_2.3.0_FRDM-KL03Z.png

Best Regards,

Robin

 

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

1,107 Views
mjbcswitzerland
Specialist V

Hi

Attached is a binary file for the FRDM-KL03Z which reads the PTA12 ADC input and prints the value to the VCOM UART output.

You can build this by taking the (Free) Open Source uTasker project on GIT hub [https://github.com/uTasker/uTasker-Kinetis] and setting the main define in config.h to the FRDM_KL03Z (or any other board). In ADC_Timers.h enable TEST_ADC and set
adc_setup.int_adc_bit = ADC_SE0_SINGLE; // ADC input on PTA12 pin
to select this ADC input be be tested.

Build in any IDE and in Visual Studio to simulate the KL03 and its ADC. The code shows how to calibrate, configure and read and its API is documented at http://www.utasker.com/docs/uTasker/uTaskerADC.pdf where it also shows how to use its automatic input range interrupts etc.

Regards

Mark


Kinetis: http://www.utasker.com/kinetis.html
Kinetis KL03:
- http://www.utasker.com/kinetis/FRDM-KL03Z.html

Professional Kinetis support, one-on-one training and complete fast-track project solutions: http://www.utasker.com/support.html

Freightened of uTasker? See Video at https://www.youtube.com/watch?v=K8ScSgpgQ6M&t=311s and have complete KDS project working in 15 minutes.

pastedImage_6.png

1,106 Views
raff5184
Contributor II

Thank you Mark, I tried your .bin file and it works properly. However, the ADC_SE0_SINGLE is not defined in the project. I looked into the code and I understood that I need to define it in the kinetis.h, but what value do I need to assign to it?

#define ADC_SE0_SINGLE  = ... ?

Thank you

0 Kudos
1,106 Views
mjbcswitzerland
Specialist V

Hi

You can add
#define ADC_SE0_SINGLE      0

to the header (the open source version has this only for the KE parts but I will update it to have it also for the KL parts with this name - you can also use ADC_DP0_SINGLE since it is equivalent).

Regards

Mark

1,106 Views
raff5184
Contributor II

Thank you, I tried to generate the .bin file following the instructions in your first reply, by just using the #defines (TEST_ADCFRDM_KL03Zadc_setup.int_adc_bit and so on) in the uTasker, but nothing is printed onto the terminal.  Instead, like I said, your .bin file works properly.

I also tried with 2 functions, one to configure the ADC and another to read the converted data as in the following code, but this always prints the same value, even though I feed the ADC with different voltage values (that are correctly read by your .bin file)

extern void myADC_CONFIG(void){
fnDebugMsg("\nMY ADC CONFIG\n");
 ADC_SETUP adc_setup; // interrupt configuration parameters
adc_setup.int_type = ADC_INTERRUPT; // identifier when configuring
PORTA_PCR12 &= ~0x00000700;
adc_setup.int_priority = PRIORITY_ADC; // ADC interrupt priority
adc_setup.int_adc_int_type = (ADC_SINGLE_SHOT_TRIGGER_INT); // interrupt type
// adc_setup.int_adc_int_type = (ADC_ZERO_CROSSING_INT_POSITIVE | ADC_ZERO_CROSSING_INT_NEGATIVE | ADC_LOW_LIMIT_INT | ADC_HIGH_LIMIT_INT); // interrupt type - interrupt continuously
 adc_setup.int_adc_mode = (ADC_SW_TRIGGERED | ADC_8_BIT_MODE);
adc_setup.int_adc_offset = 0; // no offset
adc_setup.int_adc_bit = ADC_SE0_SINGLE;
fnConfigureInterrupt((void *)&adc_setup); // configure ADC
 fnDebugMsg("Configuration Done\r\n");
 myADC_READ();
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍


extern void myADC_READ(void){
    int iADC_delay = -1;
    ADC_RESULTS results;

    ADC_SETUP adc_setup_r;                                                 // interrupt configuration parameter
    adc_setup_r.int_type = ADC_INTERRUPT;                                  // identifier when configuring
    adc_setup_r.int_adc_bit = ADC_SE0_SINGLE;
    adc_setup_r.int_adc_result = &results;
    do 
    {
        fnConfigureInterrupt((void *)&adc_setup_r);                        // get result
      iADC_delay++;
    }    while (results.ucADC_status[0] == ADC_RESULT_NOT_READY);           // 'poll until the result is ready
    
    if (results.ucADC_status[0] != ADC_RESULT_NOT_READY) {
    fnDebugMsg("ADC value = ");
    fnDebugHex(results.sADC_value[0], 2);
//  fnDebugHex(results.sADC_value[0], (WITH_SPACE | WITH_LEADIN | WITH_CR_LF | sizeof(results.sADC_value[0])));
    fnDebugMsg("\r\n");
    fnDebugMsg("Wait = ");
    fnDebugDec(iADC_delay, 0);                                    // display the wait count value
    fnDebugMsg("\r\n");
    }
    else {
      fnDebugMsg("ADC not ready\r\n");
    }
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
1,106 Views
mjbcswitzerland
Specialist V

Hi

I had built from the developer's version and not the Open Source version so I checked and found the problem:
The KL03 is a small device and so interrupts are fixed in Flash (rather than relocating to SRAM). When I checked I found that the ADC0 interrupt vector was not included and so when the ADC interrupt fired it went to the uninitialised interrupt handler.

If you pull new versions of kinetis.h, kinetis.c and ADC_Timers.h this has been updated so that it will operate.

Beware that in your other trial you haven't initialised all of the configuration values so some will be random, which probably explains the why it didn't work (also, the ADC calibration is missing).

Since the reference should be OK now I would use that as base.

Regards

Mark

P.S. I also advise running it in Visual Studio since it will simulate the KL03 and it immediately showed me the problem so I could quickly fix it.

1,106 Views
raff5184
Contributor II

I'm using the simulator (thank you for the tip!). The memory usage is always around 3/4 MB, and I added the calibration that I do only one time at the beginning, correct?

However, I think there is a problem with the ADC interrupt.

Any idea about this exception in the kinetisSim.c?

Capture.JPG

0 Kudos
1,106 Views
mjbcswitzerland
Specialist V

Hi

You are testing your code (rather than the reference) but you haven't set up a user handler for the ADC0 interrupt. For example:

adc_setup.int_handler = adc_level_change_high; // handling function

If you leave this entry uninitialised it will have the value 0xcccccccc (which VS inserts in all uninitialised locations), which is what the exception is showing.

Therefore I recommend that you follow the reference to avoid missing setup details.

VS and simulation allows massively more power-ful debugging compared to the HW target IDEs so if you make use of it you will find that it makes embedded development much simpler and reliable too.

When you call fnConfigureInterrupt() to set up and start the ADC take a look at the setup struct as follows:

pastedImage_1.png

Here you see that the entry int_handler has a valid entry - yours will be 0xcccccccc since you haven't initialised it.
In this reference there are a couple of other uninitialised entries (like the trigger levels) but there are not an issue since this function is not being used in this case.

Once the simulator operates as expected the HW will do so too.

Regards

Mark

0 Kudos