STM32F407 donanımsal olarak girişi başka çıkışa yansıtmak

Başlatan tekosis, 08 Ağustos 2015, 19:40:34

tekosis

selamün aleyküm. elimde stm32f407zg var. bu entegrenin herhangi bir pini giriş olarak ayarlanacak. bu giriş "1" ise pb15 "1",  yine bu giriş "0" ise pb15 "0" olacak. ancak bu işlem yazılımsal değil donanımsal olarak yapılmalı. bu işi yapabilmem için DMA gibi bir donanım var mı, DMA kullanılabilir mi?
İlim ilim bilmektir, ilim kendin bilmektir, sen kendin bilmezsin, bu nice okumaktır.

z

Mumkun de ne gerek var?

Donanımsal girişin gene giriş kalsın.

Bir kablo ile giriş pinini doğrudan PB15'in bağlanacağı yere bağla. PB15 de sana kalsın.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

tekosis

hocam algılamak istediğim giriş farklı frekanslarda olabilen bir kare dalga. çıkış ise haberleşme pini. normalde bu haberleşme pinini kullanırken bazen de haberleşmeden sonra buraya o kare dalga sinyali aktarmam gerekecek.
İlim ilim bilmektir, ilim kendin bilmektir, sen kendin bilmezsin, bu nice okumaktır.

Gökhan BEKEN

Dma ile yapmak için bir tetikleyici gerekiyor. Dma ile yaptığınızda giriş olan portu hedef olan porta yazarsınız en fazla. O da işinize gelmez. Çünkü siz bir biti başka bir bit ile değiştirmek istiyorsunuz, bütün bitleri değil. İlla kod ile yapmanız gerekiyorsa giriş olan pine ext. interrupt kurmalısınız. Ama z nin dediği gibi yapmanız en kestirme yol.
Özel mesaj okumuyorum, lütfen göndermeyin.

Klein

Alıntı yapılan: z - 08 Ağustos 2015, 20:02:51
Mumkun de ne gerek var?

Donanımsal girişin gene giriş kalsın.

Bir kablo ile giriş pinini doğrudan PB15'in bağlanacağı yere bağla. PB15 de sana kalsın.
Nasıl mümkün hocam?
STM32 hakkında tüm bildiklerimi gözden geçirmem gerekebilir. Bilmediğim bir şey mi var?

STM32F4xx serisi
PERIPH-PERIPH  aktarım yapamıyor.
GPIO'lar DMA tetikleyicisi olarak kullanılamıyor,
GPIO'lar DMA kanallarına bile bağlanamıyor ( Belki memory  adresi gibi yazılıp kandırılabilir ama emin değilim)

z

Yapılacabileceği kafama yattığı için öyle dedim. Katalogtan teyid etmedim.

Port dan port porta DMA transfer edebiliyorsa geriye DMA tetikleme kaynağının seçimi kalıyor.

Onun için de illaki ext pin ile uyarılan bir birim vardır. Timer vs gibi.


Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Gökhan BEKEN

Gpio lar neden bağlanamasın ki? Ben paralel port uygulaması yapmıştım. Dma ile yapmıştım yanlış hatırlamıyorsam. Timer kurup timerin tetiklemesini gpio ya vermiştim.
Özel mesaj okumuyorum, lütfen göndermeyin.

Klein

STM32F4xx serisinde Periph-toPeriph aktarım yok.  GPIO'lardan tetikleme de yok.
Memory-to-memory  aktarım seçip memory adresi olarak GPIO IDR ve ODR adresleri verilirse belki olabilir. Ama DMA'ya bu adresi verebiliyor muyuz denemedim hiç.
Olsa bile Yne de harici tetikleme ihtiyacı duyulur.

Gökhan BEKEN

#8
@Klein hocam dma'ya adres olarak gpio verebiliyorsunuz, neden verilmediğini düşündünüz anlamadım. Dma'yı tetikleme problemi var sadece, onu da timer ile tetikliyorsunuz, timer'ın interrupt vermesini ise gpio değişimine bağlayabiliyorsunuz.

Timer'ı bu modda kullanabilmek için örnek init fonksiyonu:

void TIM1_Configuration(void)
{
    GPIO_InitTypeDef   GPIO_InitStructure;
    TIM_ICInitTypeDef  TIM_ICInitStructure;
 
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);  /* TIM1 clock enable */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
 
  /* TIM1 channel 1 pin (PA8) configuration */
  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_8;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	//GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_DOWN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
 
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_TIM1); // PB3 TIM1_CH1
 
  TIM_ICInitStructure.TIM_Channel     = TIM_Channel_1;
  TIM_ICInitStructure.TIM_ICPolarity  = TIM_ICPolarity_BothEdge;//TIM_ICPolarity_Rising;
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  TIM_ICInitStructure.TIM_ICFilter    = 0x0;
  TIM_ICInit(TIM1, &TIM_ICInitStructure);
 
    TIM_CtrlPWMOutputs(TIM1, ENABLE);               /* TIM Main Inputs/Output Enable    */
  TIM_Cmd(TIM1, ENABLE);                  /* TIM enable counter               */
  TIM_DMACmd(TIM1, TIM_DMA_CC1, ENABLE ); /* Enable TIM1_CC1 DMA Requests     */
}


dma initi:
void DMA2_Configuration(void)
{


  NVIC_InitTypeDef NVIC_InitStructure;
 
  /* Enable the DMA Stream IRQ Channel */
  NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream6_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

    DMA_InitTypeDef  DMA_InitStructure;
 
    /* Enable the DMA clock */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
 
    /* Configure the DMA Stream */
    DMA_Cmd(DMA2_Stream6, DISABLE);
    DMA_DeInit(DMA2_Stream6);
 
  /* Set the parameters to be configured */
  DMA_InitStructure.DMA_Channel = DMA_Channel_0;
  DMA_InitStructure.DMA_PeripheralBaseAddr = (unsigned int)&GPIOC->IDR; //(uint32_t)&GPIOA->IDR;  /* Read fron GPIO input data register */
  DMA_InitStructure.DMA_Memory0BaseAddr    = (unsigned int)&GPIO_DATA[0]; /* Send the data to the  RAM buffer */
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
    DMA_InitStructure.DMA_BufferSize = BufferSize;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    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_Stream6, &DMA_InitStructure);
 
  /* Enable DMA Transfer Complete interrupt */
  DMA_ITConfig(DMA2_Stream6, DMA_IT_TC, ENABLE);
 
    DMA_Cmd(DMA2_Stream6, ENABLE);
 

}


Bu da dma kesmesi:

void DMA2_Stream6_IRQHandler(void) // 2 Hz
{

  if (DMA_GetITStatus(DMA2_Stream6, DMA_IT_TCIF6))
  {
	DMA_ClearITPendingBit(DMA2_Stream6, DMA_IT_TCIF6);
 
	//kullanıcının yapacağı özel işlemler burda yapılmalı, veya main fonksiyonunda DMA_DolduFlag değişkeni kontrol edilmeli
	DMA_DolduFlag=1;
  }
}
Özel mesaj okumuyorum, lütfen göndermeyin.

Klein

Verilmediğini düşünmedim. DMA'nın bus matrisini incelemediğim ve daha önce GPIO adresini vermeyi denemediğim için olur ya da olmaz şeklinde kesin yargı belitmekten kaçındım.

yamak

Alıntı yapılan: Gökhan BEKEN - 09 Ağustos 2015, 00:51:38
@Klein hocam dma'ya adres olarak gpio verebiliyorsunuz, neden verilmediğini düşündünüz anlamadım. Dma'yı tetikleme problemi var sadece, onu da timer ile tetikliyorsunuz, timer'ın interrupt vermesini ise gpio değişimine bağlayabiliyorsunuz.

Timer'ı bu modda kullanabilmek için örnek init fonksiyonu:

void TIM1_Configuration(void)
{
    GPIO_InitTypeDef   GPIO_InitStructure;
    TIM_ICInitTypeDef  TIM_ICInitStructure;
 
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);  /* TIM1 clock enable */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
 
  /* TIM1 channel 1 pin (PA8) configuration */
  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_8;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	//GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_DOWN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
 
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_TIM1); // PB3 TIM1_CH1
 
  TIM_ICInitStructure.TIM_Channel     = TIM_Channel_1;
  TIM_ICInitStructure.TIM_ICPolarity  = TIM_ICPolarity_BothEdge;//TIM_ICPolarity_Rising;
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  TIM_ICInitStructure.TIM_ICFilter    = 0x0;
  TIM_ICInit(TIM1, &TIM_ICInitStructure);
 
    TIM_CtrlPWMOutputs(TIM1, ENABLE);               /* TIM Main Inputs/Output Enable    */
  TIM_Cmd(TIM1, ENABLE);                  /* TIM enable counter               */
  TIM_DMACmd(TIM1, TIM_DMA_CC1, ENABLE ); /* Enable TIM1_CC1 DMA Requests     */
}


dma initi:
void DMA2_Configuration(void)
{


  NVIC_InitTypeDef NVIC_InitStructure;
 
  /* Enable the DMA Stream IRQ Channel */
  NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream6_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

    DMA_InitTypeDef  DMA_InitStructure;
 
    /* Enable the DMA clock */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
 
    /* Configure the DMA Stream */
    DMA_Cmd(DMA2_Stream6, DISABLE);
    DMA_DeInit(DMA2_Stream6);
 
  /* Set the parameters to be configured */
  DMA_InitStructure.DMA_Channel = DMA_Channel_0;
  DMA_InitStructure.DMA_PeripheralBaseAddr = (unsigned int)&GPIOC->IDR; //(uint32_t)&GPIOA->IDR;  /* Read fron GPIO input data register */
  DMA_InitStructure.DMA_Memory0BaseAddr    = (unsigned int)&GPIO_DATA[0]; /* Send the data to the  RAM buffer */
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
    DMA_InitStructure.DMA_BufferSize = BufferSize;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    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_Stream6, &DMA_InitStructure);
 
  /* Enable DMA Transfer Complete interrupt */
  DMA_ITConfig(DMA2_Stream6, DMA_IT_TC, ENABLE);
 
    DMA_Cmd(DMA2_Stream6, ENABLE);
 

}


Bu da dma kesmesi:

void DMA2_Stream6_IRQHandler(void) // 2 Hz
{

  if (DMA_GetITStatus(DMA2_Stream6, DMA_IT_TCIF6))
  {
	DMA_ClearITPendingBit(DMA2_Stream6, DMA_IT_TCIF6);
 
	//kullanıcının yapacağı özel işlemler burda yapılmalı, veya main fonksiyonunda DMA_DolduFlag değişkeni kontrol edilmeli
	DMA_DolduFlag=1;
  }
}

Burdaki aktarım Peripheral to peripheral değil ki.Peripheral to Memory.Anladığımı kadarıyla @Klein'in bahsettiği Memory to Memory transferde GPIO adreslerinin verilip verilemediği.

tekosis

soruyu sordum ama şu an sadece izleyicilik yapabiliyorum, inceliyorum. tüm cevaplar için çok teşekkür ederim. bu arada bu işi dediğim gibi program ile yapamam. sürekli programın buraya yönlenmesi gerekir ki bunu kesme ile de yapsam işime gelmez. cihazda sürekli veri akışı var bunun kesintiye uğraması sıkıntı olacaktır.
İlim ilim bilmektir, ilim kendin bilmektir, sen kendin bilmezsin, bu nice okumaktır.

Gökhan BEKEN

@yamak hocam dediğiniz gibi bu program peripheral to memory işi yapıyor. GPIO'yu nasıl kaynak olarak gösterildiğini paylaşmak için yazdım.
Peripheral to peripheral'i google'da aradığımda şu yazı gelmişti: http://www.mcu-turkey.com/direct-memory-access-dma/
orda stm32f10x'in Peripheral to peripheral özelliği olduğunu söylüyordu, ben de stm32f10x'de varsa stm32f4xx'de de vardır diye düşünmüştüm ve araştırmayı bırakmıştım.
Özel mesaj okumuyorum, lütfen göndermeyin.