Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "mik32_hal.h"
- #include "mik32_hal_irq.h"
- #include "mik32_hal_adc.h"
- #include "mik32_hal_timer32.h"
- #include "mik32_hal_dma.h"
- /* Пример работы запуска преобразований ADC по таймеру, полученные данные по DMA
- * складываются в текущий буфер, при заполнении текущего буфера в прерывании от DMA
- * переключаемся на свободный буфер и DMA начинает складывать новые данные в него,
- * а в это время программа может обработать заполненный буфер.
- */
- ADC_HandleTypeDef hadc;
- TIMER32_HandleTypeDef htimer32_1;
- DMA_InitTypeDef hdma;
- DMA_ChannelHandleTypeDef hdma_ch0;
- void SystemClock_Config(void);
- void GPIO_Init();
- static void ADC_Init(void);
- static void Timer32_1_Init(void);
- static void DMA_Init(void);
- static void DMA_CH0_Init(DMA_InitTypeDef *hdma);
- #define BUFF_SIZE 32 // размер должен быть степенью двойки
- volatile uint16_t adc_value = 0;
- volatile uint8_t flag_dma = 0, CurBuf = 0, buf_ready = 0, buff_fill = 0;
- volatile uint16_t buff[2][BUFF_SIZE];
- int main()
- {
- HAL_Init();
- SystemClock_Config();
- GPIO_Init();
- DMA_Init();
- Timer32_1_Init();
- ADC_Init();
- HAL_EPIC_MaskLevelSet(HAL_EPIC_TIMER32_1_MASK);
- HAL_IRQ_EnableInterrupts();
- /* Запуск таймера и прерываний в продолжительном режиме */
- HAL_Timer32_Start_IT(&htimer32_1, TIMER32_INT_OVERFLOW_M);
- ANALOG_REG->ADC_SINGLE = 1;
- HAL_DMA_Start(&hdma_ch0, (void *)&ANALOG_REG->ADC_VALUE, (void *)buff[CurBuf], sizeof(buff[0])- 1);
- while (1)
- {
- if(flag_dma){
- flag_dma = 0;
- HAL_DMA_Start(&hdma_ch0, (void *)&ANALOG_REG->ADC_VALUE, (void *)buff[CurBuf], sizeof(buff[0])- 1);
- buf_ready = 1;
- }
- if(buf_ready){
- buf_ready = 0;
- // тут можно обрабатывать заполненный буфер buff[buff_fill], пока текущий buff[CurBuf] наполняется данными
- HAL_GPIO_TogglePin(GPIO_0, GPIO_PIN_9);
- }
- }
- }
- void SystemClock_Config(void)
- {
- PCC_InitTypeDef PCC_OscInit = {0};
- PCC_OscInit.OscillatorEnable = PCC_OSCILLATORTYPE_ALL;
- PCC_OscInit.FreqMon.OscillatorSystem = PCC_OSCILLATORTYPE_OSC32M;
- PCC_OscInit.FreqMon.ForceOscSys = PCC_FORCE_OSC_SYS_UNFIXED;
- PCC_OscInit.FreqMon.Force32KClk = PCC_FREQ_MONITOR_SOURCE_OSC32K;
- PCC_OscInit.AHBDivider = 0;
- PCC_OscInit.APBMDivider = 0;
- PCC_OscInit.APBPDivider = 0;
- PCC_OscInit.HSI32MCalibrationValue = 128;
- PCC_OscInit.LSI32KCalibrationValue = 8;
- PCC_OscInit.RTCClockSelection = PCC_RTC_CLOCK_SOURCE_AUTO;
- PCC_OscInit.RTCClockCPUSelection = PCC_CPU_RTC_CLOCK_SOURCE_OSC32K;
- HAL_PCC_Config(&PCC_OscInit);
- }
- void GPIO_Init()
- {
- GPIO_InitTypeDef GPIO_InitStruct = {0};
- __HAL_PCC_GPIO_0_CLK_ENABLE();
- __HAL_PCC_GPIO_1_CLK_ENABLE();
- __HAL_PCC_GPIO_2_CLK_ENABLE();
- GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10 ;
- GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_OUTPUT;
- GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
- HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct);
- }
- void __attribute__((section(".ram_text"))) trap_handler(void)
- {
- if(EPIC_CHECK_DMA()){
- HAL_DMA_ClearIrq(&hdma);
- buff_fill = CurBuf;
- CurBuf = 1 - CurBuf;
- flag_dma = 1;
- }
- if (EPIC_CHECK_TIMER32_1())
- {
- uint32_t interrupt_status = TIMER32_1->INT_FLAGS;
- uint32_t interrupt_mask = TIMER32_1->INT_MASK;
- if ((interrupt_status & TIMER32_INT_OVERFLOW_M) & interrupt_mask)
- {
- while (!(ANALOG_REG->ADC_VALID))
- ;
- adc_value = ANALOG_REG->ADC_VALUE;
- ANALOG_REG->ADC_SINGLE = 1;
- GPIO_0->OUTPUT ^= GPIO_PIN_10;
- }
- HAL_TIMER32_INTERRUPTFLAGS_CLEAR(&htimer32_1); /* Сброс всех флагов */
- }
- /* Сброс прерываний */
- //HAL_EPIC_Clear(0xFFFFFFFF);
- }
- static void ADC_Init(void)
- {
- hadc.Instance = ANALOG_REG;
- hadc.Init.Sel = ADC_CHANNEL0;
- hadc.Init.EXTRef = ADC_EXTREF_OFF; /* Выбор источника опорного напряжения: «1» - внешний; «0» - встроенный */
- hadc.Init.EXTClb = ADC_EXTCLB_ADCREF; /* Выбор источника внешнего опорного напряжения: «1» - внешний вывод; «0» - настраиваемый ОИН */
- HAL_ADC_Init(&hadc);
- }
- static void Timer32_1_Init(void)
- {
- htimer32_1.Instance = TIMER32_1;
- htimer32_1.Top = 3200000;
- htimer32_1.Clock.Source = TIMER32_SOURCE_PRESCALER;
- htimer32_1.Clock.Prescaler = 0;
- htimer32_1.InterruptMask = TIMER32_INT_OVERFLOW_M;
- htimer32_1.CountMode = TIMER32_COUNTMODE_FORWARD;
- HAL_Timer32_Init(&htimer32_1);
- }
- static void DMA_Init(void)
- {
- /* Настройки DMA */
- hdma.Instance = DMA_CONFIG;
- hdma.CurrentValue = DMA_CURRENT_VALUE_ENABLE;
- HAL_DMA_Init(&hdma);
- HAL_DMA_GlobalIRQEnable(&hdma, DMA_IRQ_ENABLE);
- /* Инициализация канала */
- DMA_CH0_Init(&hdma);
- HAL_DMA_LocalIRQEnable(&hdma_ch0, DMA_IRQ_ENABLE);
- }
- static void DMA_CH0_Init(DMA_InitTypeDef *hdma)
- {
- hdma_ch0.dma = hdma;
- /* Настройки канала */
- hdma_ch0.ChannelInit.Channel = DMA_CHANNEL_0;
- hdma_ch0.ChannelInit.Priority = DMA_CHANNEL_PRIORITY_VERY_HIGH;
- hdma_ch0.ChannelInit.ReadMode = DMA_CHANNEL_MODE_PERIPHERY;
- hdma_ch0.ChannelInit.ReadInc = DMA_CHANNEL_INC_DISABLE;
- hdma_ch0.ChannelInit.ReadSize = DMA_CHANNEL_SIZE_HALFWORD; /* data_len должно быть кратно read_size */
- hdma_ch0.ChannelInit.ReadBurstSize = 1; /* read_burst_size должно быть кратно read_size */
- hdma_ch0.ChannelInit.ReadRequest = DMA_CHANNEL_TIMER32_1_REQUEST;
- hdma_ch0.ChannelInit.ReadAck = DMA_CHANNEL_ACK_ENABLE;
- hdma_ch0.ChannelInit.WriteMode = DMA_CHANNEL_MODE_MEMORY;
- hdma_ch0.ChannelInit.WriteInc = DMA_CHANNEL_INC_ENABLE;
- hdma_ch0.ChannelInit.WriteSize = DMA_CHANNEL_SIZE_HALFWORD; /* data_len должно быть кратно write_size */
- hdma_ch0.ChannelInit.WriteBurstSize = 1; /* write_burst_size должно быть кратно read_size */
- hdma_ch0.ChannelInit.WriteRequest = DMA_CHANNEL_TIMER32_1_REQUEST;
- hdma_ch0.ChannelInit.WriteAck = DMA_CHANNEL_ACK_ENABLE;
- }
Add Comment
Please, Sign In to add comment