В ответ могу предложить выхлоп синуса на 4 или 3 канала со сдвигом фаз,полностью аппаратный ну совершенно бесплатно.
В ответ могу предложить выхлоп синуса на 4 или 3 канала со сдвигом фаз,полностью аппаратный ну совершенно бесплатно.
Alex-lab писал(а):Есть такой же второй контроллер, поведение 1 в 1.
Я тоже не верю в неисправность периферии, да еще на двух МК.Alex-lab писал(а):Это был регистр CCR1.

Код: Выделить всё
#include "dma.h"
#include "timer.h"
#define ADC1_DR 0x4001244C //ADC onvertion result register address
#define DMA1_BASE_IFCR ((volatile uint32_t *)0x40020004)
#define DMA1_BASE_CCR1 ((volatile uint32_t *)0x40020008)
#define DMA1_BASE_CNDTR1 ((volatile uint32_t *)0x4002000C)
#define DMA1_BASE_CPAR1 ((volatile uint32_t *)0x40020010)
#define DMA1_BASE_CMAR1 ((volatile uint32_t *)0x40020014)
#define NVIC_ISER0 ((volatile uint32_t *) 0xE000E100)
const uint16_t StepDuration = 31250; //1 sec
const uint8_t StepNumber = 10;
const uint32_t PWMoff = 0xC000;
const uint32_t PWMon = 0xC000;
const uint32_t Pol1 = 0x0030; //positive
const uint32_t Pol0 = 0x0338; //opened
boolean b_stoped=true;
uint32_t u32_ADCres[4]; //ADC convertion results 12 bit
uint32_t u32_ADCaddr; //Address of ADC results ADC_DR register
uint16_t u16_cnt;
uint16_t u16_step;
uint16_t u16_output[StepNumber] = {4, 8, 16, 32, 64, 128, 256, 512, 1024,0};
void Timer1_CC2 () {
ADC1->regs->CR2 |= 0x00400000; //SOFTware start of ADC convertion
TIMER1_BASE->SR = 0;
}
void DMA1_channel1_Handler () { //happens when DMA obtained data from ADC
uint16_t tmp;
if (u16_cnt > StepDuration) { //If counter higher than length of a step
u16_step++; //switch to the next one
if (u16_step >= StepNumber) u16_step = 0; //If counter of steps higher than total step number
tmp = u16_output[u16_step];
TIMER1_BASE->CCR1 = tmp;
u16_cnt = 0;
}
u16_cnt++;
}
void setup() {
nvic_init(0x08000000, 0);
dma_attach_interrupt(DMA1, DMA_CH1, DMA1_channel1_Handler);
timer_attach_interrupt(TIMER1, TIMER_UPDATE_INTERRUPT, Timer1_CC2);
nvic_globalirq_enable();
afio_cfg_debug_ports(AFIO_DEBUG_NONE); //Debugger disable, its pins to GPIO
afio_remap(AFIO_REMAP_USART1);
// Serial.begin(115200); //High transmition rate for diag data sending
Serial.begin(9600); //Low transmission rate for 4 byte train
RCC_BASE->APB2ENR |= 0x00000200; //ADC clock enable
ADC1->regs->CR1 |= 0x00000100; //Sequence mode + //EndOfConv interrupt enable (+20)
ADC1->regs->CR2 |= 0x000E0101; //Trigggered by Softwarestart, DMA reqest enabled, ON
ADC1->regs->SQR3 |= 0x00018820; //Channels 1-4 in series
ADC1->regs->SQR1 |= 0x00300000; //Sequence length 1
RCC_BASE->APB2ENR |= 0x00000800; //PWM clock enable
TIMER1_BASE->ARR = 1152; //Max value of counter 31.25kHz output
TIMER1_BASE->CR2 = 0x0; //
TIMER1_BASE->CCMR1 = 0x3838; //CH1 high out on upconting, low out downcounting, preloading
TIMER1_BASE->CCMR2 = 0x0038; //CH3 high out on upconting, low out downcounting, preloading
TIMER1_BASE->CCER = 0x0555; //CH1,3 output, CH2 - no output
TIMER1_BASE->PSC = 0; //Prescaler=1
TIMER1_BASE->BDTR = 0x0C24; //Dead time 18 tics, auto output, uotputs disconnected
TIMER1_BASE->CCR1 = 1; //VAR. PWM width changeable value
TIMER1_BASE->CCR2 = 100; //Start ADC signal
TIMER1_BASE->CCR3 = 1; //CONST.
TIMER1_BASE->EGR = 0x0004; //Enable CC2 event for ADC convertion.
TIMER1_BASE->DIER |= 0x003F; //CC2, UEV interrupts enabled
TIMER1_BASE->RCR = 1; //Only each second (1+1) event causes interruption 0.5sec
// TIMER1_BASE->BDTR |= 0x3000; //Enable break function, active - high level
TIMER1_BASE->CR1 = 0x0080; //autoreload preload, edge alighed, run disabled
RCC_BASE->APB2ENR |= 0x00000001; //Alternate function clock enable
RCC_BASE->APB2ENR |= 0x00000004; //GPIOA clock enable
RCC_BASE->APB2ENR |= 0x00000008; //GPIOB clock enable
GPIOA->regs->CRH = 0xBBBBBBBB; //High A port alternative output with push-pull, 50 MHz
GPIOA->regs->CRL = 0x00000000; //Low A port analog inputs
GPIOB->regs->CRH = 0xBBBBBB33; //High B port (10-15) alternative output with push-pull, 50 MHz; 8,9 - output pushpull
GPIOB->regs->CRL = 0x4B333434; //Low B port (3-5)general porpose output with push-pull, 50 MHz; 1-3 - inout; 6,7 - USART1
GPIOB->regs->BRR = 0x0000033C; //Set B general outputs to low state
RCC_BASE->AHBENR |= 0x0001; //Enable DMA clock
u32_ADCaddr = uint32_t (u32_ADCres);
*DMA1_BASE_CMAR1 = u32_ADCaddr; //Startin address of ADC convertion results array
*DMA1_BASE_CPAR1 = ADC1_DR; //Address of ADC data register
*DMA1_BASE_CNDTR1 = 0x0004; //4 bytes to be moved
*DMA1_BASE_CCR1 = 0b0000101010100011; //MSIZE, PSIZE 32 bits each, mem inc, TCIE complite interrupt, enable DMA
pinMode(PC13, OUTPUT); //ON-OFF LED
digitalWrite(PC13, HIGH); //Default off state of the LED
pinMode(PB0, INPUT); //ON-OFF switch
//Starting
}
void loop() {
boolean b_state = !digitalRead(PB0);
if ((b_state) && (b_stoped)) { //ON switch
digitalWrite(PC13, LOW);
delay(500);
u16_cnt = 0; //reset main cntr
b_stoped = false; //disable STOP flag
GPIOB->regs->BSRR = Pol1;
delayMicroseconds(32); //one periods delay
DMA1->regs->IFCR = 0xFFFF; //reset DMA interrupt flag
TIMER1_BASE->SR = 0; //reset TIMER1 interrupt flag
TIMER1_BASE-> CR1 |= 0x0001; //Enable ON counter
TIMER1_BASE->BDTR |= PWMon;
}
if ((!b_state) && (!b_stoped)) { //OFF Switch
digitalWrite(PC13, HIGH);
delay(100);
b_stoped = true;
TIMER1_BASE->BDTR &= ~PWMoff; //OFF PWM outputs
TIMER1_BASE-> CR1 &= ~0x0001; //Disable OFF counter
delayMicroseconds(32); //one periods delay
GPIOB->regs->BRR = Pol0; //OFF polarity
}
}

