K32 Lシリーズマイクロコントローラのナレッジベース

表示  限定  | 次の代わりに検索 

K32 L Series Microcontrollers Knowledge Base


Introduction: SLCD of K32L2B has the capability to detect shorting between BP to FP but to detect shorting between two adjacent BPs or FPs there isn't any direct method therefore we will leverage the capability of LCD to detect BP to FP short to detect two adjacent BP's short and two adjacent FP's short. Project Description: There are two separate functions in the attached demo project: void fault_diffplane(void); ->to detect FP to BP short void fault_sameplane(void); ->to detect adjacent BP's short and FP's shorts First step is to initialize an array with all LCD pins number with  all BP's grouped together in the array and all FP's pin together inside the same array. This is done just for ease of implementing fault detection logic for both the function.  For eg. LCD_PINS[12]={14,15,59,60,20,24,26,27,40,42,43,44}; //starting 4 are BP & rest are FP Detecting BP to FP fault is straight forward done using fault_diffplane() function but for fault_sameplane() function we first need to re-initialize the LCD pins as alternate BP and FP pins regardless of the pins being actually FP or BP. Note: fault_diffplane() can detect shorting between any FP and BP but fault_sameplane() can only detect shorting in between adjacent FP's and adjacent BP's in the LCD_PINS array. Also fault_sameplane() requires re initialization of LCD pins as alternative BP and FP irrespective of their actual configuration in the application therefore user should carefully use this function(may be in the starting of code) in his application to avoid any problems. After either of the above fault detection functions are called, the Fault counts are stored in a array fault_count_difP[] fault_count_samP[] User can see the reduction in counts at the respective LCP pin index in the fault_count_difP[] & fault_count_samP[] array when those pins are shorted. Following is the screen shot of the same when LCD pin 59(BP) is shorted with pin43(FP)   When Pin 59(BP) is shorted with Pin60(BP)   Attached is the reference project tested on FRDM K32L2B development board LCD.   Thanks Madhur    
Introduction Problem Statement: K32L2B ADCs don't have the capability to scan through all the connected channels in one conversion. The input channels are muxed into the ADC, So you need to set the ADCx_Rn register to the channel number you want to convert, Run the conversion, read the results and then Set the other ADCx_Rn in that ADC to the next channel to be converted. The next conversion can then  be triggered. You have to tell each conversion the input channel it is to convert. Everytime setting a new channel and reading previous channel data can consume much CPU core bandwidth.  The goal of this example is to read all ADC inputs of Kinetis K32L2B in a row without the need of using CPU core for switching channels  and reading individual result values. Project Description The DMA in this example is used for controlling all the channel switching, reading the results for series of measurement into a memory buffer. The Direct Memory Access (DMA) channels are configured for writing and reading ADC registers the following way: DMA channel 0 reads converted results (ADC0_RA register) and stores them in g_adc16SampleDataArray[ ]. DMA channel 1 selects the ADC channel and starts conversion (ADC0_SC1A register) using values from memory g_adc16ChannelDataArray[ ]   The data for the DMA channel 1 is prepared in the g_adc16ChannelDataArray prepared in memory and the DMA operates in the following cycle: Step 1 In the beginning, the DMA channel 1 transfer is started using software trigger. This configures the channel and starts the conversion. Step 2 After the conversion is complete, the result is read by DMA channel 0 and stored to results array. Channel linking executes the Channel 1 transfer and the cycle continues.  After all needed channels are measured (DMA byte counter reaches 0), the DMA Interrupt is invoked so the user code is notified. See the following figure describing the process:           Driver Configuration 1. ADC Init (ADC16_configuration) Resolution is 16bit Single step conversion Software triggered Enable DMA on COCO=1(conversion complete) Code: static void ADC16_Configuration(void) { // adc16_config_t adcUserConfig; ADC16_GetDefaultConfig(&adcUserConfig); adcUserConfig.resolution = kADC16_Resolution16Bit; adcUserConfig.enableContinuousConversion = false; adcUserConfig.clockSource = kADC16_ClockSourceAlt0; adcUserConfig.enableAsynchronousClock = false; adcUserConfig.clockDivider = kADC16_ClockDivider2; adcUserConfig.longSampleMode = kADC16_LongSampleCycle24; adcUserConfig.enableLowPower = false; #if ((defined BOARD_ADC_USE_ALT_VREF) && BOARD_ADC_USE_ALT_VREF) adcUserConfig.referenceVoltageSource = kADC16_ReferenceVoltageSourceValt; #endif ADC16_Init(DEMO_ADC16_BASEADDR, &adcUserConfig); ADC16_SetHardwareAverage(DEMO_ADC16_BASEADDR,kADC16_HardwareAverageCount4); /* Configure SIM for ADC hw trigger source selection */ // SIM->SOPT7 |= 0x8EU; #if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION /* Auto calibration */ if (kStatus_Success == ADC16_DoAutoCalibration(DEMO_ADC16_BASEADDR)) { PRINTF("ADC16_DoAutoCalibration() Done.\r\n"); } else { PRINTF("ADC16_DoAutoCalibration() Failed.\r\n"); } #endif /* Enable software trigger. */ ADC16_EnableHardwareTrigger(DEMO_ADC16_BASEADDR, false); /* Enable DMA. */ ADC16_EnableDMA(DEMO_ADC16_BASEADDR, true); } 2. DMA Channel0(DMA_config_ch_0()) 32-bit results are transferred from ADC0_RA register (see proprerty Data source / Address). Transfer mode is Cycle-steal, which means that only one transaction is done per each external request. Channel linking is set to trigger channel 1 after each transfer DMA mux settings for the Channel 0 are enabled and ADC0_DMA_Request is selected, which is the signal from ADC when the conversion ends. External request (request from ADC) is Enabled to start the transfer. Byte count will also be changed before every sequence Auto Increment of destination address after each transfer to point to next index in adc result array (PeripheraltoMemory) 3. DMA Channel1(DMA_config_ch_1()) DMA channel 1 selects the ADC channel and starts conversion (ADC0_SC1A register) using values from memory array g_adc16ChannelDataArray[n]. 8 bits of data is transferred at once. Auto Increment of source address takes place to point towards next index in array. No channel is linked after the transfer ends. No external channel request is selected, this channel transfer is triggered by linking from CH0.  Code: void get_DMA_Channel_link(dma_channel_link_config_t *config) { config->linkType = 2; config->channel1 = 1; } static void DMA_config_ch_0() { DMA_CreateHandle(&g_DMA_Handle, DEMO_DMA_BASEADDR, DEMO_DMA_CHANNEL); DMA_SetCallback(&g_DMA_Handle, DMA_Callback, NULL); DMA_PrepareTransfer(&g_transferConfig, (void *)ADC16_RESULT_REG_ADDR, sizeof(uint32_t), &g_adc16SampleDataArray[0], sizeof(uint32_t), 20, kDMA_PeripheralToMemory); DMA_SubmitTransfer(&g_DMA_Handle, &g_transferConfig, kDMA_EnableInterrupt); get_DMA_Channel_link(&channel_link); DMA_SetChannelLinkConfig(g_DMA_Handle.base,0,&channel_link); } static void DMA_config_ch_1() { DMA_CreateHandle(&g_DMA_Handle_channel_1, DEMO_DMA_BASEADDR, 1); // DMA_SetCallback(&g_DMA_Handle_channel_1, DMA_Callback_channel_1, NULL); DMA_PrepareTransfer(&g_transferConfig_channel_1,&g_adc16ChannelDataArray[0], sizeof(uint8_t), (void *)CHANNEL_ADDRESS, sizeof(uint8_t), 5, kDMA_MemoryToPeripheral); DMA_SubmitTransfer(&g_DMA_Handle_channel_1, &g_transferConfig_channel_1, kDMA_NoOptions); DMA_TriggerChannelStart(g_DMA_Handle_channel_1.base,1); } 4. Running the Demo Import the attached project into MCUXpresso v11.2, SDK v2.8.0 K32L2B Build the project Connect FRDM K32L2B board with PC Debug and Run the application Watch ADC result in g_adc16SampleDataArray[n] in Global variables window for the channels SC1A  data given in g_adc16ChannelDataArray[n] respectively  Attached is the Project for reference. Do let me know if any other information required. Thanks!!