Я настроил на gd32f303zet6 цап на генерацию сигнала. Делаю я это посредством dma из заранее заготовленного буфера. Циклический режим dma для проверки настроил таким образом, чтобы ТОЧНО не вылазить за рамки буфера. Проблема заключается в том, что при достижении конца цикла, dma подсовывает цап нулевое значение. В результате один отсчет между циклами всегда нулевой. Может я не в том порядке настроил? Просто вроде много чего перепробовал и идеи закончились.
Исполняемый код:
#include "gd32f30x.h"
#include "systick.h"
#include "gd32f30x_dac.h"
#include "math.h"
#include "main.h"
#include "stddef.h"
//uint16_t buff_dac[4] = {500, 1000, 2024, 4000};
//uint16_t buff_dac[4] = {4000, 2000, 500, 500};// последний элемент не учитывается
uint16_t buff_dac[600] = {500, 1000, 2000, 1000, 3000};
uint8_t test_flag = 1;
// Функция по генерации синуса
uint32_t gen_sin(float f, uint8_t A)
{
double f_s = 1000000;
double f_sig = 45;
double t = 0;
for(uint16_t i = 0; i < 500; i++)
{
t = (double)i * (f_sig/f_s);
buff_dac[i] = (uint16_t)(4095* (1 + sin(2*3.14*f_sig*t))/2);
// buff_dac[i] = i*100;
}
return 100;
}
// Функция для тестирования пина
void delay_ms(uint32_t ms)
{
for(uint32_t i = 0; i < ms * 8000; i++)
{
__NOP(); // пропуск операций
}
}
void rcc_conf(void)
{
rcu_periph_clock_enable(RCU_GPIOF);
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_DAC);
rcu_periph_clock_enable(RCU_DMA0);
rcu_periph_clock_enable(RCU_DMA1);
rcu_periph_clock_enable(RCU_TIMER5);
}
void dac_config(void)
{
dac_deinit();
/* configure the DAC0 */
dac_wave_mode_config(DAC0, DAC_WAVE_DISABLE);
dac_output_buffer_disable(DAC0);
dac_trigger_source_config(DAC1, DAC_TRIGGER_T5_TRGO);
//dac_trigger_source_config(DAC0, DAC_TRIGGER_SOFTWARE);
dac_dma_enable(DAC0);
dac_output_buffer_enable(DAC0);
dac_trigger_enable(DAC0);
dac_enable(DAC0);
delay_1ms(100);
timer_enable(TIMER5);
delay_1ms(100);
}
void timer_config(void)
{
/* TIMER0 configuration: generate PWM signals with different duty cycles:
TIMER0CLK = SystemCoreClock / 12000 = 10kHz */
timer_oc_parameter_struct timer_ocintpara;
timer_parameter_struct timer_initpara;
timer_deinit(TIMER5);
/* TIMER0 configuration */
//timer_initpara.prescaler = 59;
timer_initpara.prescaler = 119;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
//timer_initpara.period = 1;
timer_initpara.period = 250;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TIMER5, &timer_initpara);
//timer_channel_output_pulse_value_config(TIMER5,TIMER_CH_0,250);
//timer_channel_output_mode_config(TIMER5,TIMER_CH_0,TIMER_OC_MODE_PWM0);
// timer_channel_output_shadow_config(TIMER5,TIMER_CH_0,TIMER_OC_SHADOW_DISABLE);
timer_master_output_trigger_source_select(TIMER5, TIMER_TRI_OUT_SRC_UPDATE);
timer_update_source_config(TIMER5, TIMER_UPDATE_SRC_GLOBAL); // БЕЗ ЭТОЙ СТРОЧКИ ТРИГГЕР от таймера НЕ РАБОТАЕТ и не поступает на ЦАП!!!!!!!!!
//timer_primary_output_config(TIMER5,ENABLE);
/* auto-reload preload enable */
timer_auto_reload_shadow_enable(TIMER5);
//timer_interrupt_enable(TIMER5, TIMER_INT_UP);
//nvic_irq_enable(TIMER5_IRQn, 2, 0);
}
void dac_dma_config(void)
{
//dma_interrupt_flag_clear(DMA1, DMA_CH2, DMA_INT_FLAG_G);
dma_parameter_struct dma_init_struct;
/* deinitialize DMA channel3 */
dma_deinit(DMA1, DMA_CH2);
dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;
//dma_init_struct.memory_addr = (uint32_t)&buff_dac;
dma_init_struct.memory_addr = (uint32_t)_binary_C__data_for_MC_2_bin_start + 20;
dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT;
dma_init_struct.number = 250; // выше 500 отсчетов не работает
dma_init_struct.periph_addr = (uint32_t)&DAC0_R12DH;
dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
dma_init(DMA1, DMA_CH2, &dma_init_struct);
/* configure DMA mode */
//uint32_t adrr_DMA01 = DMA_CHCNT(DMA1, DMA_CH2);
//*adrr_DMA01 = _binary_C___data_for_MC_2_bin_start[20];
dma_circulation_enable(DMA1, DMA_CH2);
//dma_channel_enable(DMA1, DMA_CH2);
//dma_interrupt_enable(DMA1, DMA_CH2, DMA_INT_HTF);
//nvic_irq_enable(DMA1_Channel2_IRQn, 2, 0);
}
void DMA1_Channel2_IRQHandler(void)
{
if(dma_interrupt_flag_get(DMA1, DMA_CH2, DMA_INT_HTF))
{
dma_channel_disable(DMA1, DMA_CH2);
DMA_CHCNT(DMA1, DMA_CH2) = _binary_C__data_for_MC_2_bin_start[20];
DAC0_R12DH = _binary_C__data_for_MC_2_bin_start[20];
//dma_channel_enable(DMA1, DMA_CH2);
dma_interrupt_flag_clear(DMA1, DMA_CH2, DMA_INT_HTF);
}
}
void TIMER5_IRQHandler(void)
{
if(timer_interrupt_flag_get(TIMER5, TIMER_INT_FLAG_UP) == SET)
{
timer_interrupt_flag_clear(TIMER5, TIMER_INT_FLAG_UP);
}
if(test_flag == 1)
{
gpio_bit_set(GPIOF, GPIO_PIN_2);
test_flag = 0;
}
else
{
gpio_bit_reset(GPIOF, GPIO_PIN_2);
test_flag = 1;
}
}
int main(void) {
gen_sin(100, 1);
systick_config();
rcc_conf();
gpio_init(GPIOF, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1);
gpio_init(GPIOF, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
dac_dma_config();
timer_config();
dac_config();
// После определения - вечный цикл моргания
while(1)
{
gpio_bit_reset(GPIOF, GPIO_PIN_1);
delay_1ms(500);
gpio_bit_set(GPIOF, GPIO_PIN_1);
delay_1ms(500);
}
}