EEVblog Electronics Community Forum

Electronics => Microcontrollers => Topic started by: raff5184 on December 06, 2017, 05:27:33 am

Title: [beginner]: KL03 MCU - Configuration of ADC
Post by: raff5184 on December 06, 2017, 05:27:33 am
Hi all,
I am a beginner with microcontrollers, so I ask for your patience.
I need to use the ADC function of a Freescale KL03. From the reference manual I understood how it works and I found the definitions of all the ADC parameters in the code. However I can't find, in the code, where I can define my configuration for a specific mode of operation of the ADC.

For example, if I want it to work: hardware triggered, with continuous conversions and average on 4 samples, do I have to create my own function, or I just give the parameters in input to some function somewhere in the code? But where?
Title: Re: [beginner]: KL03 MCU - Configuration of ADC
Post by: ElektroQuark on December 11, 2017, 07:17:08 pm
You have to use the NXP provided SDK, or create your own functions or write directly to registers.
Title: Re: [beginner]: KL03 MCU - Configuration of ADC
Post by: raff5184 on December 11, 2017, 08:07:56 pm
thanks for your reply.
I actually already have the NXP SDK but it is not very clear how to initialize the ADC, especially if I want to use the pin PTA12
Title: Re: [beginner]: KL03 MCU - Configuration of ADC
Post by: ElektroQuark on December 12, 2017, 08:17:21 am
You will have to read the SDK help files them. It all depends on the SDK.
Sorry, I can help as I don't have experience with it.
Title: Re: [beginner]: KL03 MCU - Configuration of ADC
Post by: Geoff_S on December 12, 2017, 09:30:23 am
Have you looked at the SDK v2 ADC example ?  It should be fairly obvious how they've assigned the ADC pin muxes etc from the main source file and board.c/board.h.
Title: Re: [beginner]: KL03 MCU - Configuration of ADC
Post by: uTasker on December 12, 2017, 11:44:24 pm
Hi

If you choose the ADC0_SE0 channel and don't touch PTA12 for any other peripheral function it will automatically be there.
This is because PTA12 defaults to the ADC0_SE0 (analog function).

In case you have been using this pin for something else previously, example a GPIO or timer output, you can reprogram it to its (default) ALT0 function again in the PORTA_PCR12 register - i.e PORTA_PCR12 &= ~0x00000700; (setting the MUX mask back to 0 -> ALT0 function).

If you want hardware triggering pf the ADC conversion you will need to program a trigger from one of the possible TPM trigger sources - it is best to get it working in software triggered mode before moving to HW triggering.

Regards

uTasker

KL03: http://www.utasker.com/kinetis/FRDM-KL03Z.html (http://www.utasker.com/kinetis/FRDM-KL03Z.html)
Title: Re: [beginner]: KL03 MCU - Configuration of ADC
Post by: alexyzhov on December 15, 2017, 04:13:07 am
FSL's design are always full of complexity and powerful. But unfortunately, the MCUxpressoSDK document really sucks.
Here is my experience&code based on KSDK2.1, MK66F18, I believe the IP core are the mostly similar to KL series. And I've tested the code on my smart car while participating the competition ^-^

Just like STM32 or other ARM-based MCU, you should firstly set up the pinmux like:
Code: [Select]
PORT_SetPinMux(PORTC, 9u, kPORT_PinDisabledOrAnalog);
following the datasheet, we could see PTC9 could be mux to ADC1_SE5b, which also means ADC 1, Group B, Channel 5.
And then, to finish setting up ADC:
Code: [Select]
    adc16_config_t ADC1_config;    // defines ADC configure structure   
    ADC16_GetDefaultConfig(&ADC1_config);       // ??ADC????   
    ADC1_config.resolution = kADC16_ResolutionSE12Bit;    // Set ADC1 working on 12-bit resolution mode
   
    ADC16_Init(ADC1, &ADC1_config);

    ADC16_EnableHardwareTrigger(ADC1, true);   // ??ADC????(Auto Calibration??)
    ADC16_DoAutoCalibration(ADC1);                  // u should always finish this step if firstly use ADC after reset.
    ADC16_EnableHardwareTrigger(ADC1, false);  // ??ADC????

    ADC16_SetHardwareAverage(ADC1, kADC16_HardwareAverageDisabled);             // ??ADC1??0?????
   
    ADC16_SetChannelMuxMode(ADC1, kADC16_ChannelMuxB);

After finishing initializing Pins and ADCs, u could package a single conversion function like this:
Code: [Select]
uint32_t Motor_GetADCVal(_Motor_t MOTORn)
{
    static adc16_channel_config_t ADC1_SExb_config;
    ADC1_SExb_config.channelNumber = MOTORn;                                  // 4 ~ ADC1 SE4a(b), 4 ~ ADC1 SE5a(b)
    ADC1_SExb_config.enableDifferentialConversion = false;                    // ?????????
    ADC1_SExb_config.enableInterruptOnConversionCompleted = false;            // ?????????
   
    ADC16_SetChannelConfig(ADC1, 0, &ADC1_SExb_config);                        // This trigs ADC start working
    while(kADC16_ChannelConversionDoneFlag != ADC16_GetChannelStatusFlags(ADC1, 0));     
    return ADC16_GetChannelConversionValue(ADC1, 0);               // ???????????
}

And finially congratulations! This is a single-end and single conversion sample, and these codes should make ADCs work successfully.

ADCs on Kinetis are really flexible, pins and channels can be mux and reused in so many ways. Each ADC has several Channels that could be linked to the main converter. There are 2 Groups in each ADC, and each Group contains dozens of pins(7?). These two Group use some same channel numbers which leads to ADC part-time using. U can change register settings to define which Group are u used right now in the ADC. After setting this, if u let ADC working in Single Conversion Mode but NOT Continuous Mode, u could start a definite ADC conversion through a named channel linked to a named pin, and u can check the register flags to find out whether the conversion has finished or not.

PS: some comments are wrote in Chinese and it seems our forum dosen't support Chinese Encoding Charsets so well :(