Haberler:

Foruma Resim Yükleme ve Boyut Sınırlaması ( ! )  https://bit.ly/2GMFb8H

Ana Menü

STM32L0 uyku modu hakkında

Başlatan Eren Eraslan, 23 Eylül 2017, 20:46:26

Eren Eraslan

Merhabalar ,
Şu aralar, STM32L053C6T6 işlemcisini kullanarak düşük güç modunda pil tüketimini optimize etme çalışmaları sürdürüyorum.
İşin içinden çıkamadığım bir problemle karşı karşıyayım, yardımcı olabilirseniz çok sevinirim.
Öncelikle algoritmayı çok basitleştirilmiş şekilde anlatacak olursam while döngüsü içerisinde Uart üzerinden Pc ye started yazdırıyorum. Daha sonra RTC alarmını 10sn sonraya kuracak şekilde ayarlıyorum
ve en sonunda Stop Moda alıp işlemciyi uyutuyorum. 10sn sonra da düzgün bir şekilde uyanıyor. Buraya kadar herşey normal. Fakat iş burada biraz değişiyor. Uyandıktan sonra SystemClock_Config çağırıp kaldığım yerden devam ediyorum. Yani ekrana woken-up yazdırıyorum. Burası cepte... Bu şekilde sonsuza kadar çalıştırabiliyorum Fakat uykuda çektiği akım hoşuma gitmiyor 10mA civarı.

Güç tüketimini çok daha aşşağılara çekme adına, Uyku moduna girmeden evvel bütün pinleri yaparak güç tüketimini indirgiyorum. Fakat bütün pinleri analog yaptıktan sonra uyutup uyanınca bütün peripheral ları init ettiğim halde(GPIO,UART,TIMER vs.) uarttan veri gönderemiyorum. Ama I/O larım ve systick timerım çalışıyor. Bunu da bir ledi belirli bir beklemede (HAL_DELAY)yakıp söndürerek anlıyorum

MAIN.C
int main(void)
{
	HAL_Init();
	SystemClock_Config();

	MX_GPIO_Init();
	MX_ADC_Init();
	MX_I2C1_Init();
	MX_RTC_Init();
	MX_TIM22_Init();
	MX_USART1_UART_Init();
	MX_USART2_UART_Init();;
	Init_RTC();
	HAL_Delay(500);
	while(1)
	{
		printf("Started\n\r");						
		for(uint16_t count1 = 0;count1<25;count1++){
			HAL_GPIO_TogglePin(STATE_LED0_GPIO_Port,STATE_LED0_Pin);
			HAL_Delay(25);
		}
		SetAlarm(10);							//10sn sonra alarm kuruyor
		EnterStopMode();						//Uyku modu ayarlamalari
		printf("Woken-Up\n\r");
		HAL_Delay(1000); 	
	}
}


Uyku Moduna Aldığım Fonksiyon
void EnterStopMode(void)
{
  GPIO_InitTypeDef GPIO_InitStruct;
  //A ve B portlarini kullandigim icin bu portlari analog yaptim
  __HAL_RCC_GPIOA_CLK_ENABLE();                           
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /* Configure all GPIO port pins in Analog Input mode (floating input trigger OFF) */
  GPIO_InitStruct.Pin = GPIO_PIN_All;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);


  /* Disable GPIOs clock */
  __HAL_RCC_GPIOA_CLK_DISABLE();
  __HAL_RCC_GPIOB_CLK_DISABLE();

  // STOP Moda girme komutu
  HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
	HAL_Delay(1000);
	SystemClock_Config();

	HAL_Delay(500);
	MX_GPIO_Init();
  MX_USART2_UART_Init();	
}



Hatayı nerede yapıyorum. Neden pinleri analog yaptıktan sonra MX_GPIO_Init ve MX_USART2_UART_Init çağırmış olmam birşey değiştirmiyor?
Teşekkürler
insanın içine işleyen şarkılar ;  https://soundcloud.com/reeraslan

baran123

Hocam I/O pinlerini kapatınca UART'ın kullandığı I/O pinlerinde kapanmıyor mu ?

Eren Eraslan

Alıntı yapılan: baran123 - 23 Eylül 2017, 22:09:47
Hocam I/O pinlerini kapatınca UART'ın kullandığı I/O pinlerinde kapanmıyor mu ?

kapanıyor da uyandıktan sonra MX_USART1_UART_Init(); fonksiyonunu çağırıyorum. tekrardan init etmesi gerekiyor. Onu soruyorum aslında
insanın içine işleyen şarkılar ;  https://soundcloud.com/reeraslan

baran123

Hocam bu fonksiyon sadece UART init yapmıyor mu ?
Sizin RCC clocklarını tekrar aktif edip GPIO init yaptıktan sonra bu fonksiyon çağırmanız gerekiyor sanırım
Ben HAL kullanmadığım için pek bilmiyorum yanlış yönlendiriyorsam affola :)

Eren Eraslan

Alıntı yapılan: baran123 - 23 Eylül 2017, 22:21:29
Hocam bu fonksiyon sadece UART init yapmıyor mu ?
Sizin RCC clocklarını tekrar aktif edip GPIO init yaptıktan sonra bu fonksiyon çağırmanız gerekiyor sanırım
Ben HAL kullanmadığım için pek bilmiyorum yanlış yönlendiriyorsam affola :)

Uyku moduna aldığım fonksiyon içerine bakarsak hocam
SystemClock_Config() ile bütün clock ları tekrardan aktifleştiriyor(mcu ilk açıldığındaki gibi)
MX_GPIO_Init() GPIO ve clock ları aktifleştiriliyor
MX_USART1_UART_Init(); kullandığım uart modülü aktifleştiriliyor.

zaten akış sizin bahsettiğiniz gibi hocam ben mi yanılıyorum
insanın içine işleyen şarkılar ;  https://soundcloud.com/reeraslan

baran123

SystemClock_Config bu fonksiyon içerisinde sadece systemClock ayarlanıyor.
Siz bütün sistemi yeniden çalıştırmak istiyorsanız uyandırma ile birlikte şu işlemleri yapmalısınız.

1 Uyandıran komut
2 MX_GPIO_Init();
3 MX_USART1_UART_Init();

2 numarayı yapmamızın sebebi uart pinlerinin GPIO Clock ları aktifleştirilmesi içindir.

Eren Eraslan

Alıntı yapılan: baran123 - 23 Eylül 2017, 22:31:12
SystemClock_Config bu fonksiyon içerisinde sadece systemClock ayarlanıyor.
Siz bütün sistemi yeniden çalıştırmak istiyorsanız uyandırma ile birlikte şu işlemleri yapmalısınız.

1 Uyandıran komut
2 MX_GPIO_Init();
3 MX_USART1_UART_Init();

2 numarayı yapmamızın sebebi uart pinlerinin GPIO Clock ları aktifleştirilmesi içindir.

hocam systemClock içerisinden kod parçaçığı gönderiyorum
    /**Initializes the CPU, AHB and APB busses clocks 
    */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_USART2
                              |RCC_PERIPHCLK_I2C1|RCC_PERIPHCLK_RTC;
  PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
  PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
  PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
  PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }


tüm peripheral ların clockları aktifleniyor.
ayrıca uyandıran komut dediğiniz zaten rtc aracılığı ile oluyor.
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
uykuya burdan giriyor ve rtc interrupt olduğuna burdan devam ediyor. sizin 1,2 ve 3 diye sıralamanız paylaştığım kod ile aynı aslında
insanın içine işleyen şarkılar ;  https://soundcloud.com/reeraslan

Klein

Stm32L0 uyku modu için 10mA fevkalade yüksek bir değer.
1uA'i geçmiyor olmalı.

Boşta pininiz olmamalı.  Boşta olanlar içeriden Hi ya da Lo yapılmalı.
Kullanılan pinler ile  bağlı olduğu çevre birim arasında akım akmayacak şekilde konfigürasyon yapılmalı.
Analog portların girişinde Pull-Up veya Pull-Down  yoksa, float bırakılmamalı içeriden yapılmalı.

Mümkünse ADC çevrimi durdurulmalı.
HSI , HSE ve PLL kapatılmalı.

Sadece RTC ve MSI osilatör açık iken 1uA civarını görebilirsiniz.

Eren Eraslan

Alıntı yapılan: Klein - 23 Eylül 2017, 22:46:58
Stm32L0 uyku modu için 10mA fevkalade yüksek bir değer.
1uA'i geçmiyor olmalı.

Boşta pininiz olmamalı.  Boşta olanlar içeriden Hi ya da Lo yapılmalı.
Kullanılan pinler ile  bağlı olduğu çevre birim arasında akım akmayacak şekilde konfigürasyon yapılmalı.
Analog portların girişinde Pull-Up veya Pull-Down  yoksa, float bırakılmamalı içeriden yapılmalı.

Mümkünse ADC çevrimi durdurulmalı.
HSI , HSE ve PLL kapatılmalı.

Sadece RTC ve MSI osilatör açık iken 1uA civarını görebilirsiniz.


Hocam tüm bu dediklerinize benzer şekilde adc yi kapattım
kullandığım kullanmadığım tüm pinleri analoğa çektim. Bu ayarlamalarda 10uA e indirgeyebildim. Aksi taktirde analog yapmassam 10ma mertebesinde dolanıyor.
Onca fark sadece pinleri analog yapmam ile değişiyor. fakat problemim ondan sonrasında uart vs gibi modülleri aktifleştiremiyor oluşum. zaten indirgediğim akım seviyesi bana yetiyor
insanın içine işleyen şarkılar ;  https://soundcloud.com/reeraslan

Klein

Sadece UART mı? Uyanma sonrasında çalışmayan başka çevre birimler var mı?
UART hiç mi çalışmıyor? Baud mu farklı?  kontrol eder misiniz? SysClk ayarları yapıldıktan sonra, ClkUpdate işlemi yapılmazsa  baud doğru çıkmayabilir.
Uyandıktan sonra , debug modunda UART ayarlarını görebiliyor  musunuz?