• Tidak ada hasil yang ditemukan

Amril, (2010), “Pendeteksi Kadar Gas Buang (CO) Kendaraan Bermotor Roda

Dua Menggunakan Sensor Gas,” Poli Rekayasa, Jurusan Teknik Elektro Politeknik Negeri Padang Kampus Unand Limau Manis Padang, Vol. 6, No. 1, hal. 9-18.

Armen, B., (2008), Phase Sensitive Detection : Lock-In Amplifier, Laboratory Manual, Department of Physics and Astronomi, The University of Tennesse, Tennesse.

Bahri, A., (2013), “Simulasi Karakteristik Inverter IC 555,”ISSN, Universitas Islam Lamongan, No. 2085-0859.

Bengtsson, L. E., (2012), “A Microcontroller-Based Lock-In Amplifier For

Sub-Milliohm Resistant Measurement,” Riview of Scientific Instrument, University of Gothenburg, Sweden, Vol. 83, hal. 1-8.

Bochenkov, V. E. dan Sergeev, G. B., (2010), Sensitivity, Selectivity, and Stability of Gas-Sensitive Metal-Oxide Nanostructure, Lecture handout : Metal Oxide Gas Sensor, Laboratory of Low Temperature Chemistry, M. V. Lomonosov Moscow State University, Rusia.

Dening, D. C., (1976), “Simulation of Digital Lock-In Amplifier,” Journal of Magnetic Resonance, Virginia Polytechnic Institute and State University, Virginia, Virginia, Vol. 23, hal. 461-463.

Farrar, H. D. dan Hiorns, R. E., (1993), “Development of A Digital Amplifier,”

Proccedings of Audio DSP - Circuits and Systems, IEE Coilloq uium on, Savoy Place, London, hal. 1-5.

Fessler, J., (2004), Digital Signal Processing, Lecture handout : Designe of Digital Filter, Chapter 8 (Student Version), The University of Michigan, Michigan.

Fine, G. F., Cavanagh, L. M., Afonja, A., dan Binions, R., (2010), “Metal Oxide

Semi-Conductor Gas Sensor in Environmental Monitoring,” Sensors, University College London, London, Vol. 10, hal. 5469-5502.

Gaspar, J., Chen, S. F., Gordillo, A., Hepp, M., Ferreyra, P., dan Marquez, C.,

(2003), “Digital Lock-In Amplifier : Study, Designe, and Development

With A Digital Signal Processor,” Microprocessor and Microsystems, Universidad Nacional de Cordoba, Cordoba, Argentina, Vol. 28, hal. 157-162.

Gooch dan Housego, (1996), The Benefits of DSP Lock-In Amplifiers, Lecture handout : Lock- in Amplifier Principles, Rev. 9-96.

78

Hernandez, P. M. M., Simon, L. C. A., Pascual, M. T. S., dan Lopz, B. C., (2014),

“An Integrated Low-Power Lock-In Amplifier and It’s Application to Gas Detection,”Sensors, Vol. 14, hal.15880–15899.

Hidayat, W. S., (2012), “Kinerja Butterworth Low-Pass Filter pada Teknik Modulasi Digital ASK Terhadap Paket Data yang Dipengaruhi oleh

Derau,” InComTech, Universitas Mercu Buana, Jakarta, Vol. 3, No. 2, hal. 169-184.

Huang, J. dan Wan, Q., (2009), “Gas Sensor Based on Semiconducting Metal Oxide One-Dimensional Nanostructures,” Sensors, Hunan University, China, Vol. 9, hal. 9903-9924.

Kanan, S. M., Kadri, O. M. E., Yousef, I. A. A., dan Kanan, M. C., (2009),

“Semiconducting Metal Oxide Based Sensors for Selective Gas Pollutant

Detection,” Sensors, American University of Sharjah, Sharjah, UAE, Vol. 9, hal. 8158-8196.

Lacopini, E., Smith, B., Stfanini, G., dan Carusotto, S., (1983) “Digital

Techniques Applied to Phase-Sensitive Detection,” J. Phys. E : Sci. Instrum., Great Britain, Vol. 16, hal. 844-847.

Li, G., Zhou, M., Li, X., dan Lin, L., (2013), “Digital Lock-In Algoritm and Parameter Setting In Multi-Channel Sensor Signal Detection,”

Measurement, Hebei University of Technology, Hanjin, China, Vol. 46, hal. 2519-2524.

Marcellis, D., Giasante, A. D., Ferri, G., Natale, C. D., Martinelli, E., dan Amico, A. D., (2010), “Analog Automatic Lock-In Amplifier for Very Low Gas

Concentration Detection,” Procedia Engineering, Linz, Austria, Vol. 5, hal. 200-203.

Marki, F. dan Marki, C., (2010), Mixer Basic Primer : A Tutorial for RF and Microwave Mixers, Microwave Inc, Morgan Hill, California, hal. 1-12. Masciotti, J. M., Lasker, J, M., dan Hielscher, A, H., (2008), “Digital Lock-In

Detection for Discriminating Multiple Modulation Frequencies With High Accuracy and Computational Efficiency,” IEEE Transactions On Instrumentation and Measurement, Vol. 57, No. 1, hal. 182-189.

Moos, R., Sahner, K., Fleischer, M., Guth, U., Barsan, N., dan Weimar, U.,

(2009), “Solid State Gas Sensor Research in Germain,”Sensors, Vol. 9, hal. 4323-4365.

Niknejad, A. M., (2005), Introduction to Mixers, Lecture handout 15 : Integrated Circuits for Communication, University of California, Barkeley.

79

Raharjo, W., Haryatno, J., Hidayat, I., (2008), Perancangan dan Realisasi Pengukur Kadar Karbon Monoksida Pada Emisi Kendaraan Bermotor Berbasis Mikrokontroller, Tugas Akhir, Telkom University, Bandung, hal. 1-7.

Roberge,J.K., (1975), "Operational Amplifier : Teory and Practice," Masssacusetts Institute of Technology, Masssacusetts.

Samadikun, S., Rio, S. R., dan Mengko, T., (1989), Sistem Instrumentasi Elektronika, Lecture handout : Pusat Antar Universitas Bidang Elektronika, ITB, Bandung.

Santoso, T. B. dan Huda, M., (2008), Pemfilteran Sinyal Suara, Petunjuk Praktikum 4, Politeknik Elektronika Negeri Surabaya, Surabaya.

Savitri, B., Irianti, A., dan Nur’ainingsih, D., (2009), “Perancangan Low Pass

Filter Digital Dengan FPGA,” Seminar Nasional V, Universitas Teknologi Yogyakarta, Yogyakarta, hal. 15-22.

Schafer dan Buck, (2006), Discrete-Time Signal Processing, Lecture handout : DT Filter Designe : IIR Filters, Massachusetts Institute of Technology, Massachusetts.

Schilcher, T., (2007), Digital Signal Processing in RF Application, Lecture handout : Digital Signal Processing, Paul Scherrer Institute, Villigen, Swiss.

Scholten, R., (2011), Lock-In Amplifier, Lecture handout : Electronics Research Laboratory, University of Helsinki, Finland.

Scofield, J. H., (1994), “A Frequency-Domain Description of Lock-In Amplifier,”

American Journal of Physics, Department of Physics, Oberlin College, Oberlin, Vol. 62, hal. 129-133.

Sonnaillon, M. O. dan Bonetto, F. J., (2005), “A Low-Cost, High-Performance, Digital Sinyal Processor-Based Lock-In Amplifier Capable measuring Multiple Frequency Sweeps Simultaneously,” Riview of Scientific Instrument, Laboratorio de Cavitation y Biotecnologia, San Carlos de Bariloche, Argentina, Vol. 79, hal. 1-7.

STMicroelectronics., (2014), STM32F4DISCOVERY, ST Products, Jenewa, Swiss.

Stoltenberg, J., Pengra, D., Dyck, R., dan Vilches, O., (2005), The Phase Sensitive (Lock-in) Detector, Lecture handout : Lockin Amplifier, The University of Texas, Texas.

80

Winarsih, I., Agoes, S., dan Wahyudi, R., (2003), “Implementasi Filter Digital IIR

Butterworth Pada DSP Starter Kit TMS320C3x,”JETTri, Vol. 2, No. 2, hal. 9-20.

Wolfson, R., (1991), “The Lock-In Amplifier : A Student Experiment,” American Journal of Physics, Vol. 59, hal. 569-572.

81

LAMPIRAN

 Listing Program #include "stm32f4xx.h" #include "defines.h" #include "tm_stm32f4_dac.h" #include "tm_stm32f4_delay.h" #include "tm_stm32f4_disco.h" #include "tm_stm32f4_usart.h" #include "tm_stm32f4_adc.h" #include "tm_stm32f4_usart_dma.h" #include "string.h" #include <stdio.h> #include "stm32f4xx_dac.h" #include "tm_stm32f4_dac_signal.h" #include <stm32f4xx_gpio.h> #include "stm32f4xx_tim.h" #include <stm32f4xx_rcc.h> #include <misc.h> #include "tm_stm32f4_usart.h" #include <stdlib.h> #include <math.h> #define DAC_DHR12R2_ADDRESS 0x40007414 #define DAC_DHR8R1_ADDRESS 0x40007410 GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; float ref,adc1,mixer,LPFsk,LPFsb;

void INTTIM_Config(void);

void LED_Config(void);

int main(void) {

/* Initialize sistem */

SistemInit();

/* Initialize delay */

TM_DELAY_Init();

/* Initialize onboard leds */

TM_DISCO_LedInit();

/* Initialize USART1, 115200baud, TX: PB6 */

TM_USART_Init(USART1, TM_USART_PinsPack_2, 115200);

/* Initialize ADC1 on channel 0, this is pin PA0 */

TM_ADC_Init(ADC1, ADC_Channel_0);

/* Initialize ADC1 on channel 1, this is pin PA1 */

TM_ADC_Init(ADC1, ADC_Channel_1);

/* Initialize ADC1 on channel 3, this is pin PA3 */

TM_ADC_Init(ADC1, ADC_Channel_3);

/* Initialize DAC channel 1, pin PA4

TM_DAC_Init(TM_DAC1);

/* Initialize DAC2, use TIM5 for signal generation */

TM_DAC_SIGNAL_Init(TM_DAC22, TIM5);

TM_DAC_SIGNAL_SetSignal(TM_DAC22, TM_DAC_SIGNAL_Signal_Square, 1000);

INTTIM_Config();

LED_Config();

82

while (1){ }

}

void INTTIM_Config(void) {

NVIC_InitTypeDef NVIC_InitStructure;

/* Enable the TIM2 gloabal Interrupt */

NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

/* TIM2 clock enable */

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

/* Time base configuration */

TIM_TimeBaseStructure.TIM_Period = 100 - 1; // 1 MHz down to 10 KHz

TIM_TimeBaseStructure.TIM_Prescaler = 84 - 1; // 84 MHz Clock down to 1 MHz (adjust per your clock)

TIM_TimeBaseStructure.TIM_ClockDivision = 0;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

/* TIM IT enable */

TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

/* TIM2 enable counter */

TIM_Cmd(TIM2, ENABLE); }

void LED_Config(void) {

/* GPIOD Periph clock enable */

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

/* Configure PD12, PD13, PD14 and PD15 in keluaran pushpull mode

/*GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13|

GPIO_Pin_14| GPIO_Pin_15;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

GPIO_Init(GPIOD, &GPIO_InitStructure); }

void TIM2_IRQHandler(void) {

if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)

{

TIM_ClearITPendingBit(TIM2, TIM_IT_Update);

ref=(TM_ADC_Read(ADC1, ADC_Channel_0));

adc1=(TM_ADC_Read(ADC1, ADC_Channel_1));

mixer=((adc1*ref)/4096)+100;

LPFsk=((0.0006278*ref) + (0.9994*LPFsb)); // 1hz fs=>10khz

LPFsb=LPFsk;

TM_DAC_SetValue(TM_DAC1, (LPFsk));

}

83

////////////////////SETTING PARAMETER FUNGSI DAC///////////////

void TM_DAC_Init(TM_DAC_Channel_t DACx) {

DAC_InitTypeDef DAC_InitStruct;

uint16_t GPIO_Pin;

/* Select proper GPIO pin */

if (DACx == TM_DAC1) { GPIO_Pin = GPIO_PIN_4; } else { GPIO_Pin = GPIO_PIN_5; }

/* Initialize proper GPIO pin */

TM_GPIO_Init(GPIOA, GPIO_Pin, TM_GPIO_Mode_AN,

TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Fast);

/* Enable DAC clock */

RCC->APB1ENR |= RCC_APB1ENR_DACEN;

/* Set DAC options */

DAC_InitStruct.DAC_Trigger = DAC_Trigger_None;

DAC_InitStruct.DAC_WaveGeneration = DAC_WaveGeneration_None;

DAC_InitStruct.DAC_KeluaranBuffer = DAC_KeluaranBuffer_Enable;

/* Init and enable proper DAC */

if (DACx == TM_DAC1) {

DAC_Init(DAC_Channel_1, &DAC_InitStruct);

/* Enable DAC channel 1 */

DAC->CR |= DAC_CR_EN1;

} else {

DAC_Init(DAC_Channel_2, &DAC_InitStruct);

/* Enable DAC channel 2 */

DAC->CR |= DAC_CR_EN2;

} }

void TM_DAC_SetValue(TM_DAC_Channel_t DACx, uint16_t value) {

/* Check value */

if (value > 4095) {

value = 4095;

}

/* Set 12-bit value, right aligned */

if (DACx == TM_DAC1) { DAC->DHR12R1 = value; } else { DAC->DHR12R2 = value; } }

84

/////////////SETTING PARAMETER FUNGSI DAC SET_SIGNAL//////////////

TM_DAC_SIGNAL_Result_t

TM_DAC_SIGNAL_SetCustomSignal(TM_DAC_SIGNAL_Channel_t DACx,

uint16_t* Signal_Data, uint16_t Signal_Length, double frequency);

uint16_t DAC_SIGNAL_Square[DAC_SIGNAL_SQUARE_LENGTH] = {

0, 4095

};

TIM_TypeDef *DAC_TIM[2];

uint8_t dac_timer_set[2] = {0, 0};

TM_DAC_SIGNAL_Result_t TM_DAC_SIGNAL_Init(TM_DAC_SIGNAL_Channel_t DACx, TIM_TypeDef* TIMx) {

uint16_t GPIO_Pin;

/* Check used timer */

/* Set proper trigger */

if (

TIMx == TIM5 ||

) {

/* Set timer */

DAC_TIM[DACx] = TIMx;

/* Set flag */

dac_timer_set[DACx] = 1;

} else {

/* Timer is not valid */

return TM_DAC_SIGNAL_Result_TimerNotValid;

}

/* Select proper GPIO pin */

if (DACx == TM_DAC1) {///////////////////////////////////////////////////////////////// //////////////////////////////// GPIO_Pin = GPIO_PIN_4; } else { GPIO_Pin = GPIO_PIN_5; }

/* Initialize proper GPIO pin */

TM_GPIO_Init(GPIOA, GPIO_Pin, TM_GPIO_Mode_AN,

TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Fast);

/* Return OK */

return TM_DAC_SIGNAL_Result_Ok; }

TM_DAC_SIGNAL_Result_t

TM_DAC_SIGNAL_SetSignal(TM_DAC_SIGNAL_Channel_t DACx,

TM_DAC_SIGNAL_Signal_t signal_type, double frequency) {

TM_DAC_SIGNAL_Result_t result;

switch (signal_type) {

DAC_SIGNAL_TRIANGLE_LENGTH, frequency);

break;

case TM_DAC_SIGNAL_Signal_Square:

result = TM_DAC_SIGNAL_SetCustomSignal(DACx,

85 break; default: result = TM_DAC_SIGNAL_Result_Error; } /* Return result */ return result; } TM_DAC_SIGNAL_Result_t

TM_DAC_SIGNAL_SetCustomSignal(TM_DAC_SIGNAL_Channel_t DACx,

uint16_t* Signal_Data, uint16_t Signal_Length, double frequency) {

DAC_InitTypeDef DAC_InitStruct;

TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;

DMA_InitTypeDef DMA_InitStruct;

TM_TIMER_PROPERTIES_t Timer_Data;

/* Check if timer is set */

if (!dac_timer_set[DACx]) {

return TM_DAC_SIGNAL_Result_Error;

}

/* Check used timer */

/* Set proper trigger */

if (DAC_TIM[DACx] == TIM5) {

DAC_InitStruct.DAC_Trigger = DAC_Trigger_T5_TRGO;

{

/* Timer is not valid */

return TM_DAC_SIGNAL_Result_TimerNotValid;

}

/* Get timer data */

TM_TIMER_PROPERTIES_GetTimerProperties(DAC_TIM[DACx], &Timer_Data);

/* Get period and prescaler values */

TM_TIMER_PROPERTIES_GenerateDataForWorkingFrequency(&Timer_Data,

frequency * Signal_Length);

/* Check valid frequency */

if (Timer_Data.Frequency == 0) {

return TM_DAC_SIGNAL_Result_Error;

}

/* Enable DAC clock */

RCC->APB1ENR |= RCC_APB1ENR_DACEN;

/* Enable DMA1 clock */

RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;

/* Initialize DAC */

DAC_InitStruct.DAC_WaveGeneration = DAC_WaveGeneration_None;

DAC_InitStruct.DAC_KeluaranBuffer = DAC_KeluaranBuffer_Enable;

/* Disable DMA */

if (DACx == TM_DAC1) {

/* Init DAC channel 1 */

86

} else if (DACx == TM_DAC2) {

/* Init DAC channel 2 */

DAC_Init(DAC_Channel_2, &DAC_InitStruct);

}

/* Enable timer clock */

TM_TIMER_PROPERTIES_EnableClock(DAC_TIM[DACx]);

/* Time base configuration */

TIM_TimeBaseStructInit(&TIM_TimeBaseStruct);

TIM_TimeBaseStruct.TIM_Period = Timer_Data.Period - 1; TIM_TimeBaseStruct.TIM_Prescaler = Timer_Data.Prescaler - 1; TIM_TimeBaseStruct.TIM_ClockDivision = 0;

TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;

/* Initialize timer */

TIM_TimeBaseInit(DAC_TIM[DACx], &TIM_TimeBaseStruct);

/* Enable TIM selection */

TIM_SelectKeluaranTrigger(DAC_TIM[DACx],

TIM_TRGOSource_Update);

/* Set DMA options */

DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)Signal_Data;

DMA_InitStruct.DMA_DIR = DMA_DIR_MemoryToPeripheral;

DMA_InitStruct.DMA_BufferSize = Signal_Length;

DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;

DMA_InitStruct.DMA_PeripheralDataSize =

DMA_PeripheralDataSize_HalfWord;

DMA_InitStruct.DMA_MemoryDataSize =

DMA_MemoryDataSize_HalfWord;

DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;

DMA_InitStruct.DMA_Priority = DMA_Priority_High;

DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;

DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single;

DMA_InitStruct.DMA_PeripheralBurst =

DMA_PeripheralBurst_Single;

switch (DACx) {

case TM_DAC1:

/* Set peripheral location = 12bit right aligned for channel 1 */

DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&DAC->DHR12R1;

/* Disable DMA */

DMA_DeInit(DAC_SIGNAL_DMA_DAC1_STREAM);

/* Set channel used */

DMA_InitStruct.DMA_Channel =

DAC_SIGNAL_DMA_DAC1_CHANNEL;

/* Initialize DMA */

DMA_Init(DAC_SIGNAL_DMA_DAC1_STREAM, &DMA_InitStruct);

87

DMA_Cmd(DAC_SIGNAL_DMA_DAC1_STREAM, ENABLE);

/* Enable DAC Channel 1 */

DAC_Cmd(DAC_Channel_1, ENABLE);

/* Enable DMA for DAC Channel 1 */

DAC_DMACmd(DAC_Channel_1, ENABLE);

break;

case TM_DAC2:

/* Disable DMA */

DMA_DeInit(DAC_SIGNAL_DMA_DAC2_STREAM);

/* Set channel used */

DMA_InitStruct.DMA_Channel =

DAC_SIGNAL_DMA_DAC2_CHANNEL;

/* Set peripheral location = 12bit right aligned for channel 2 */

DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&DAC->DHR12R2;

/* Initialize DMA */

DMA_Init(DAC_SIGNAL_DMA_DAC2_STREAM, &DMA_InitStruct);

/* Enable DMA Stream for DAC Channel 2 */

DMA_Cmd(DAC_SIGNAL_DMA_DAC2_STREAM, ENABLE);

/* Enable DAC Channel 2 */

DAC_Cmd(DAC_Channel_2, ENABLE);

/* Enable DMA for DAC Channel 2 */

DAC_DMACmd(DAC_Channel_2, ENABLE);

break; default: break; } /* Enable timer */

DAC_TIM[DACx]->CR1 |= TIM_CR1_CEN;

/* Return OK */

return TM_DAC_SIGNAL_Result_Ok; }

88

//////////////////SETTING PARAMETER FUNGSI ADC//////////////////

/* Private functions */

void TM_ADC_INT_Channel_0_Init(ADC_TypeDef* ADCx); void TM_ADC_INT_Channel_1_Init(ADC_TypeDef* ADCx);

void TM_ADC_INT_InitPin(GPIO_TypeDef* GPIOx, uint16_t PinX); void TM_ADC_Init(ADC_TypeDef* ADCx, uint8_t channel) {

TM_ADC_Channel_t ch = (TM_ADC_Channel_t) channel;

if (ch == TM_ADC_Channel_0) { TM_ADC_INT_Channel_0_Init(ADCx); } else if (ch == TM_ADC_Channel_1) { TM_ADC_INT_Channel_1_Init(ADCx); } else if (ch == TM_ADC_Channel_2) { } /* Init ADC */ TM_ADC_InitADC(ADCx); }

void TM_ADC_InitADC(ADC_TypeDef* ADCx) {

ADC_InitTypeDef ADC_InitStruct;

ADC_CommonInitTypeDef ADC_CommonInitStruct;

/* Init ADC settings */

ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;

ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;

ADC_InitStruct.ADC_ExternalTrigConv = DISABLE;

ADC_InitStruct.ADC_ExternalTrigConvEdge =

ADC_ExternalTrigConvEdge_None;

ADC_InitStruct.ADC_NbrOfConversion = 1;

ADC_InitStruct.ADC_ScanConvMode = DISABLE;

/* Enable clock and fill resolution settings */

if (ADCx == ADC1) {

/* Enable ADC clock */

RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;

/* Set resolution */

ADC_InitStruct.ADC_Resolution = TM_ADC1_RESOLUTION;

}

/* Set common ADC settings */

ADC_CommonInitStruct.ADC_DMAAccessMode =

ADC_DMAAccessMode_Disabled;

ADC_CommonInitStruct.ADC_Mode = ADC_Mode_Independent;

ADC_CommonInitStruct.ADC_Prescaler = ADC_Prescaler_Div4;

ADC_CommonInitStruct.ADC_TwoSamplingDelay =

ADC_TwoSamplingDelay_8Cycles;

ADC_CommonInit(&ADC_CommonInitStruct);

/* Initialize ADC */

ADC_Init(ADCx, &ADC_InitStruct);

/* Enable ADC */

ADCx->CR2 |= ADC_CR2_ADON; }

89

uint16_t TM_ADC_Read(ADC_TypeDef* ADCx, uint8_t channel) {

uint32_t timeout = 0xFFF;

ADC_RegularChannelConfig(ADCx, channel, 1,

ADC_SampleTime_15Cycles);

/* Start software conversion */

ADCx->CR2 |= (uint32_t)ADC_CR2_SWSTART;

/* Wait till done */

while (!(ADCx->SR & ADC_SR_EOC)) {

if (timeout-- == 0x00) { return 0; } } /* Return result */ return ADCx->DR; } /* Private functions */

void TM_ADC_INT_Channel_0_Init(ADC_TypeDef* ADCx) {

TM_ADC_INT_InitPin(GPIOA, GPIO_PIN_0); }

void TM_ADC_INT_Channel_1_Init(ADC_TypeDef* ADCx) {

TM_ADC_INT_InitPin(GPIOA, GPIO_PIN_1); }

void TM_ADC_INT_InitPin(GPIO_TypeDef* GPIOx, uint16_t PinX) {

/* Enable GPIO */

TM_GPIO_Init(GPIOx, PinX, TM_GPIO_Mode_AN, TM_GPIO_OType_PP,

TM_GPIO_PuPd_DOWN, TM_GPIO_Speed_Medium); }

90

//////////////////SETTING PARAMETER FUNGSI TIMER//////////////////

TM_TIMER_PROPERTIES_Result_t

TM_TIMER_PROPERTIES_GetTimerProperties(TIM_TypeDef* TIMx,

TM_TIMER_PROPERTIES_t* Timer_Data) {

RCC_ClocksTypeDef RCC_ClocksStruct;

/* Get clocks */

RCC_GetClocksFreq(&RCC_ClocksStruct);

/* All timers have 16-bit prescaler */

Timer_Data->MaxPrescaler = 0xFFFF;

if (0 /* 32bit timers with PCLK2 max frequency */

#ifdef TIM2

|| TIMx == TIM2

#endif

) {

Timer_Data->TimerFrequency =

RCC_ClocksStruct.PCLK2_Frequency; /* Clock */

Timer_Data->MaxPeriod = 0xFFFFFFFF;

/* Max period */

/* Timer valid */

return TM_TIMER_PROPERTIES_Result_Ok;

} else if (0 /* 16bit timers with HCLK clock frequency */

) {

Timer_Data->TimerFrequency =

RCC_ClocksStruct.HCLK_Frequency; /* Clock */

Timer_Data->MaxPeriod = 0xFFFF;

/* Max period */

/* Timer valid */

return TM_TIMER_PROPERTIES_Result_Ok;

} else if (0 /* 16bit timers with PCLK2 clock frequency */

) {

Timer_Data->TimerFrequency =

RCC_ClocksStruct.PCLK2_Frequency; /* Clock */

Timer_Data->MaxPeriod = 0xFFFF; /* Max period */ /* Timer valid */ return TM_TIMER_PROPERTIES_Result_Ok; }

/* Timer is not valid */

return TM_TIMER_PROPERTIES_Result_TimerNotValid; }

TM_TIMER_PROPERTIES_Result_t

TM_TIMER_PROPERTIES_GenerateDataForWorkingFrequency(TM_TIMER_PROPE RTIES_t* Timer_Data, double frequency) {

if (frequency > Timer_Data->TimerFrequency) {

/* Reset values */

Timer_Data->Prescaler = 0;

Timer_Data->Period = 0;

91

/* Frequency too high */

return TM_TIMER_PROPERTIES_Result_FrequencyTooHigh; } else if (frequency == 0) { /* Reset values */ Timer_Data->Prescaler = 0; Timer_Data->Period = 0; Timer_Data->Frequency = 0;

/* Not valid frequency */

return TM_TIMER_PROPERTIES_Result_FrequencyTooLow;

}

/* Fix for 16/32bit timers */

if (Timer_Data->MaxPeriod <= 0xFFFF) {

Timer_Data->MaxPeriod++;

}

/* Get minimum prescaler and maximum resolution for timer */

Timer_Data->Prescaler = 0;

do {

/* Get clock */

Timer_Data->Period = (Timer_Data->TimerFrequency / (Timer_Data->Prescaler + 1));

/* Get period */

Timer_Data->Period = (Timer_Data->Period / frequency);

/* Increase prescaler value */

Timer_Data->Prescaler++;

} while (Timer_Data->Period > (Timer_Data->MaxPeriod) &&

Timer_Data->Prescaler <= (Timer_Data->MaxPrescaler + 1));

/* Check for too low frequency */

if (Timer_Data->Prescaler > (Timer_Data->MaxPrescaler + 1)) {

/* Reset values */

Timer_Data->Prescaler = 0;

Timer_Data->Period = 0;

Timer_Data->Frequency = 0;

/* Prescaler too high, frequency is too low for use */

return TM_TIMER_PROPERTIES_Result_FrequencyTooLow;

}

/* Set frequency */

Timer_Data->Frequency = frequency;

/* Return OK */

return TM_TIMER_PROPERTIES_Result_Ok; }

TM_TIMER_PROPERTIES_Result_t

TM_TIMER_PROPERTIES_EnableClock(TIM_TypeDef* TIMx) { #ifdef TIM2 if (TIMx == TIM2) { RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; } #endif /* Return OK */ return TM_TIMER_PROPERTIES_Result_Ok; }

92

////////////SETTING FUNGSI PUSH BUTTON BOARD STM32F4/////////////

/* Button pressed status for onpressed/onreleased events */

static volatile uint8_t TM_INT_DISCO_ButtonPressed = 0; void TM_DISCO_LedInit(void) {

/* Set pins as keluaran */

TM_GPIO_Init(TM_DISCO_LED_PORT, LED_ALL, TM_GPIO_Mode_OUT,

TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High);

/* Turn leds off */

TM_DISCO_LedOff(LED_ALL); }

void TM_DISCO_ButtonInit(void) {

/* Set pin as masukan */

TM_GPIO_Init(TM_DISCO_BUTTON_PORT, TM_DISCO_BUTTON_PIN,

TM_GPIO_Mode_IN, TM_GPIO_OType_PP, TM_DISCO_BUTTON_PULL,

TM_GPIO_Speed_Low); }

uint8_t TM_DISCO_ButtonOnPressed(void) {

/* If button is now pressed, but was not already pressed */

if (TM_DISCO_ButtonPressed()) {

if (!TM_INT_DISCO_ButtonPressed) {

/* Set flag */

TM_INT_DISCO_ButtonPressed = 1;

/* Return button onpressed */

return 1; } } else { /* Clear flag */ TM_INT_DISCO_ButtonPressed = 0; }

/* Button is not pressed or it was already pressed before */

return 0; }

uint8_t TM_DISCO_ButtonOnReleased(void) {

/* If button is now released, but was not already released */

if (!TM_DISCO_ButtonPressed()) {

if (TM_INT_DISCO_ButtonPressed) {

/* Set flag */

TM_INT_DISCO_ButtonPressed = 0;

/* Return button onreleased */

return 1; } } else { /* Set flag */ TM_INT_DISCO_ButtonPressed = 1; }

/* Button is not released or it was already released before */

return 0; }

93

Dokumen terkait