Форум РадиоКот • Просмотр темы - 3-канальный DDS на STM32F303
Сообщения без ответов | Активные темы
Страница 2 из 2
[ Сообщений: 29 ]
,
Автор
Сообщение
John Doe
Заголовок сообщения: Re: 3-канальный DDS на STM32F303
Добавлено: Сб ноя 25, 2017 23:24:49
Первый раз сказал Мяу!
Зарегистрирован: Чт май 10, 2012 03:01:41Сообщений: 39
Рейтинг сообщения: 0
Исключительно с целю экономии компонентов. У меня всего два 303-х. Применение 2-го МК не связано с измерениями, так что то устройство будет на отдельной плате. А вот названные 2 проекта - из одной сферы. И я не имел в виду совмещение функционала в одной прошивке, а что-то вроде переключения между двумя программами.Добавлено after 2 hours 21 minute 23 seconds: ...и что на счёт ГКЧ?
Вернуться наверх
Реклама
ncp1400
Заголовок сообщения: Re: 3-канальный DDS на STM32F303
Добавлено: Вс ноя 26, 2017 14:30:42
Карма: 10
Рейтинг сообщений: 81
Зарегистрирован: Чт янв 08, 2015 00:58:11Сообщений: 410
Рейтинг сообщения: 0
не вижу препятствий, можно и объединить ГКЧ+RLC. и софт общий на ПК+Android. в дальнейшем можно заменить фронт-энд более высокочастотным на AD98xx для измерения малых индуктивностей/емкостей и для VNA
Вернуться наверх
Реклама
John Doe
Заголовок сообщения: Re: 3-канальный DDS на STM32F303
Добавлено: Вс ноя 26, 2017 16:53:55
Первый раз сказал Мяу!
Зарегистрирован: Чт май 10, 2012 03:01:41Сообщений: 39
Рейтинг сообщения: 0
Но я только что заметил, что код, видимо, закрыт...
Вернуться наверх
Реклама
ncp1400
Заголовок сообщения: Re: 3-канальный DDS на STM32F303
Добавлено: Вс ноя 26, 2017 17:10:00
Карма: 10
Рейтинг сообщений: 81
Зарегистрирован: Чт янв 08, 2015 00:58:11Сообщений: 410
Рейтинг сообщения: 0
пока закрыт.
вот DDS часть, если поможет, в принципе ничего сложного - в прерывании половины DMA обновляются буферы семплов:
https://pastebin.com/uG6yUNKX Спойлер Код:
#define F_DDS 3200000uL // DDS base frequency #define DDS_CHANNELS 3 // number of DDS channels #define DDS_WAVE_BITS 10 // number of bits in waveform buffer #define DDS_WAVE_SAMPLES (1 << DDS_WAVE_BITS) // number of waveform samples #define DDS_OUT_BITS 9 // number of bits in waveform buffer #define DDS_OUT_SAMPLES (1 << DDS_OUT_BITS) // number of samples in output buffer #define DDS_SHIFT (32 - DDS_WAVE_BITS) #define DAC_OUT_MAX 4095 // DAC maximum level enum { DDS_FORM_SINE, DDS_FORM_SQR, DDS_FORM_PWM, DDS_FORM_TRI, DDS_FORM_SAW1, DDS_FORM_SAW2, DDS_FORM_DC, DDS_FORM_USER1, DDS_FORM_USER2, DDS_FORM_USER3, DDS_FORM_USER4, DDS_FORM_LAST }; struct dds_struct { // current table pointer, user wave table, output samples u16 *wave, table[DDS_WAVE_SAMPLES], out[DDS_OUT_SAMPLES]; struct { u32 acc, inc, add; } phase; u32 form, pwm, amp; // current wave form, PWM duty, amplitude u64 f,ph; // real frequency, phase struct { u8 chn, form, f, ph, pwm; } update; } __attribute__((aligned(2),packed)); inline u32 dds_sync(){ return gpio_get(GPIOA,3); } struct dds_struct dds[DDS_CHANNELS]; const u16 table_sine[DDS_WAVE_SAMPLES] = { 2048, 2061, 2073, 2086, 2098, 2111, 2123, 2136, 2148, 2161, 2174, 2186, 2199, 2211, 2224, 2236, 2249, 2261, 2274, 2286, 2299, 2311, 2323, 2336, 2348, 2361, 2373, 2386, 2398, 2410, 2423, 2435, 2447, 2460, 2472, 2484, 2497, 2509, 2521, 2533, 2545, 2558, 2570, 2582, 2594, 2606, 2618, 2630, 2642, 2654, 2666, 2678, 2690, 2702, 2714, 2726, 2738, 2749, 2761, 2773, 2785, 2796, 2808, 2820, 2831, 2843, 2855, 2866, 2878, 2889, 2900, 2912, 2923, 2935, 2946, 2957, 2968, 2980, 2991, 3002, 3013, 3024, 3035, 3046, 3057, 3068, 3079, 3090, 3100, 3111, 3122, 3133, 3143, 3154, 3164, 3175, 3185, 3196, 3206, 3216, 3227, 3237, 3247, 3257, 3267, 3277, 3287, 3297, 3307, 3317, 3327, 3337, 3347, 3356, 3366, 3376, 3385, 3395, 3404, 3413, 3423, 3432, 3441, 3450, 3459, 3469, 3478, 3487, 3495, 3504, 3513, 3522, 3531, 3539, 3548, 3556, 3565, 3573, 3581, 3590, 3598, 3606, 3614, 3622, 3630, 3638, 3646, 3654, 3662, 3669, 3677, 3685, 3692, 3700, 3707, 3714, 3722, 3729, 3736, 3743, 3750, 3757, 3764, 3771, 3777, 3784, 3791, 3797, 3804, 3810, 3817, 3823, 3829, 3835, 3841, 3847, 3853, 3859, 3865, 3871, 3876, 3882, 3888, 3893, 3898, 3904, 3909, 3914, 3919, 3924, 3929, 3934, 3939, 3944, 3949, 3953, 3958, 3962, 3967, 3971, 3975, 3980, 3984, 3988, 3992, 3996, 3999, 4003, 4007, 4010, 4014, 4017, 4021, 4024, 4027, 4031, 4034, 4037, 4040, 4042, 4045, 4048, 4051, 4053, 4056, 4058, 4060, 4063, 4065, 4067, 4069, 4071, 4073, 4075, 4076, 4078, 4080, 4081, 4083, 4084, 4085, 4086, 4087, 4088, 4089, 4090, 4091, 4092, 4093, 4093, 4094, 4094, 4094, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4094, 4094, 4094, 4093, 4093, 4092, 4091, 4090, 4089, 4088, 4087, 4086, 4085, 4084, 4083, 4081, 4080, 4078, 4076, 4075, 4073, 4071, 4069, 4067, 4065, 4063, 4060, 4058, 4056, 4053, 4051, 4048, 4045, 4042, 4040, 4037, 4034, 4031, 4027, 4024, 4021, 4017, 4014, 4010, 4007, 4003, 3999, 3996, 3992, 3988, 3984, 3980, 3975, 3971, 3967, 3962, 3958, 3953, 3949, 3944, 3939, 3934, 3929, 3924, 3919, 3914, 3909, 3904, 3898, 3893, 3888, 3882, 3876, 3871, 3865, 3859, 3853, 3847, 3841, 3835, 3829, 3823, 3817, 3810, 3804, 3797, 3791, 3784, 3777, 3771, 3764, 3757, 3750, 3743, 3736, 3729, 3722, 3714, 3707, 3700, 3692, 3685, 3677, 3669, 3662, 3654, 3646, 3638, 3630, 3622, 3614, 3606, 3598, 3590, 3581, 3573, 3565, 3556, 3548, 3539, 3531, 3522, 3513, 3504, 3495, 3487, 3478, 3469, 3459, 3450, 3441, 3432, 3423, 3413, 3404, 3395, 3385, 3376, 3366, 3356, 3347, 3337, 3327, 3317, 3307, 3297, 3287, 3277, 3267, 3257, 3247, 3237, 3227, 3216, 3206, 3196, 3185, 3175, 3164, 3154, 3143, 3133, 3122, 3111, 3100, 3090, 3079, 3068, 3057, 3046, 3035, 3024, 3013, 3002, 2991, 2980, 2968, 2957, 2946, 2935, 2923, 2912, 2900, 2889, 2878, 2866, 2855, 2843, 2831, 2820, 2808, 2796, 2785, 2773, 2761, 2749, 2738, 2726, 2714, 2702, 2690, 2678, 2666, 2654, 2642, 2630, 2618, 2606, 2594, 2582, 2570, 2558, 2545, 2533, 2521, 2509, 2497, 2484, 2472, 2460, 2447, 2435, 2423, 2410, 2398, 2386, 2373, 2361, 2348, 2336, 2323, 2311, 2299, 2286, 2274, 2261, 2249, 2236, 2224, 2211, 2199, 2186, 2174, 2161, 2148, 2136, 2123, 2111, 2098, 2086, 2073, 2061, 2048, 2035, 2023, 2010, 1998, 1985, 1973, 1960, 1948, 1935, 1922, 1910, 1897, 1885, 1872, 1860, 1847, 1835, 1822, 1810, 1797, 1785, 1773, 1760, 1748, 1735, 1723, 1710, 1698, 1686, 1673, 1661, 1649, 1636, 1624, 1612, 1599, 1587, 1575, 1563, 1551, 1538, 1526, 1514, 1502, 1490, 1478, 1466, 1454, 1442, 1430, 1418, 1406, 1394, 1382, 1370, 1358, 1347, 1335, 1323, 1311, 1300, 1288, 1276, 1265, 1253, 1241, 1230, 1218, 1207, 1196, 1184, 1173, 1161, 1150, 1139, 1128, 1116, 1105, 1094, 1083, 1072, 1061, 1050, 1039, 1028, 1017, 1006, 996, 985, 974, 963, 953, 942, 932, 921, 911, 900, 890, 880, 869, 859, 849, 839, 829, 819, 809, 799, 789, 779, 769, 759, 749, 740, 730, 720, 711, 701, 692, 683, 673, 664, 655, 646, 637, 627, 618, 609, 601, 592, 583, 574, 565, 557, 548, 540, 531, 523, 515, 506, 498, 490, 482, 474, 466, 458, 450, 442, 434, 427, 419, 411, 404, 396, 389, 382, 374, 367, 360, 353, 346, 339, 332, 325, 319, 312, 305, 299, 292, 286, 279, 273, 267, 261, 255, 249, 243, 237, 231, 225, 220, 214, 208, 203, 198, 192, 187, 182, 177, 172, 167, 162, 157, 152, 147, 143, 138, 134, 129, 125, 121, 116, 112, 108, 104, 100, 97, 93, 89, 86, 82, 79, 75, 72, 69, 65, 62, 59, 56, 54, 51, 48, 45, 43, 40, 38, 36, 33, 31, 29, 27, 25, 23, 21, 20, 18, 16, 15, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18, 20, 21, 23, 25, 27, 29, 31, 33, 36, 38, 40, 43, 45, 48, 51, 54, 56, 59, 62, 65, 69, 72, 75, 79, 82, 86, 89, 93, 97, 100, 104, 108, 112, 116, 121, 125, 129, 134, 138, 143, 147, 152, 157, 162, 167, 172, 177, 182, 187, 192, 198, 203, 208, 214, 220, 225, 231, 237, 243, 249, 255, 261, 267, 273, 279, 286, 292, 299, 305, 312, 319, 325, 332, 339, 346, 353, 360, 367, 374, 382, 389, 396, 404, 411, 419, 427, 434, 442, 450, 458, 466, 474, 482, 490, 498, 506, 515, 523, 531, 540, 548, 557, 565, 574, 583, 592, 601, 609, 618, 627, 637, 646, 655, 664, 673, 683, 692, 701, 711, 720, 730, 740, 749, 759, 769, 779, 789, 799, 809, 819, 829, 839, 849, 859, 869, 880, 890, 900, 911, 921, 932, 942, 953, 963, 974, 985, 996, 1006, 1017, 1028, 1039, 1050, 1061, 1072, 1083, 1094, 1105, 1116, 1128, 1139, 1150, 1161, 1173, 1184, 1196, 1207, 1218, 1230, 1241, 1253, 1265, 1276, 1288, 1300, 1311, 1323, 1335, 1347, 1358, 1370, 1382, 1394, 1406, 1418, 1430, 1442, 1454, 1466, 1478, 1490, 1502, 1514, 1526, 1538, 1551, 1563, 1575, 1587, 1599, 1612, 1624, 1636, 1649, 1661, 1673, 1686, 1698, 1710, 1723, 1735, 1748, 1760, 1773, 1785, 1797, 1810, 1822, 1835, 1847, 1860, 1872, 1885, 1897, 1910, 1922, 1935, 1948, 1960, 1973, 1985, 1998, 2010, 2023, 2035, }; void dds_setup(){ // PA3 - Sync gpio_mode1(GPIOA, GPIO_MODE_INPUT, 3); gpio_pupd1(GPIOA, GPIO_PULLUP, 3); // PA4-6 - DACs gpio_mode3(GPIOA, GPIO_MODE_ANALOG, 4,5,6); gpio_pupd3(GPIOA, GPIO_NOPULL, 4,5,6); // DACs __DAC1_CLK_ENABLE(); __DAC2_CLK_ENABLE(); DAC1->CR = DAC_CR_TSEL1 | DAC_CR_TSEL2 | DAC_CR_EN1 | DAC_CR_EN2 | DAC_CR_BOFF2 | (config.params.s.buf ? 0 : DAC_CR_BOFF1); DAC2->CR = DAC_CR_TSEL1 | DAC_CR_TSEL2 | DAC_CR_EN1 | DAC_CR_EN2 | DAC_CR_BOFF1 | DAC_CR_BOFF2; // Timer __TIM1_CLK_ENABLE(); TIM_HandleTypeDef timh; timh.Instance = TIM1; timh.Init.Prescaler = 0; timh.Init.Period = F_CPU / F_DDS - 1; timh.Init.ClockDivision = 1; //TIM_CLOCKDIVISION_DIV1; timh.Init.CounterMode = TIM_COUNTERMODE_UP; timh.Init.RepetitionCounter = 0; HAL_TIM_Base_Init(&timh); TIM1->CR1 &= ~TIM_CR1_CEN; TIM1->CCR1 = TIM1->CCR2 = TIM1->CCR3 = F_CPU / F_DDS - 1; TIM1->DIER |= TIM_DIER_CC1DE | TIM_DIER_CC2DE | TIM_DIER_CC3DE; // DMA __DMA1_CLK_ENABLE(); DMA_HandleTypeDef dmah12; dmah12.Instance = DMA1_Channel2; dmah12.Init.Direction = DMA_MEMORY_TO_PERIPH; dmah12.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; dmah12.Init.MemInc = DMA_MINC_ENABLE; dmah12.Init.Mode = DMA_CIRCULAR; dmah12.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; dmah12.Init.PeriphInc = DMA_PINC_DISABLE; dmah12.Init.Priority = DMA_PRIORITY_VERY_HIGH; HAL_DMA_Init(&dmah12); HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn); HAL_DMA_Start_IT(&dmah12, (u32)&dds[0].out, (u32)&DAC1->DHR12R1, DDS_OUT_SAMPLES); DMA_HandleTypeDef dmah13; dmah13.Instance = DMA1_Channel3; dmah13.Init.Direction = DMA_MEMORY_TO_PERIPH; dmah13.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; dmah13.Init.MemInc = DMA_MINC_ENABLE; dmah13.Init.Mode = DMA_CIRCULAR; dmah13.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; dmah13.Init.PeriphInc = DMA_PINC_DISABLE; dmah13.Init.Priority = DMA_PRIORITY_VERY_HIGH; HAL_DMA_Init(&dmah13); HAL_DMA_Start(&dmah13, (u32)&dds[1].out, (u32)&DAC1->DHR12R2, DDS_OUT_SAMPLES); DMA_HandleTypeDef dmah16; dmah16.Instance = DMA1_Channel6; dmah16.Init.Direction = DMA_MEMORY_TO_PERIPH; dmah16.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; dmah16.Init.MemInc = DMA_MINC_ENABLE; dmah16.Init.Mode = DMA_CIRCULAR; dmah16.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; dmah16.Init.PeriphInc = DMA_PINC_DISABLE; dmah16.Init.Priority = DMA_PRIORITY_VERY_HIGH; HAL_DMA_Init(&dmah16); HAL_DMA_Start(&dmah16, (u32)&dds[2].out, (u32)&DAC2->DHR12R1, DDS_OUT_SAMPLES); // update all channels for (u8 i=0; i<DDS_CHANNELS; i++){ dds[i].wave = &dds[i].table[0]; dds[i].update.form = dds[i].update.f = dds[i].update.ph = dds[i].update.pwm = 1; } // start main timer TIM1->CR1 |= TIM_CR1_CEN; ptx_add(dds_thread, NULL, PTX_RUN); } void handler_IRQ_DMA1_Channel2(){ u16 *out1,*out2,*out3, *wave1,*wave2,*wave3; // load pointers to out buffers if (DMA1->ISR & DMA_FLAG_HT2){ out1 = &dds[0].out[0]; out2 = &dds[1].out[0]; out3 = &dds[2].out[0]; } else if (DMA1->ISR & DMA_FLAG_TC2){ out1 = &dds[0].out[DDS_OUT_SAMPLES / 2]; out2 = &dds[1].out[DDS_OUT_SAMPLES / 2]; out3 = &dds[2].out[DDS_OUT_SAMPLES / 2]; } // clear DMA flags DMA1->IFCR = DMA_IFCR_CHTIF2 | DMA_IFCR_CTCIF2;// | DMA_IFCR_CTEIF2; // synchronize accumulators if (config.params.s.sync) config.params.s.sync = dds[0].phase.acc = dds[1].phase.acc = dds[2].phase.acc = 0; // cache phase/increment u32 acc1 = dds[0].phase.acc + dds[0].phase.add; u32 inc1 = dds[0].phase.inc; u32 acc2 = dds[1].phase.acc + dds[1].phase.add; u32 inc2 = config.params.s.all_freq1 ? dds[0].phase.inc : dds[1].phase.inc; u32 acc3 = dds[2].phase.acc + dds[2].phase.add; u32 inc3 = config.params.s.all_freq1 ? dds[0].phase.inc : dds[2].phase.inc; // load pointers to wavetables if (config.params.s.all_form1) wave1 = wave2 = wave3 = dds[0].wave; else { wave1 = dds[0].wave; wave2 = dds[1].wave; wave3 = dds[2].wave; } // update out buffers for (u32 i=(DDS_OUT_SAMPLES / 64); i--; ){ *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; *out1++ = wave1[acc1 >> DDS_SHIFT]; *out2++ = wave2[acc2 >> DDS_SHIFT]; *out3++ = wave3[acc3 >> DDS_SHIFT]; acc1 += inc1; acc2 += inc2; acc3 += inc3; } // store current accumulators dds[0].phase.acc = acc1 - dds[0].phase.add; dds[1].phase.acc = acc2 - dds[1].phase.add; dds[2].phase.acc = acc3 - dds[2].phase.add; } u8 dds_chn, sync_prev; PT_THREAD( dds_thread( struct pt *pt, struct ptx *ptx ) ) { PT_BEGIN(pt); while (1) { PT_YIELD(pt); // update Sync input u32 sync = !!dds_sync(); if (!sync && sync_prev){ cli(); dds[0].phase.acc = dds[1].phase.acc = dds[2].phase.acc = 0; sei(); } sync_prev = sync; // update DDS parameters for (dds_chn=0; dds_chn<DDS_CHANNELS; dds_chn++){ // update waveform if (dds[dds_chn].update.form){ if (config.params.s.dc[dds_chn] >= 0){ u16 dac = config.params.s.dc[dds_chn] * (u32)DAC_OUT_MAX / 100; for (u32 i=0; i<DDS_WAVE_SAMPLES; i++) dds[dds_chn].table[i] = dac; } else { switch (config.params.s.form[dds_chn]){ case DDS_FORM_SINE: for (u32 i=0; i<DDS_WAVE_SAMPLES; i++) dds[dds_chn].table[i] = config.params.s.inv[dds_chn] ? (DAC_OUT_MAX - table_sine[i]) : table_sine[i]; break; case DDS_FORM_SQR: for (u32 i=0; i<DDS_WAVE_SAMPLES; i++){ u16 s = (i < DDS_WAVE_SAMPLES/2) ? 0 : DAC_OUT_MAX; dds[dds_chn].table[i] = config.params.s.inv[dds_chn] ? (DAC_OUT_MAX - s) : s; } break; case DDS_FORM_PWM: dds[dds_chn].update.pwm = 1; break; case DDS_FORM_TRI: { u16 w = 0; for (u32 i=0; i<DDS_WAVE_SAMPLES/2; i++,w+=((DAC_OUT_MAX+1)/(DDS_WAVE_SAMPLES/2))) dds[dds_chn].table[i] = config.params.s.inv[dds_chn] ? (DAC_OUT_MAX - w) : w; for (u32 i=DDS_WAVE_SAMPLES/2; i<DDS_WAVE_SAMPLES; i++,w-=((DAC_OUT_MAX+1)/(DDS_WAVE_SAMPLES/2))) dds[dds_chn].table[i] = config.params.s.inv[dds_chn] ? (DAC_OUT_MAX - w) : w; break; } case DDS_FORM_SAW1: { u16 w = 0; for (u32 i=0; i<DDS_WAVE_SAMPLES; i++,w+=((DAC_OUT_MAX+1)/DDS_WAVE_SAMPLES)) dds[dds_chn].table[i] = config.params.s.inv[dds_chn] ? (DAC_OUT_MAX - w) : w; break; } case DDS_FORM_SAW2: { u16 w = DAC_OUT_MAX; for (u32 i=0; i<DDS_WAVE_SAMPLES; i++,w-=((DAC_OUT_MAX+1)/DDS_WAVE_SAMPLES)) dds[dds_chn].table[i] = config.params.s.inv[dds_chn] ? (DAC_OUT_MAX - w) : w; break; } case DDS_FORM_DC: dds[dds_chn].update.pwm = 1; break; case DDS_FORM_USER1: break; case DDS_FORM_USER2: break; case DDS_FORM_USER3: break; case DDS_FORM_USER4: break; } } dds[dds_chn].update.form = 0; PT_YIELD(pt); } // update frequency if (dds[dds_chn].update.f){ dds[dds_chn].phase.inc = 0x100000000uLL * config.set.s.f[dds_chn] / F_DDS / 1000uLL; dds[dds_chn].update.f = 0; PT_YIELD(pt); } // update phase if (dds[dds_chn].update.ph){ dds[dds_chn].phase.add = config.set.s.ph[dds_chn] * 0xFFFFFFFFuLL / 359999uLL; dds[dds_chn].update.ph = 0; PT_YIELD(pt); } // update PWM if (dds[dds_chn].update.pwm){ if (config.params.s.form[dds_chn] == DDS_FORM_PWM){ u16 pwm = config.set.s.pwm[dds_chn] * DDS_WAVE_SAMPLES / 100000uL; for (u32 i=0; i<DDS_WAVE_SAMPLES; i++){ u16 s = (i < pwm) ? DAC_OUT_MAX : 0; dds[dds_chn].table[i] = config.params.s.inv[dds_chn] ? (DAC_OUT_MAX - s) : s; } dds[dds_chn].update.pwm = 0; PT_YIELD(pt); } else if (config.params.s.form[dds_chn] == DDS_FORM_DC){ u16 dc = config.set.s.pwm[dds_chn] * DAC_OUT_MAX / 100000uL; for (u32 i=0; i<DDS_WAVE_SAMPLES; i++) dds[dds_chn].table[i] = config.params.s.inv[dds_chn] ? (DAC_OUT_MAX - dc) : dc; } } } } PT_END(pt); return PT_ENDED; }
Вернуться наверх
Реклама
Выбираем схему BMS для заряда литий-железофосфатных (LiFePO4) аккумуляторов
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Подробнее>>
kloker
Заголовок сообщения: Re: 3-канальный DDS на STM32F303
Добавлено: Чт окт 03, 2019 15:12:24
Зарегистрирован: Ср сен 09, 2015 13:09:15Сообщений: 558
Рейтинг сообщения: 0
ncp1400 , а чем разработка закончилась, версией 0.1?
Вернуться наверх
Реклама
Реклама
Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Подробнее>>
ncp1400
Заголовок сообщения: Re: 3-канальный DDS на STM32F303
Добавлено: Пт ноя 01, 2019 15:41:54
Карма: 10
Рейтинг сообщений: 81
Зарегистрирован: Чт янв 08, 2015 00:58:11Сообщений: 410
Рейтинг сообщения: 0
а чем должно закончиться ?... мне всего несколько раз был нужен 2/3-фазный синус/ШИМ с программируемой частотой/фазой. в прошивке это реализовано, и больше к проекту не возвращался, платы демонтированы...
Вернуться наверх
Реклама
muravei
Заголовок сообщения: Re: 3-канальный DDS на STM32F303
Добавлено: Вс ноя 03, 2019 12:06:34
Первый раз сказал Мяу!
Зарегистрирован: Ср фев 14, 2018 11:33:43Сообщений: 39
Рейтинг сообщения: 1
платы демонтированы...
Сурово.
Может быть , тогда, выложить проект целиком?
Кстати, какой шаг частоты синуса?
Вернуться наверх
Реклама
alexlo13
Заголовок сообщения: Re: 3-канальный DDS на STM32F303
Добавлено: Пт май 15, 2020 10:57:11
Карма: 1
Рейтинг сообщений: 1
Зарегистрирован: Ср ноя 25, 2009 20:47:16Сообщений: 88
Рейтинг сообщения: 0
А кто то собирал схему из второго поста? Что то у меня на дисплее тишина, а на выходах просто постоянное напряжение.
Вернуться наверх
Реклама
Chip4ik74
Заголовок сообщения: Re: 3-канальный DDS на STM32F303
Добавлено: Ср окт 12, 2022 12:47:32
Зарегистрирован: Ср окт 12, 2022 12:29:09Сообщений: 3
Рейтинг сообщения: 0
Всем добрый день, проблема с CAN на STM32F303VCT6 , прогу пишу в IAR, Can вообще никак не стартует, при этом gpio, таймеры все работает, может есть у кого готовый кусок кода с рабочей передачей по CAN, чтобы сравнить и найти косяк. До этого писал под st32f373, вообще никаких проблем.
Вернуться наверх
Реклама
Страница 2 из 2
[ Сообщений: 29 ]
,
Кто сейчас на форуме
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 40
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения