Stm32f4 Discovery ADC sonucu lcd ye yazdırma

Başlatan Kaanx, 23 Mart 2013, 02:25:03

Kaanx

Merhabalar Stm32f4 discovery nın adc modulunu ıncelemekteyım ve yapılan cevrim sonucu gerilim degerimi 2x16 lcd de görmek istiyorum.Fakat lcd ye nasıl bu degeri nasıl gönderebilirim işin içinden cıkamadım yardım edermisiniz. ?

sseedat

bu şekilde yapabilirsin
#include "STM32F4xx.h"
#include "Delay.c"
#include "HD44780.c"

 unsigned char say[]=" ";
 unsigned char a,b,d,c;
 float x;
 uint16_t adc_val;
 float isb=0.0007;



void SystemInit(void)
{
unsigned int i;

    for (i=0;i<0x00100000;i++);          // OSC oturtma ve kurtarma rutini
    RCC->CFGR |= 0x00009400;         // AHB ve APB hizlarini max degerlere set edelim
    RCC->CR |= 0x00010000;            // HSE Xtal osc calismaya baslasin       
    while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
    RCC->PLLCFGR = 0x07405408;      // PLL katsayilarini M=8, N=336, P=2 ve Q=7 yapalim
//  RCC->PLLCFGR = 0x07402A04;     // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
    RCC->CR |= 0x01000000;            // PLL calismaya baslasin  (Rehber Sayfa 95)
    while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
//  FLASH->ACR = 0x00000705;        // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
    FLASH->ACR = 0x00000605;        // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
    RCC->CFGR |= 0x00000002;        // Sistem Clk u PLL uzerinden besleyelim
    while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
    RCC->AHB1ENR |= 0x0000000F;    // GPIO A,B,C,D clock'u aktif edelim
    
    GPIOD->MODER = 0x55000055;     // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (LEDler icin) 0..7 arasıda çıkış
    GPIOB->MODER = 0x00000500;     // GPIOB 4 ve 5 i çıkış yaptık.

    GPIOA->OSPEEDR= 0x00000000;   // GPIOD nin tum cikislarinı Max. 2 Mhz de kullanacağız.
    GPIOB->OSPEEDR= 0x00000000;	  // AYnı şey GPIOB içinde geçerli
    GPIOC->OSPEEDR= 0xFFFFFFFF;
    GPIOD->OSPEEDR= 0x00000000;

GPIOB->MODER |= 0x00000003; 
     RCC->APB2ENR|=0x00000100;  // ADC saat kaynağını aktif ettik. 
     ADC1->CR1 |=0x00000100; //  ADC scan modunda çalışacak.
     ADC1->SQR3 |= 0x00000008; // Çevrime ilk girecek kanal 8. (PB0)
     ADC1->CR2 |=0x00000003;   // AD converter'i açtık. Sürekli çevirim yapacağımızı belirttik. 
}


int main(void)
{

	 lcd_init();
	 lcd_imlec_yok();
     
ADC1->CR2 |=0x40000000; // ADC çevrimini başlattık. 


    while(1)
    { 
		if(ADC1->SR & 0x0002){
            ADC1->SR &= ~0x0002;
            adc_val = ADC1->DR;
			 x=adc_val*isb;
			 a=(int)(x);
			 b=(int)((x-a)*10) ;   d=(int)((x-a)) ;
			 c=(int)((x-a-d)*100)	;
			sprintf(say,"%u.%u%u",a,b,c);
			lcd_git(1,1);
			lcd_yaz(say);
			}
    }
}




[b][/b]
Görünmez bir mezarlıktır Zaman...

Kaanx

Hocam cok sagolun yardımınız için fakar buradaki sprintf kullanımı nasıl yapıcam ? Benım kullandıgım 2x16 lcd kodları burada
http://kaankandemir.wordpress.com/2013/02/28/stm32f4-discovery-2x16-lcd-kullanimi-2/

sseedat

sanırsam kodları ccs ile yazılmış o konuda biligim yok mallesef ama istersen lcd kütüphanelerini verebilirim.
Görünmez bir mezarlıktır Zaman...

Kaanx

Atollicte yazıldı hocam size zahmet olmazsa verebilirseniz cok memnun kalırım sizdeki kodun mantıgını kendımınınkıne uyarlamak daha az zaman kaybı saglar :)

sseedat

hd44780.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//		  LCD data Portu GPIOD
//        RS. GPIOB.4
//        E.  GPIOB.5  olarak kullanılmıştır.
//
//	      Kullanılışı;
//		  Lcd_init();         // 2x16 LCD yi kullanıma hazır hale getirir.
//		  Lcd_Veri();         // Lcd ye KOmut göndermek için kullanılır.
//		  Lcd_Git(1,2);       // Lcd nin 1. satırının 2. sütununa imleci konumlandırır.
//		  Lcd_Yaz("Merhaba"); // Lcd ye Merhaba Stringini gönderir.
//                Yaz();              // Bu kullanılmayacak.
//                Lcd_Sil();          // Lcd yi silmek için kullanılır.
//		  Lcd_Imlec_Var();	  // İmleç YanSön Moduna sokar.
//		  Lcd_Imlec_Yok();	  // İmleç i yok eder.
//
//
#include "hd44780.h"



void lcd_init(void)
{

   // GPIOD->MODER = 0x55000055;     // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (LEDler icin) 0..7 arasıda çıkış
   // GPIOB->MODER = 0x00000500;     // GPIOB 4 ve 5 i çıkış yaptık.

   // GPIOD->OSPEEDR= 0x00000000;   // GPIOD nin tum cikislarinı Max. 2 Mhz de kullanacağız.
   // GPIOB->OSPEEDR= 0x00000000;	  // AYnı şey GPIOB içinde geçerli

    GPIO_B(4)=0;	GPIO_B(5)=0;  //	 Genel
    GPIOD->ODR= 0x00000000;		  //	 Temizlik

    delayms(20);
	  GPIO_B(5)=1;
    lcd_veri(0x03); // Lcd Reset
    lcd_sil();
    lcd_veri(40);   // 2 satır kullanacağımızı yazdık
    lcd_veri(15);   // Display i aç
    lcd_veri(0x06); // Kursör 1 artan modda.
    lcd_sil();	    // Lcd yi temizle
	lcd_veri(128);

}

void lcd_veri(unsigned char veri)
{
 	GPIO_B(4)=0;
	GPIO_B(5)=1;
	delayms(10);
    GPIOD->ODR =(veri & 0xF0)>>4;   ///Delay_ms(1); 
    GPIO_B(5)=0; 
	 delayms(1); 
	  GPIO_B(5)=1;	  delayms(1); 
	  GPIOD->ODR=((veri & 0x0F));	 //  Delay_ms(1); 
	  GPIO_B(5)=0;
	  delayms(10);
}

void lcd_git(unsigned char p1,unsigned char p2)
{
    if (p1==1)
	{
	 lcd_veri(0x80+(p2-1));
	 //lcd_veri(16);
	}
    else  
	{
	    lcd_veri(0xC0+(p2-1));
		 // lcd_veri(16);
		}
}
/*void lcd_ggit(unsigned char h1,unsigned char h2)
{
   
}
	*/

void lcd_yaz(unsigned char *lcd_data)
{
    delayms(10);
    while(*lcd_data)  yaz(*lcd_data++);
}

void yaz(unsigned  dat)
{
 	GPIO_B(4)=1; 
	GPIO_B(5)=1;
	 delayms(10);
    GPIOD->ODR = (dat & 0xF0)>>4; // Delay_ms(1); 
    GPIO_B(5)=0;
	 delayms(1); 
	 GPIO_B(5)=1;   delayms(1); 
	 GPIOD->ODR = ((dat & 0x0F)); //Delay_ms(1); 
	 GPIO_B(5)=0;
}
    
void lcd_sil(void)
{
    lcd_veri(1);
    delayms(10);
}

void lcd_imlec_yok(void)
{
    lcd_veri(0x0C);
    delayms(10);
}

void lcd_imlec_var(void)
{
 	lcd_veri(0x0F);
    delayms(10);
}



hd44780.h
#define GPIO_A(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOA->ODR) << 5) + ((b) << 2)))
#define GPIO_B(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOB->ODR) << 5) + ((b) << 2)))
#define GPIO_C(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOC->ODR) << 5) + ((b) << 2)))
#define GPIO_D(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOD->ODR) << 5) + ((b) << 2)))
#define GPIO_E(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOE->ODR) << 5) + ((b) << 2)))
#define GPIO_F(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOF->ODR) << 5) + ((b) << 2)))
#define GPIO_G(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOG->ODR) << 5) + ((b) << 2)))
#define GPIO_I(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOI->ODR) << 5) + ((b) << 2)))

extern void lcd_init(void);
extern void lcd_veri(unsigned char veri);
extern void lcd_git(unsigned char p1,unsigned char p2);
extern void yaz(unsigned dat);
extern void lcd_yaz(unsigned char *lcd_data);
//void lcd_ggit(unsigned char h1,unsigned char h2)
extern void lcd_sil(void);
extern void lcd_imlec_var(void);
extern void lcd_imlec_yok(void);


Delay.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//		 Kullanılışı;
//		 Delay_ms(100);   // 100 msn Bekle.
//		 Delay_us(100);   // 100 usn Bekle. 
//		 Not CPU OSC = 168 mhz - 210 MIPS

#include "Delay.h"

void delayms(unsigned long Bekle)
{
    Bekle = Bekle * 21008;	// mSn ye ye çevirdik. OSC 168Mhz de uçuyor.
    while(Bekle>0){Bekle--;}
}

void delayus(unsigned long Bekle)
{
    Bekle = Bekle * 21;	// uSn ye ye çevirdik. OSC 168Mhz de uçuyor.
    while(Bekle>0){Bekle--;}
}


Delay.h
extern void delayms(unsigned long Bekle);
extern void delayus(unsigned long Bekle);

Görünmez bir mezarlıktır Zaman...

Kaanx

Hocam sagolasınız peki bir sorum daha olucak size burada sprintf kullanımı hakkında bilgi verebilirmisiniz acaba ?
while(1)
	  {
		  /*0-3.3volt arası cevrım adımı ayarı*/

		  ADC3ConvertedVoltage=ADC3ConvertedValue*3300/0xFFF;
		  LCD_LINE(1);
		  LCD_STR("DEGER");
		  sprintf(ADC3ConvertedVoltage,"%u",ADC3ConvertedValue);
}


gibi yazarsam buradaki degeri direk lcd ye mi gönderiyor sprintf in calısması hakkında bilgim yok ?

sseedat

veri yollarken sprintf kulanmadan da verinin ascii kodu şeklinde göndererek işlem yapabilirsin.
örmek olarak
    veri(okunanVoltaj/1000+48);
    veri((okunanVoltaj%1000)/100+48);
    veri('.');
    veri((okunanVoltaj%100)/10+48);
    veri(okunanVoltaj%10+48);
Görünmez bir mezarlıktır Zaman...

Kaanx

Alıntı yapılan: sseedat - 23 Mart 2013, 03:12:44
veri yollarken sprintf kulanmadan da verinin ascii kodu şeklinde göndererek işlem yapabilirsin.
örmek olarak
    veri(okunanVoltaj/1000+48);
    veri((okunanVoltaj%1000)/100+48);
    veri('.');
    veri((okunanVoltaj%100)/10+48);
    veri(okunanVoltaj%10+48);


void integer_yaz(unsigned int deger,char flag)
{
  LCD_DATA( deger/1000+48);
  LCD_DATA((deger%1000)/100+48);
  if(flag==1) lcd_putch('.');
  LCD_DATA((deger%100)/10+48);
  LCD_DATA((deger)%10+48);
}


void deger_goster(unsigned int ham)
{
  unsigned int volt=0;
 
  volt=(float)(ham/2.87);
 
  lcd_goto(1,1);
  lcd_puts("10 Bit  = ");
  integer_yaz(ADC10MEM,0);
 
  lcd_goto(2,1);
  lcd_puts("Gerilim = ");
  integer_yaz(volt,1);
}
   

msp430 ile yaptıgım calısmayı yapmaya calısıyorum kısacası hocam. Burada ADC10mem Cevrım sonucunun hafızada tutuldugu yer ve ben buradan degeri alıp hesaplayıp yazdırıyordum fakat stm32f4 de bu dönusum degerm hangi registerda bilmiyorum cunku library kullanıyorum .

sseedat

adc_val = ADC1->DR;

değerleri ADC1->DR tutar.bu değeri de adc_val değişkenimize aktarıp işlemlere sokuyoruz.
Görünmez bir mezarlıktır Zaman...

Kaanx

Ben adc dr adresi olarak söyle bı tanım yaptım
#define ADC3_DR_ADDRESS     ((uint32_t)0x4001224C)
daha sonra uint olarak
uint16_t ADC3ConvertedValue=0;
uint32_t ADC3ConvertedVoltage=0; yazdım ve hesaplamayı

ADC3ConvertedVoltage=ADC3ConvertedValue*3300/0xFFF;    olarak yaptım hocam burada ben ADC3ConvertedVoltage=ADC3->DR desem direk nasıl olur