Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-src by
analogin_api.c
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #include "analogin_api.h" 00017 #include "cmsis.h" 00018 #include "pinmap.h" 00019 #include "error.h" 00020 00021 #define ANALOGIN_MEDIAN_FILTER 1 00022 00023 #define ADC_10BIT_RANGE 0x3FF 00024 #define ADC_12BIT_RANGE 0xFFF 00025 00026 static inline int div_round_up(int x, int y) { 00027 return (x + (y - 1)) / y; 00028 } 00029 00030 static const PinMap PinMap_ADC[] = { 00031 {P0_23, ADC0_0, 0x01}, 00032 {P0_24, ADC0_1, 0x01}, 00033 {P0_25, ADC0_2, 0x01}, 00034 {P0_26, ADC0_3, 0x01}, 00035 {P1_30, ADC0_4, 0x03}, 00036 {P1_31, ADC0_5, 0x03}, 00037 {P0_12, ADC0_6, 0x03}, 00038 {P0_13, ADC0_7, 0x03}, 00039 {NC , NC , 0 } 00040 }; 00041 00042 #define ADC_RANGE ADC_12BIT_RANGE 00043 00044 void analogin_init(analogin_t *obj, PinName pin) { 00045 obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC); 00046 if (obj->adc == (uint32_t)NC) { 00047 error("ADC pin mapping failed"); 00048 } 00049 00050 // ensure power is turned on 00051 LPC_SC->PCONP |= (1 << 12); 00052 00053 uint32_t PCLK = PeripheralClock ; 00054 00055 // calculate minimum clock divider 00056 // clkdiv = divider - 1 00057 uint32_t MAX_ADC_CLK = 12400000; 00058 uint32_t clkdiv = div_round_up(PCLK, MAX_ADC_CLK) - 1; 00059 00060 // Set the generic software-controlled ADC settings 00061 LPC_ADC->CR = (0 << 0) // SEL: 0 = no channels selected 00062 | (clkdiv << 8) // CLKDIV: 00063 | (0 << 16) // BURST: 0 = software control 00064 | (1 << 21) // PDN: 1 = operational 00065 | (0 << 24) // START: 0 = no start 00066 | (0 << 27); // EDGE: not applicable 00067 00068 // must enable analog mode (ADMODE = 0) 00069 __IO uint32_t *reg = (__IO uint32_t*) (LPC_IOCON_BASE + 4 * pin); 00070 *reg &= ~(1 << 7); 00071 00072 pinmap_pinout(pin, PinMap_ADC); 00073 } 00074 00075 static inline uint32_t adc_read(analogin_t *obj) { 00076 // Select the appropriate channel and start conversion 00077 LPC_ADC->CR &= ~0xFF; 00078 LPC_ADC->CR |= 1 << (int)obj->adc; 00079 LPC_ADC->CR |= 1 << 24; 00080 00081 // Repeatedly get the sample data until DONE bit 00082 unsigned int data; 00083 do { 00084 data = LPC_ADC->GDR; 00085 } while ((data & ((unsigned int)1 << 31)) == 0); 00086 00087 // Stop conversion 00088 LPC_ADC->CR &= ~(1 << 24); 00089 00090 return (data >> 4) & ADC_RANGE; // 12 bit 00091 } 00092 00093 static inline void order(uint32_t *a, uint32_t *b) { 00094 if (*a > *b) { 00095 uint32_t t = *a; 00096 *a = *b; 00097 *b = t; 00098 } 00099 } 00100 00101 static inline uint32_t adc_read_u32(analogin_t *obj) { 00102 uint32_t value; 00103 #if ANALOGIN_MEDIAN_FILTER 00104 uint32_t v1 = adc_read(obj); 00105 uint32_t v2 = adc_read(obj); 00106 uint32_t v3 = adc_read(obj); 00107 order(&v1, &v2); 00108 order(&v2, &v3); 00109 order(&v1, &v2); 00110 value = v2; 00111 #else 00112 value = adc_read(obj); 00113 #endif 00114 return value; 00115 } 00116 00117 uint16_t analogin_read_u16(analogin_t *obj) { 00118 uint32_t value = adc_read_u32(obj); 00119 00120 return (value << 4) | ((value >> 8) & 0x000F); // 12 bit 00121 } 00122 00123 float analogin_read(analogin_t *obj) { 00124 uint32_t value = adc_read_u32(obj); 00125 return (float)value * (1.0f / (float)ADC_RANGE); 00126 }
Generated on Tue Jul 12 2022 13:47:00 by
1.7.2
