Zase STM32
Pavel Hudecek
edizon na seznam.cz
Pondělí Listopad 30 11:20:13 CET 2020
Bingo!
switch(chan) {
case 1:
TIM3->CCMR1 |= 0b111<<4;// OCxM out 111 PWM mode 2, 110 PWM mode 1
TIM3->CCER &= ~(0b1111UL);
TIM3->CCER |= 0b0011; // CCxP 1: OCx active low / CCxE 1: On - OCx signal is output
break;
case 2:
TIM3->CCMR1 |= 0b111<<12;
TIM3->CCER &= ~(0b1111UL<<4);
TIM3->CCER |= 0b0011<<4;
break;
case 3:
TIM3->CCMR2 |= 0b111<<4;
TIM3->CCER &= ~(0b1111UL<<8);
TIM3->CCER |= 0b0011<<8;
break;
case 4:
TIM3->CCMR2 |= 0b111<<12;
TIM3->CCER &= ~(0b1111UL<<12);
TIM3->CCER |= 0b0011<<12;
break;
}
A taky jsem zohlednil námitky ohledně 0xffffffff-… normálně to používám u 8b, 255-…, ale tady to není úplně jisté.
PH
Od: Fanda Kopriva
pro pwm mate spusteny pouze kanal 4
pro kanaly 2 a 3 by tam melo byt
TIM3->CCMR2 = (0b111<<12) | (0b111<<4); // OC4M out 111 PWM mode 2, 110 PWM mode 1
TIM3->CCMR1 = 0b111<<12;
TIM3->CCER = 0x3330;
fanda
Dne 30. 11. 2020 v 3:36 Pavel Hudecek napsal(a):
Je to tak. Dokonce to původně bylo správně, ale pak jsem to v rámci nějakého zmatkování „opravil“. Ale nepomohlo. Ale při zkoumání registrů v DS jsem provedl ještě další úpravy:
// moje PWM TIM3 chan
#define PWM0_chan 3 // az po propojeni
#define PWM1_chan 4
#define PWM2_chan 2
void pwmSet(char chan, uint16_t val) { // hodnota PWM -------------------------------------------------
switch(chan) {
//case 0: TIM3->CCR0 = val; break;
case 1: TIM3->CCR1 = val; break;
case 2: TIM3->CCR2 = val; break;
case 3: TIM3->CCR3 = val; break;
case 4: TIM3->CCR4 = val; break;
}
}
void pwmInit(uint8_t chan, char port, uint8_t pin, uint16_t per, uint16_t val) { // -------------------
RCC->AHBENR |= (1<<17) + (1<<18); // IOPAEN IOPBEN
RCC->APB1ENR |= 2; // APB peripheral clock enable TIM3
switch (port) {
case 'A':
GPIOA->MODER &= 0xffffffff-(3<<(pin<<1)); // port fn clear
GPIOA->MODER |= 2<<(pin<<1); // port alt fn
GPIOA->OTYPER &= 0xffffffff-(1<<pin); // push-pull
GPIOA->OSPEEDR |= 3<<(pin<<1); // port high speed
switch(chan) {
case 0:
break;
case 1:
GPIOA->AFR[0] |= 1<<(pin<<2); // AF1
break;
case 2:
GPIOA->AFR[0] |= 1<<(pin<<2); // AF1
break;
case 3:
break;
case 4:
break;
}
break;
case 'B':
GPIOB->MODER &= 0xffffffff-(3<<(pin<<1)); // port fn clear
GPIOB->MODER |= 2<<(pin<<1); // port alt fn
GPIOB->OTYPER &= 0xffffffff-(1<<pin); // push-pull
GPIOB->OSPEEDR |= 3<<(pin<<1); // port high speed
switch(chan) {
case 0:
break;
case 1:
GPIOB->AFR[0] |= 1<<(pin<<2); // AF1
break;
case 2:
GPIOB->AFR[0] |= 1<<(pin<<2); // AF1
break;
case 3:
GPIOB->AFR[0] |= 1<<(pin<<2); // AF1
break;
case 4:
GPIOB->AFR[0] |= 1<<(pin<<2); // AF1
break;
}
break;
}
TIM3->CR1 = 1; // Bit 1 UDIS: Update disable
TIM3->CCMR2 = 0b111<<12; // OC4M out 111 PWM mode 2, 110 PWM mode 1
TIM3->CCER = 0x3000; // CC4P 1: OC1 active low / CC4E 1: On - OC1 signal is output
TIM3->CNT = 0; // counter
TIM3->PSC = 0; // nedelit - 48 MHz
TIM3->ARR = per; // perioda
TIM3->CR1 = 1; // CEN 1: Counter enabled
pwmSet(chan, val); // hodnota PWM
}
A v mainu:
pwm0=10; pwm1=30; pwm2=180;
pwmInit(PWM0_chan, 'B', 0, CPU_freq/PWM_freq, pwm0);
pwmInit(PWM1_chan, 'B', 1, CPU_freq/PWM_freq, pwm1);
pwmInit(PWM2_chan, 'A', 7, CPU_freq/PWM_freq, pwm2);
while (1) {
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, 1);
HAL_GPIO_WritePin(LEDpwm0_GPIO_Port, LEDpwm0_Pin, 1);
for (n=0; n<1000000; n++);
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, 0);
HAL_GPIO_WritePin(LEDpwm0_GPIO_Port, LEDpwm0_Pin, 0);
for (n=0; n<1000000; n++);
}
Stav byl takový, že ty výstupy se chovaly jako vstupy. Na jednom, který končí testpinem (to je ta poznámka u definů „az po propojeni“) osciloskop ukazoval 0, na zbylých 2 byly skoro 4 V (připojeno na vstupy NCP81071A s pullupama, s napájením asi 7,5 V) a na PWM0, které vede na A9/TIM1.2 (nekonfigurován), bylo skoro 7.
Závěr ze čtení registrů: Je v nich všechno správně.
Po úpravě kódu ten nepoužitej už nemá 7, ale funguje jako výstup. Navíc na PWM1 (=B1/TIM3.4) je PWM 240 kHz. Zbylé 2 zůstaly stejné (0 a skoro 4), tedy asi stále vstupy.
Po kontrole výšeuvedeného textu jsem pojal podezření a před řádky s nastavením alternativní funkce jsem přidal:
GPIOB->AFR[0] &= 0xffffffff - (3<<(pin<<2)); // nulovat AF
Ale už se tím nic nezměnilo.
PH
Od: Jan Waclawek
Dobry postreh!
> GPIOA->MODER |= 2<<(1<<pin);
ma byt
GPIOA->MODER |= 2<<(pin<<1);
alebo mozno lepsie
GPIOA->MODER |= 0b10 << (2 * pin);
z coho je jasne vidiet, ze v MODER su 2 bity na pin.
wek
----- Original Message ---------------
Subject: Re: Zase STM32
From: Fanda Kopriva <info na elektronikavyvoj.cz>
Date: Sun, 29 Nov 2020 22:39:56 +0100
To: hw-list na list.hw.cz
dobry vecer
tyto zapisy moc nepouzivam .takze mozna budu kecat ,ale vychazi mi to
nejak divne proto pisu "asi":
void pwmInit(uint8_t chan, char port, uint8_t pin, uint16_t per,
uint16_t val) parametry funkce
jak dopadne volani jednotlivych funkci
pwmInit(PWM0_chan, 'B', 0, CPU_freq/PWM_freq, pwm0); //chan = 3
GPIOB->MODER |= 2<<(1<<pin); > 2<<(1<<0) = 4 asi by melo byt
2 port.1 je asi nastaven do vystupu misto port.0 do altern.
case 3:
GPIOB->AFR[0] |= 1<<(pin<<2); // AF1 > 1<<(0<<2) = 1 to je asi spravne
break;
_______________________________________________
HW-list mailing list - sponsored by www.HW.cz
Hw-list na list.hw.cz
http://list.hw.cz/mailman/listinfo/hw-list
------------- další část ---------------
HTML příloha byla odstraněna...
URL: <http://list.hw.cz/pipermail/hw-list/attachments/20201130/68fdb777/attachment-0001.html>
Další informace o konferenci Hw-list