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.
Dependencies: mbed
Fork of TAU_ZOOLOG_Chirp_Generator by
Diff: main.cpp
- Revision:
- 0:e239fd599412
- Child:
- 1:0b510109a099
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sun Dec 06 19:39:37 2015 +0000 @@ -0,0 +1,273 @@ +/* +Digital Filter Implementation: arkadiraf@gmail.com 21/10/2015 +ADC --> Filter --> DAC , Based on NUCLEO - F303RE + +Pinout: +ADC -- PA_0 -- A0 +DAC -- PA_4 -- A2 + +I/O -- PA_5 -- D13 (Status LED, Condition) +I/O -- PA_6 -- D12 (Toggle Pin, Loop Freq) +I/O -- PA_7 -- D11 (General Output Pin ) + +Loop Running at up to 1 MHz, depending on filter lenght. +250 proccessor operations at 250 kHz +Make sure to use float variables in filter (Not double!). +*/ +#include "mbed.h" +// mbed variables, Settings +AnalogOut my_output(PA_4); +AnalogIn my_input(PA_0); +DigitalOut myled(PA_5); +DigitalOut mytoggle(PA_6); +DigitalOut mytrigger(PA_7); + +// Low level declerations +ADC_HandleTypeDef hadc1; +DAC_HandleTypeDef hdac1; + +// initialize low level dac, adc +static void MX_ADC1_Init(void); +static void MX_DAC1_Init(void); + +// declare filter +inline float FilterFloat(float Variable); +// declare output filter +inline float OutputFilterFloat(float Variable); +//nadav - declare simple filter +inline float simpleFilterFloat(float Variable); + +// Variables +uint16_t ADCValue=0; +float ADCFloat=0; +float OutputADCFloat=0; +//amplitude scale is normalized such that 1 equals 3.3V, -1 equals 0V, and 0 equals 3.3/2V +float ADC2Float=(2.0f/4095.0f); //ADCvalue*(2/0xFFF)-1.0f // 12 bits range +float Float2ADC=(4095.0f/2.0f); //(ADCvalue+1.0f)*(0xFFF/2) // 12 bits range + + +bool PinD11_state=0; +bool PinD12_state=0; +bool PinD13_state=0; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//// Define Your Variables ////////////////////////////////////////////// Define Your Variables //// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +float example=0.0f; // example + +//nadav - Simple First order filter +//get this from matlab script "simple_SimpleFilterExample.m" +//float ALPF=0.152641; +//float AHPF=0.999815; +//float AHPF=0.999815; //10Hz cut off fs=340 +//float AHPF=0.574978; //40KHz cut off fs=340 +//float AHPF=0.782963; //15KHz cut off fs=340 +//float AHPF=0.844025; //10KHz cut off fs=340 +//float AHPF=0.871202; //8KHz cut off fs=340 +//float AHPF=0.915416; //5KHz cut off fs=340 +//float AHPF=0.900187; //6KHz cut off fs=340 +//float AHPF=0.885458; //7KHz cut off fs=340 +//float AHPF=0.931168; //8KHz cut off fs=340*2 +float AHPF=0.999128; //100Hz cut off fs=340*2 +float LastY=0; +float CurY=0; +float LastU=0; +float CurU=0; + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//// Define Your Variables ////////////////////////////////////////////// Define Your Variables //// +//////////////////////////////////////////////////////////////////////////////////////////////////// + + + + +// Main code +int main() +{ + // System Clock Configuration (Peripherial clocks) + RCC_PeriphCLKInitTypeDef PeriphClkInit; + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC12; + PeriphClkInit.Adc12ClockSelection = RCC_ADC12PLLCLK_DIV1; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit); + + MX_ADC1_Init(); + MX_DAC1_Init(); + + HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, 0x000); + HAL_DAC_Start(&hdac1, DAC_CHANNEL_1); + + HAL_ADC_Start(&hadc1); + + // more direct method to setting DAC value`s + //define Dac Register. + __IO uint32_t Dac_Reg = 0; + Dac_Reg = (uint32_t) (hdac1.Instance); + Dac_Reg += __HAL_DHR12R1_ALIGNEMENT(DAC_ALIGN_12B_R); + + /* Set the DAC channel1 selected data holding register */ + *(__IO uint32_t *) Dac_Reg = ADCValue; + + // more direct method to reading ADC value's: + /* Clear regular group conversion flag */ + + //__HAL_ADC_CLEAR_FLAG(&hadc1, (ADC_FLAG_EOC | ADC_FLAG_EOS) ); + + /* Return ADC converted value */ + //ADCValue=(uint16_t)(hadc1.Instance->DR); + + // Infinite loop + + // ADC to float convertion and back. + + while(1) { + // more direct method to reading ADC value's: + /* Return ADC converted value */ + ADCValue=(uint16_t)(hadc1.Instance->DR); + + // read ADC value , Alternative more slow method + //ADCValue=HAL_ADC_GetValue(&hadc1); + + // convert to float for filter + //amplitude scale is normalized such that 1 equals 3.3V -1 euqales 0V, and 0 equales 3.3/2V + ADCFloat=((float)ADCValue * ADC2Float)-1.0f; + + // toggle pin, Loop frequency indicator + PinD12_state=!PinD12_state; + if (PinD12_state) {GPIOA->BSRRL = GPIO_PIN_6;}else{GPIOA->BSRRH = GPIO_PIN_6;} + + //////////////////////////////////////////////////////////////////////////////////////////////////// + //// Change Code from here ////////////////////////////////////////////// Change Code from here //// + //////////////////////////////////////////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////// + // Apply Filter to reading before further processing// + ////////////////////////////////////////////////////// + + ADCFloat=simpleFilterFloat(ADCFloat); //nadav - filtering input + + + //////////////////////////// + // Apply Filter to Output // + //////////////////////////// + + OutputADCFloat=OutputFilterFloat(ADCFloat); + + // Set Condition of Pin D13 (LED2) Status + if (ADCFloat>0.5f){ + GPIOA->BSRRL = GPIO_PIN_5; + }else{ + GPIOA->BSRRH = GPIO_PIN_5; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////// + //// Change Code Up To Here /////////////////////////////////////////// Change Code Up To Here //// + /////////////////////////////////////////////////////////////////////////////////////////////////// + + + // Apply limits to max dac values [0..1] + // Convert filtered data back to uint16_t, + if (OutputADCFloat < -1.0f) { + ADCValue=0; // Min value + } else if (OutputADCFloat > 1.0f) { + ADCValue=0xFFF; // Max value + } else { + ADCValue=(uint16_t)((OutputADCFloat+1.0f) * Float2ADC); + } + + // Update Dac value + /* Set the DAC channel1 selected data holding register */ + *(__IO uint32_t *) Dac_Reg = ADCValue; + //HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, ADCValue); //Alternative more slow method + + } +} +/////////////////////////////////////////// +// Filter Function //////////////////////// +/////////////////////////////////////////// +inline void NOP() { __ASM volatile ("nop"); } // one tick operation, Use to adjust frequency by slowing down the proccess +//nadav - simple filter implementation +inline float simpleFilterFloat(float Variable){ + // Buffer variables + LastU=CurU; + CurU=Variable; + LastY=CurY; + + // Simple Filter LFP + //CurY=(1-ALPF)*LastY+ALPF*CurU; + + // Simple Filter HPF + CurY=AHPF*(LastY+CurU-LastU); + + + return CurY; +}// end output filter function + +/////////////////////////////////////////// +// Output Filter Function ///////////////// +/////////////////////////////////////////// +inline float OutputFilterFloat(float Variable){ + Variable*=1.0f; // Example of Math operation, Make sure to use float operations and not Double. + return Variable; +}// end output filter function + + + + +//////////////////////// +// Settings functions // +//////////////////////// +/* ADC1 init function */ +void MX_ADC1_Init(void) +{ + + ADC_ChannelConfTypeDef sConfig; + + /**Common config + */ + hadc1.Instance = ADC1; + hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC; + hadc1.Init.Resolution = ADC_RESOLUTION12b; + hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; + hadc1.Init.ContinuousConvMode = ENABLE; + hadc1.Init.DiscontinuousConvMode = DISABLE; + hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; + hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; + hadc1.Init.NbrOfConversion = 1; + hadc1.Init.DMAContinuousRequests = DISABLE; + hadc1.Init.EOCSelection = EOC_SINGLE_CONV; + hadc1.Init.LowPowerAutoWait = DISABLE; + hadc1.Init.Overrun = OVR_DATA_OVERWRITTEN; + HAL_ADC_Init(&hadc1); + + /**Configure Regular Channel + */ + sConfig.Channel = ADC_CHANNEL_1; + sConfig.Rank = 1; + sConfig.SingleDiff = ADC_DIFFERENTIAL_ENDED ;//ADC_DIFFERENTIAL_ENDED; //ADC_SINGLE_ENDED + sConfig.SamplingTime = ADC_SAMPLETIME_19CYCLES_5; //ADC_SAMPLETIME_1CYCLE_5; + sConfig.OffsetNumber = ADC_OFFSET_NONE; + sConfig.Offset = 0; + HAL_ADC_ConfigChannel(&hadc1, &sConfig); + +} + +/* DAC1 init function */ +void MX_DAC1_Init(void) +{ + + DAC_ChannelConfTypeDef sConfig; + + /**DAC Initialization + */ + hdac1.Instance = DAC1; + HAL_DAC_Init(&hdac1); + + /**DAC channel OUT1 config + */ + sConfig.DAC_Trigger = DAC_TRIGGER_NONE; + sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE; + HAL_DAC_ConfigChannel(&hdac1, &sConfig, DAC_CHANNEL_1); + +} \ No newline at end of file