Zase STM32

Pavel Hudecek edizon na seznam.cz
Pondělí Listopad 30 03:36:37 CET 2020


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;

------------- další část ---------------
HTML příloha byla odstraněna...
URL: <http://list.hw.cz/pipermail/hw-list/attachments/20201130/38a144ca/attachment-0001.html>


Další informace o konferenci Hw-list