STM32F407 Cortex M4 şamataları

Başlatan bunalmis, 16 Ekim 2011, 17:14:50

muhittin_kaplan

bunalmış hocam verdiğin usart ile denemeler yapıyordum
char (8bit) bilgiden daha büyük (örn 16bit) nasıl gönderebilirim

Klein

#751
Alıntı yapılan: muhittin_kaplan - 13 Ocak 2012, 22:00:06
peki bu usart3 den byte byte bilgi gönderirken gönderilen bilgiler arasında nekadar beklemeliyim? yada alıp işlem yaptığını nereden anlarım ?
Usart ile bilgi gönderirken bilgiler arasına sabit beklemeler koymak yerine , TX tamponunun boşalmasını beklemek daha daha doğru olur.
Usart bayraklarını incelemedim. Ama SPI ile olan tecrübelerden, TX tamponundaki bilgi donanıma aktarıldığında, donanımın işini bitirmesi beklenmeden bayrağın çekileceğini tahmin ediyorum.
Eğer öyle ise, eğer RS485 gibi bir sistemi alma moduna geçirecekseniz , sadece son verinin sonuna bir bekleme konulabilir.
Bu değeri sabit bir sayı yerine baud hızına göre değişen bir değer yapmak programı daha esnek yapar.
Eğer 8 bit data, 1 stop , parite yok şeklinde bir konfigürasyon varsa.  Start+Data+Stop = 10 bit veri gönderilecek demektir.
TX tamponu boşaldıktan sonra bu kadar bitin gönderilmesine yetecek kadar bir süre beklenmesi uygun olacaktır.
Bu süre şöyle hesaplanabilir.
(Start+Data+Stop+Parite)/baud
sonuç saniye cinsindendir. 


Ekleme:
Şimdi baktım. TXE bayrağı dediğim gibi çalışıyor. TC bayrağı ise  gönderim tamamen bittiğinde çekliyor.
Veri aralarında TXE  veri gönderimi tamamen bittiğinde TC bayrağı kullanılabilir.

mcan

Program Size: Code=15088 RO-data=29592 RW-data=56 ZI-data=10316 

Şimdi ben kaç kb ram kaç kb rom kullanmışım?

Larkin

Selamun aleykum arkadaşlar, heveslendim stm32f4 satın aldım ve ADC tek kanal 1024 bit okuma yapmak istiyorum. sağdan soldan birkaç kod buldum ama coğu sorunlu ve uzun bir kod yapısı var. acaba basit bir örnek yazarmısınız. :(

fryrmnd

uzun dediğiniz kodları biz yazsak register bazında kodlama ile anlayabilicekmisiniz. yani yanlış anlamayın da program çok basit olmayacaktır. altı üstü 10 bit ADC diyebilirsiniz tabi ama anlamak istiyorsanız,kodda nerede ne yapılmış bilmek istiyorsanız datasheeti kurcalamanız gerekicek. ben 1-2 deneme yapıtım henüz sonuç alamadım. umarım yardım eden olur. ama siz yazsaydınız ,şu kodu çalıştıramadım, yada şu register ne iş yapıyor bu programda deseydiniz daha çok yardım eden olabilir.

hyperalika

Bunalmis hocam sizin yazdığınız uart3 modülünü kullanarak rs232 bluetooth bağladım telefonada bir terminal programı kurdum. Ama ne telefona veri göndere biliyorum nede stm32f4 e mesela telefondan A verisi geldiğinde GPIOD->ODR 0x00001000 deki led yansın gibi ama beceremedim hocam yardımını bekliyorum. Elimdeki bluetooth modülü http://www.goodluckbuy.com/serial-bluetooth-rf-transceiver-module-rs232-w-backplane-enable-and-state-pin-1.html bu üründür. Sadece RX-TX'e TX-RX'e ve VCC - GND Bacakları bağlı.
#include "STM32F4xx.h"
unsigned char WAdr,RAdr;
char RxBuf[128];
/*********************************************************************************
CPU frekansi 168Mhz
AHB frekansi 84 Mhz
APB frekansi 42 Mhz
*********************************************************************************/
void SystemInit()
{
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 = 0x07402A04;      // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim   168 Mhz
RCC->CR |= 0x01000000;          // PLL calismaya baslasin  (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
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 |= 0x0000001F;     // GPIO A,B,C,D,E clock'u aktif edelim
GPIOD->MODER  = 0x55550000;     // GPIOD nin 15, 14, 13, 12, 11, 10, 9, 8 pinleri cikis tanimlandi (LEDler icin)
GPIOD->OSPEEDR= 0xFFFFFFFF;     // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
}
/*********************************************************************************
USART3 modulunu kullanarak asenkron haberlesme (Hata kontrolu yapilmiyor)
*********************************************************************************/
void USART3_IRQHandler()
{
volatile int Sts;
Sts=USART3->SR;
RxBuf[WAdr]=USART3->DR;
WAdr=(WAdr+1)&0x7F;
}
void UsartInit()
{
WAdr=0;RAdr=0;
// USART3 MODULUNU AKTIF HALE GETIRELIM
RCC->APB1ENR|=0x00040000;  // USART3 Clk Enable (Rehber Sayfa 113)
RCC->APB1RSTR|=0x00040000;  // USART3 Resetlendi
GPIOB->AFR[1]=0x07777700;  // PB10..PB14 pinleri USART3 ile alakalandirildi (Hard Sayfa 49)
GPIOB->MODER|=0x2AA00000;  // GPIOB 10..14 icin alternatif fonksiyon tanimi (Rehber Sayfa 148)
// USART3 MODULUNU AYARLAYALIM  // 1 Start, 8 Data, 1 Stop, No parity (Default degerler)
RCC->APB1RSTR&=~0x00040000;  // USART3 Reseti kaldiralim
//      USART3->SR&=~0X03FF;   // Status registeri silelim
USART3->BRR=0X1112;    // 9600 Baud
USART3->CR1|=0x0000202C;  // USART3 enable
NVIC->ISER[1]|=0x80;         // NVIC da USART3 interrupta izin verelim
}
void SendChar(char Tx)
{
while(!(USART3->SR&0x80));  // TX Buffer dolu ise bekle (Rehber Sayfa 646)
USART3->DR=Tx;
}
void SendTxt(char *Adr)
{
while(*Adr)
{
SendChar(*Adr);
Adr++;
}
}
char DataReady()
{
return(WAdr-RAdr);
}
char ReadChar()
{
char Dat;
Dat=RxBuf[RAdr];
RAdr=(RAdr+1)&0x7F;
return(Dat);
}
// Rx ve TX pinlerini (GPIOB10 ve GPIOB11) birbirine baglarsaniz gonderdiginiz datalar geri gelecektir
int main()
{
int i;
UsartInit();
SendTxt("Mcu-Turkey");
SendChar(' ');
SendTxt("Bunalmis");
for(i=0;i<0x1000000;i++);         // Laf olsun diye bekledik
while(DataReady()) ReadChar();
while(1);
}

Larkin

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"
#include "stm324xg_eval.h"
#include "stm324xg_eval_lcd.h"
#include <stdio.h>

/** @addtogroup STM32F4xx_StdPeriph_Examples
  * @{
  */

/** @addtogroup ADC_ADC3_DMA
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* used to display the ADC converted value on LCD */
#define PRINT_ON_LCD
  /* if you are not using the LCD, you can monitor the converted value by adding
     the variable "ADC3ConvertedValue" to the debugger watch window */

#define ADC3_DR_ADDRESS    ((uint32_t)0x4001224C)

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
__IO uint16_t ADC3ConvertedValue = 0;
__IO uint32_t ADC3ConvertedVoltage = 0;

/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
void ADC3_CH7_DMA_Config(void);

#ifdef PRINT_ON_LCD
void Display_Init(void);
void Display(void);
#endif /* PRINT_ON_LCD */

/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void)
{
  /*!< At this stage the microcontroller clock setting is already configured,
       this is done through SystemInit() function which is called from startup
       file (startup_stm32f4xx.s) before to branch to application main.
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f4xx.c file
     */
#ifdef PRINT_ON_LCD
  /* LCD Display init  */
  Display_Init();
#endif

  /* ADC3 configuration *******************************************************/
  /*  - Enable peripheral clocks                                              */
  /*  - DMA2_Stream0 channel2 configuration                                   */
  /*  - Configure ADC Channel7 pin as analog input                            */
  /*  - Configure ADC3 Channel7                                               */
  ADC3_CH7_DMA_Config();

  /* Start ADC3 Software Conversion */
  ADC_SoftwareStartConv(ADC3);

  while (1)
  {
    ADC3ConvertedVoltage = ADC3ConvertedValue *3300/0xFFF;
#ifdef PRINT_ON_LCD
  /* Display ADC3 converted value on LCD */
    Display();
#endif
  }
}


/**
  * @brief  ADC3 channel07 with DMA configuration
  * @param  None
  * @retval None
  */
void ADC3_CH7_DMA_Config(void)
{
  ADC_InitTypeDef       ADC_InitStructure;
  ADC_CommonInitTypeDef ADC_CommonInitStructure;
  DMA_InitTypeDef       DMA_InitStructure;
  GPIO_InitTypeDef      GPIO_InitStructure;

  /* Enable ADC3, DMA2 and GPIO clocks ****************************************/
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOF, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);

  /* DMA2 Stream0 channel2 configuration **************************************/
  DMA_InitStructure.DMA_Channel = DMA_Channel_2; 
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC3_DR_ADDRESS;
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC3ConvertedValue;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  DMA_InitStructure.DMA_BufferSize = 1;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  DMA_Init(DMA2_Stream0, &DMA_InitStructure);
  DMA_Cmd(DMA2_Stream0, ENABLE);

  /* Configure ADC3 Channel7 pin as analog input ******************************/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  GPIO_Init(GPIOF, &GPIO_InitStructure);

  /* ADC Common Init **********************************************************/
  ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
  ADC_CommonInit(&ADC_CommonInitStructure);

  /* ADC3 Init ****************************************************************/
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfConversion = 1;
  ADC_Init(ADC3, &ADC_InitStructure);

  /* ADC3 regular channel7 configuration *************************************/
  ADC_RegularChannelConfig(ADC3, ADC_Channel_7, 1, ADC_SampleTime_3Cycles);

/* Enable DMA request after last transfer (Single-ADC mode) */
  ADC_DMARequestAfterLastTransferCmd(ADC3, ENABLE);

  /* Enable ADC3 DMA */
  ADC_DMACmd(ADC3, ENABLE);

  /* Enable ADC3 */
  ADC_Cmd(ADC3, ENABLE);
}

#ifdef PRINT_ON_LCD
/**
  * @brief  Display ADC converted value on LCD
  * @param  None
  * @retval None
  */
void Display(void)
{
  uint32_t v=0,mv=0;
  uint8_t text[50];

  v=(ADC3ConvertedVoltage)/1000;
  mv = (ADC3ConvertedVoltage%1000)/100;
  sprintf((char*)text,"   ADC = %d,%d V   ",v,mv);
  LCD_DisplayStringLine(LINE(6),text);
}

/**
  * @brief  Display Init (LCD)
  * @param  None
  * @retval None
  */
void Display_Init(void)
{
  /* Initialize the LCD */
  STM324xG_LCD_Init();

  /* Clear the LCD */
  LCD_Clear(White);

  /* Set the LCD Text size */
  LCD_SetFont(&Font8x12);

  /* Set the LCD Back Color and Text Color*/
  LCD_SetBackColor(Blue);
  LCD_SetTextColor(White);

  /* Display */
  LCD_DisplayStringLine(LINE(0x13), " ADC conversion w/ DMA transfer example ");

  /* Set the LCD Text size */
  LCD_SetFont(&Font16x24);

  /* Display */
  LCD_DisplayStringLine(LINE(0), "ADC Ch7 Conv @2.4Msps");


  /* Set the LCD Back Color and Text Color*/
  LCD_SetBackColor(White);
  LCD_SetTextColor(Blue);

  /* Display */
  LCD_DisplayStringLine(LINE(2),"  Turn RV1(PF.09)    ");
  LCD_DisplayStringLine(LINE(4),"   Potentiometer     ");
}
#endif /* PRINT_ON_LCD */

#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif



kod bu, header dosyalarını da ekledim fakat derlediğimde 30 tane hata verdi
hatalardan birisi de HalfWord undefined diyor (tanımlı değilmiş) lcd dosyası lazım değil dedim kodları sadeleştirdim yine değişen birşey olmadı nerde hata yapıyorum anlamadım

kaynak:http://tech.munts.com/MCU/Frameworks/ARM/stm32f4/libs/STM32F4xx_DSP_StdPeriph_Lib_V1.0.0/Project/STM32F4xx_StdPeriph_Examples/ADC/ADC3_DMA/

muhittin_kaplan

Yeri Gelmişken SendTXT nasıl çalışıyor hocam.

fryrmnd

larkin hocam readme dosyasını okudunuz mu. koskoca st çalışmayan kod koymaz sanırım.

Hardware and Software environment

  - This example runs on STM32F4xx Devices.
 
  - This example has been tested with STM324xG-EVAL RevB and can be easily tailored
    to any other development board.

  - STM324xG-EVAL Set-up
    - Use the Potentiometer (RV1) of the Eval board (connected to PF.09).

In order to make the program work, you must do the following :
- Copy all source files from this example folder to the template folder under
   Project\STM32F4xx_StdPeriph_Templates
- Open your preferred toolchain
- Rebuild all files and load your image into target memory
- Run the example

gibi uyarılar var. gerekli ayarları yaparsanız çalışcaktır sanırım.




Klein

Alıntı yapılan: muhittin_kaplan - 14 Ocak 2012, 17:41:02
Yeri Gelmişken SendTXT nasıl çalışıyor hocam.
Sorduğunuz sorular yoruma dayalı veya doğrudan kişiyi ilgilendiren sorular olmadığı için; doğrudan @bunalmıs'a sorulmuş olsa da gördükçe yanıtlamaya çalışıyorum. Umarım kızmaz.

void SendTxt(char *Adr)
{
while(*Adr)
{
SendChar(*Adr);
Adr++;
}
}

Eğer soru koddaki pointerler ile ilgili değilse:
C de metinler (TXT) sıfır sonludur.  bir pointer veya array'a "merhaba dunya" yazdığınızda  siz metnin sonuna 0 koymasanız da derleyicilerin çoğu otomatik olarak metnin sonuna 0 sayısını ('0' karakteri değil) koyar.  Biz de metnin sonuna gelip gelmediğimizi bilmek için bu sayıyı kontrol ederiz.

şart cümlelerinde eğer kontrol edeceğimiz cümleye '>' , '<' , '==' gibi karşılaştırma operatörü koymamışsak, eğer doğruysa anlamına gelir. Eğer şarta konu olan değer bir sayı ise 0'dan farklı hangi değeri alırsa alsın "doğru" değeri gönderir

while(*Adr) döngüsünde yapılan da budur. Adr işaretçisi ile gösterilen hücrenin değeri 0 dan farklı olduğu sürece dönmeye devam edecektir.
SendChar(*Adr); burada yapılan belli. SendChar(..) fonksiyonu nun parametresi char tipinde. parametre bir işaretçi olmadığı için o fonksiyonu doğrudan değerin kendisi ile çağırmak gerekiyor. Burada yapılan iş de Adr işaretçisinin gösterdiği adresin içeriğini doğrudan SendChar(...) fonksiyonuna parametre olarak geçmek.
Adr++; Burada da yapılan iş açık. pointer değeri 1 artırılarak , bir sonraki adresi göstermesi sağlanıyor.

Eğer soru bu anlattıklarım ile ilgili değil , işaretçiler ve kullanımları ile ilgili ise:
Pointer konusu yanlış hatırlamıyorsam "Basic kullanıcılarını C'ye alaıştırma" gibi bir başlıkta konuşulmuştu. Orada daha fazla detay olabilir.


muhittin_kaplan

#760
C de metinler (TXT) sıfır sonludur
Anahtar Kelime Bu hocam. Sıfırdan Nastınız Null değer mi ? (/n)


--ekleme--
SendTXT ("Mcu-Turkey") ile ram a sırayla M C U gibi karakter katarlarınının char değerini ekliyor. (Nereye Nasıl Ekliyor ?)
SendTXT (Char *A) ilede bu her bir karakterin adresini veriyor.
SendChar gösterilen adresteki CHAR değeri gönderiyor

Doğrumu anlamışım ?

muhittin_kaplan

(USART_DR) register değeri 32bit görünüyor. neden Char Gönderiyoruz ?

Klein

Evet null değeri.

SendTXT ("Mcu-Turkey") ile ram a sırayla M C U gibi karakter katarlarınının char değerini ekliyor. (Nereye Nasıl Ekliyor ?)

Fonksiyona bu şekilde derleme anında belli olan bir parametre değeri verilmişse, derleyici derleme esnasında bu değeri rom'da bir yere yazar. fonksiyonu çağırdığımızda Adr işaretçisine rom'daki bu adresi atar. artık işaretçimizin gösterdiği adres burasıdır.

SendChar(...)  fonksiyonunda adres ile işimiz yok. Çünkü bu fonksiyonun parametresi işaretçi değil. Bu yüzden *Adr ile elde ettiğimiz değeri doğrudan bu fonksiyona parametre olarak geçiyoruz.
Şöyle bir akış gerçekleşiyor.
Burada r0,r1,r2 gibi tanımlamalar var. bunlar gerçekte mcu içerisindeki registerleri ifade ediyor. bir çeşit geçici alanlar. sürekli kullanmayacağı veriler üzerinde işlem yaparken bunlara veriyi atıyor, bu veri üzerinde işlem yapıyor. başka bir işleme geçtiğinde buraya başka bir veri atıyor. Bir çeşit yaz boz tahtası.

SendTXT("Mcu-Turkey")  fonksiyonu çağııldı.
fonksiyonun adresine git.
r0' a "Mcu-Turkey" metninin bulunduğu yerin adresini at. örn. 0x200;

while(*Adr)
r1'e   0x200 adresinde bulunan karakteri at.
r2'ye 0 değerini at.
r1 ile r2'yi karşılaştır. eğer aynı değilse yoluna devam et.

SendChar(*Adr);
r1'e  0x200 adresindeki  karakteri at.
sendchar(..) fonksiyonunu r1 ile çağır. SendChar(r1); demek gibi. dikkat et burada gerçekten değer ile çağırıyoruz. Adres yok. 

Adr++;
r0 içeriğini 1 artır.   r0 =r0+1 gibi.  artık r0'ın değeri 0x0201

başa dön.
Bundan sonra 0x200 yerine 0x2001, 0x2002 gibi gidecek.


Klein

Alıntı yapılan: muhittin_kaplan - 14 Ocak 2012, 19:40:36
(USART_DR) register değeri 32bit görünüyor. neden Char Gönderiyoruz ?
Char gönderebiliyor olmamızın sebebi, register yapısından veya işlemcinin yeteklerinden kaynaklı bir durum değil.
uart,usart haberleşme protokolünün yapısından kaynaklı. 
Bu protokolde her bir pakette ancak 7,8 veya 9 bit veri olabiliyor. Biri çıkıp ben usart_32 diye bir protokol yazdım derse ve bunu da bir endüstri standartı  haline getirebilirse, o zaman üreticiler bu protokole uygun donanımlar veya yazılımlar yapar. Ancak şimdilik elimizdeki bu.

muhittin_kaplan

Hocam Aslında Birçok Sorunun cevabını Biliyorum.
232 Standardına Ne olduğunu Örneğin. Ama Basic den kalma Bir alışkanlık var. Muhittin i Gönder dediğimizde Karşıya Muhittin Gönderir. İçeriği nedir ilgilenmezsin.
r0 lar r1 8051 de de kullanıyordum. ama asm olunca ve burada C ile yazınca hiç r0 lar r1 ler gelmiyor aklımıza.