#include "adc.h" #include "common.h" #include "FreeRTOS.h" #include "task.h" #include "semphr.h" #ifdef PRINTF_STDLIB #include #endif #ifdef PRINTF_CUSTOM #include "tinystdio.h" #endif SemaphoreHandle_t adc_raw_data_semphr; // here raw values will be put by DMA static volatile uint16_t adc_raw[ADC_TOTAL_COUNT] = {0}; // Сырые данные АЦП канала uint16_t adc_mv_raw(adc_chan_t chan) { return adc_raw[chan]; } // Данные АЦП канала в мВ uint16_t adc_mv(adc_chan_t chan) { return (((uint32_t)adc_raw[chan]) * VREF) >> 12; } // void adc_init(void) { adc_raw_data_semphr = xSemaphoreCreateBinary(); adc_gpio_init(); adc_dma_init(); adc_init_base(); adc_timer_init(); adc_tim_set(TRUE); } // void adc_init_base(void) { adc_base_config_type adc_base_struct; crm_periph_clock_enable(CRM_ADC1_PERIPH_CLOCK, TRUE); crm_adc_clock_div_set(CRM_ADC_DIV_2); nvic_priority_group_config(NVIC_PRIORITY_GROUP_4); nvic_irq_enable(ADC1_2_IRQn, 5, 0); //NVIC_SetPriority(ADC1_2_IRQn, 5); // select combine mode adc_combine_mode_select(ADC_INDEPENDENT_MODE); adc_base_default_para_init(&adc_base_struct); adc_base_struct.sequence_mode = TRUE; adc_base_struct.repeat_mode = FALSE; adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT; adc_base_struct.ordinary_channel_length = 3; adc_base_config(ADC1, &adc_base_struct); adc_ordinary_channel_set(ADC1, ADC_CHANNEL_9, 1, ADC_SAMPLETIME_239_5); adc_ordinary_channel_set(ADC1, ADC_CHANNEL_10, 2, ADC_SAMPLETIME_239_5); adc_ordinary_channel_set(ADC1, ADC_CHANNEL_16, 3, ADC_SAMPLETIME_239_5); adc_ordinary_conversion_trigger_set(ADC1, ADC12_ORDINARY_TRIG_SOFTWARE, TRUE); adc_dma_mode_enable(ADC1, TRUE); adc_tempersensor_vintrv_enable(TRUE); adc_flag_clear(ADC1, ADC_CCE_FLAG); adc_interrupt_enable(ADC1, ADC_CCE_INT, TRUE); adc_enable(ADC1, TRUE); adc_calibration_init(ADC1); while(adc_calibration_init_status_get(ADC1)); adc_calibration_start(ADC1); while(adc_calibration_status_get(ADC1)); } // void adc_gpio_init(void) { gpio_init_type gpio_initstructure; crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE); crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE); crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE); crm_periph_clock_enable(CRM_GPIOD_PERIPH_CLOCK, TRUE); gpio_default_para_init(&gpio_initstructure); // Vbat gpio_initstructure.gpio_mode = GPIO_MODE_ANALOG; gpio_initstructure.gpio_pins = GPIO_PINS_1; gpio_init(GPIOB, &gpio_initstructure); // check 220 gpio_initstructure.gpio_pins = GPIO_PINS_0; gpio_init(GPIOC, &gpio_initstructure); gpio_initstructure.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; gpio_initstructure.gpio_pull = GPIO_PULL_NONE; gpio_initstructure.gpio_mode = GPIO_MODE_OUTPUT; gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; gpio_initstructure.gpio_pins = GPIO_PINS_11; gpio_init(GPIOD, &gpio_initstructure); // Установка пина подключает измерительную цепь. Цепь подключена всегда. gpio_bits_set(GPIOD, GPIO_PINS_11); } // void adc_timer_init(void) { crm_clocks_freq_type crm_clocks_freq_struct = {0}; crm_periph_clock_enable(CRM_TMR7_PERIPH_CLOCK, TRUE); crm_clocks_freq_get(&crm_clocks_freq_struct); tmr_base_init(TMR7, 999, (crm_clocks_freq_struct.ahb_freq / 10000) - 1); tmr_cnt_dir_set(TMR7, TMR_COUNT_UP); tmr_flag_clear(TMR7, TMR_OVF_FLAG); nvic_priority_group_config(NVIC_PRIORITY_GROUP_4); nvic_irq_enable(TMR7_GLOBAL_IRQn, 5, 0); tmr_counter_enable(TMR7, FALSE); tmr_interrupt_enable(TMR7, TMR_OVF_INT, TRUE); } // void adc_tim_set(confirm_state state) { //tmr_counter_enable(TMR7, state); //tmr_interrupt_enable(TMR7, TMR_OVF_INT, state); tmr_counter_enable(TMR7, state); } // void adc_dma_init(void) { dma_init_type dma_init_struct; crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE); dma_reset(DMA1_CHANNEL1); dma_default_para_init(&dma_init_struct); dma_init_struct.buffer_size = 3; dma_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY; dma_init_struct.memory_base_addr = (uint32_t)adc_raw; dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_HALFWORD; dma_init_struct.memory_inc_enable = TRUE; dma_init_struct.peripheral_base_addr = (uint32_t)&(ADC1->odt); dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_HALFWORD; dma_init_struct.peripheral_inc_enable = FALSE; dma_init_struct.priority = DMA_PRIORITY_HIGH; dma_init_struct.loop_mode_enable = TRUE; dma_init(DMA1_CHANNEL1, &dma_init_struct); dma_flexible_config(DMA1, FLEX_CHANNEL1, DMA_FLEXIBLE_ADC1); dma_channel_enable(DMA1_CHANNEL1, TRUE); } // void ADC1_2_IRQHandler(void) { static uint8_t empty = 0; static BaseType_t xHigherPriorityTaskWoken = pdFALSE; adc_flag_clear(ADC1, ADC_CCE_FLAG); if (empty > 3) { xSemaphoreGiveFromISR(adc_raw_data_semphr, &xHigherPriorityTaskWoken); } else empty++; #if 0 Ubat = ADC_UBAT_FACTOR*(float)adc1_ordinary_valuetab[0]*ADC_VREF/4096.0; check_220 = ((float)adc1_ordinary_valuetab[1]*ADC_VREF/4096.0)/CONST_RESISTOR_DEVIDER; temperature = (ADC_TEMP_BASE - (float)adc1_ordinary_valuetab[2]*ADC_VREF/4096.0)/ADC_TEMP_SLOPE + 25.0; printf("Ubat: %f ", Ubat); printf("check 220V: %f ", check_220); printf("temper: %.2f ", temperature); #endif #if 0 printf("Ubat: %u \r\n", adc_raw[0]); printf("check 220V: %u \r\n", adc_raw[1]); printf("temper: %.2u \r\n\n", adc_raw[2]); #endif } // void TMR7_GLOBAL_IRQHandler(void) { if(tmr_flag_get(TMR7, TMR_OVF_FLAG) != RESET) { tmr_flag_clear(TMR7, TMR_OVF_FLAG); adc_ordinary_software_trigger_enable(ADC1, TRUE); } }