SPI Cortex

Başlatan muhittin_kaplan, 27 Şubat 2014, 15:48:28

muhittin_kaplan

Cortex işlemcilerde SPI dan en fazla kaç bit yollayabiliriz. 192*n gibi bir degeri yollayacağım.
Yazılımal olarak şu an gönderiyorum.

yamak

Hocam stm32f407'de bir defada en fazla 16 bit gönderilebiliyor.2 şer bytelık frame'ler halinde gönderebilirsiniz.

muhittin_kaplan

Göndereceğim her paket 12bit, bundan dolayı birşürü hesap kitap gerekecek.

yamak

Hocam 16 bit şeklinde gönderip son 4 biti sıfır yapmasanız olmuyo mu?

ercan_t

hocam merhaba,

c kullanıyorsan bit düzeyinde hesap kitap yapmadan çok pratik çözüm var.

aşağıdaki kod bayt bayt gönderir ama her bayt bayte size kadar diğer değişken bitleri barındırır. bu yöntem çok kullanılıyor sizede tavsiye ederim.

özetle  struct içindeki değişkenleri bit sınırlaması yapıp kendi özel bit düzeyimizi tanımlıyoruz


typedef struct __attribute__((__packed__)){
     int adres : 12;
     int channel : 6;
     int  payload : 2;
     }TRfCom ;

TRfCom rfdata ;

SendSPI(&rfdata,sizeof(TRfCom));

muhittin_kaplan

@yamak
Hocam  son 4 bit icinde clk uretilir. Sonucta bu son 4bit 0 ilarak gider, olmaz
@ercan
Hocam anladigim bir byte in 6bitini birinci paket 2bitini 2 paketten mi aliyor

muhittin_kaplan

Yukardaki ornekte 12bit adres 6bit channel 2bit pay Seklinde rf dataya atamis ve gondermis

yamak

Alıntı yapılan: muhittin_kaplan - 28 Şubat 2014, 11:02:10
@yamak
Hocam  son 4 bit icinde clk uretilir. Sonucta bu son 4bit 0 ilarak gider, olmaz
@ercan
Hocam anladigim bir byte in 6bitini birinci paket 2bitini 2 paketten mi aliyor
Hocam üretilsin.Karşı tarafta siz yine ilk 12 biti alırsınız.

ercan_t

Alıntı yapılan: muhittin_kaplan - 28 Şubat 2014, 11:02:10
@yamak
Hocam  son 4 bit icinde clk uretilir. Sonucta bu son 4bit 0 ilarak gider, olmaz
@ercan
Hocam anladigim bir byte in 6bitini birinci paket 2bitini 2 paketten mi aliyor
aynen dediğiniz gibi

örneğin   bir paket 12 bit diğeri 6 diğeri 2
111111101110 111111 11

1. byte         2. bayt      3. bayt
11111110 11101111   11 ..........

yani iki paket dataki bitler birinci byte kaymıştır.





z

#9
192, 8 in tam katı olduğu için sorun yok.

unsigned int data[16];  // 16 adet 12 bitlik pwm degeri (192 bit)


for(n=0; n<16; n=n+2)
    {
       send8(data[n]>>4);
       send8((data[n]<<4) | (data[n+1])>>8);
       send8(n+1);
    }
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

muhittin_kaplan

#10
Hocam kodları biraz açarmısınız, neden nasıl ?

send8(data[n]>>4); mesela datayı 4 sağa kaydır ilk8biti gönder mi demek istediniz.

(Siz önderilecek dataları SAĞA mı SOLA mı yanaşık olarak yazdınız Kodları ?)





mesaj birleştirme:: 28 Şubat 2014, 14:45:46

-Ekleme-

data örneği

data[0]=0x0FFF; //Max Duty
data[0]=0x0001; //Min Duty

mesaj birleştirme:: 28 Şubat 2014, 14:49:57

for(n=0; n<16; n=n+2)
    {
       send8(data[n]>>4); //datayı sağa 4 kaydır ve lsb 8 biti yolla
       send8((data[n]<<4) | (data[n+1])>>8); //data[0] ı sola 4 kaydır ve sağa 8 kaymış data[1] i or layarak gönder 
       send8(n+1); //kalan 8 bit lb yi gönder
    }

muhittin_kaplan

#11
Peki Böyle bir işlem için SPI ı kullanırmıydınız (Biraz Eskiyim Herhalde Herşe Önce Yazılımsal Yapıyorum.)



mesaj birleştirme:: 28 Şubat 2014, 17:57:00

ben yazılımsal söyle yapmışım

char i;
			char z;
			u16 Value=0;
			u16 TempValue=0;

			for (i = 0; i < 16*TLC5940_N; ++i) {  //kanal sayısını hesaplayark döngü kuruyor 1*15

				TempValue=Param_PwmValue[((16*TLC5940_N)-1)-i]<<4; //sola 4 kaydırıyor.

				for (z = 0; z < 12; ++z) {  //12 bit olduğundan

					Value=TempValue<<z;
					if (Value &=0x8000)
						GPIO_SetBits(TLC5940_GPIO, SIN_PIN);
					else
						GPIO_ResetBits(TLC5940_GPIO, SIN_PIN);
						SCLK_Pulse();

				}
			}
		}
		GSCLK_Pulse();
		GSCLK_Counter++;
	}
}

(kodlarım çok optimizedir laf etmeyiniz  :P)

z

Pwm update peryodun uzun ise yazılımsal yapmanda sakınca yok. Fakat update peryodun kısa ise yani sık sık pwm değerlerini update edeceksen SPI kullanmak daha mantıklı.

Hatırlarsan aşağıdaki gibi bir çalışma yapmıştık. Bu iş görüyorsa seninkisi de hayli hayli iş görecektir.

https://www.picproje.org/index.php/topic,35896.msg257842.html#msg257842
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

muhittin_kaplan

#13
TLC ile Servo Sürecek sonra Örümcek Yürüteceğim.

mesaj birleştirme:: 28 Şubat 2014, 21:27:50

Bunu Daha Önce Görmemişim SPI Cortex TLC deyince çıktı.

http://blog.bastelhalde.de/?p=833
(Bu arada Adam Aynı Senin gibi yapmış abi.)

mesaj birleştirme:: 28 Şubat 2014, 21:28:25

for (i = 0; i < 16; i+=2)
    {
        uint8_t send1 = 0;
        uint8_t send = leds[i] >> 4;
        spi_writeByte(send);
 
        send = (leds[i] & 0x000F);
        send <<= 4;
        send1 = (leds[i+1]) >> 8;
 
        send |= send1;
        spi_writeByte(send);
 
        send = leds[i+1];
        spi_writeByte(send);
    }

muhittin_kaplan

#include <stm32f4xx.h>
#include <stm32f4xx_spi.h>
#include <stm32f4xx_rcc.h>
#include <stm32f4xx_gpio.h>
#include <misc.h>


// this function initializes the SPI1 peripheral
void init_SPI1(void){

	GPIO_InitTypeDef GPIO_InitStruct;
	SPI_InitTypeDef SPI_InitStruct;

	// enable clock for used IO pins
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOD, ENABLE);


	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_All;
		GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
		GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
		GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
		GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
		GPIO_Init(GPIOD, &GPIO_InitStruct);



	/* configure pins used by SPI1
	 * PA5 = SCK
	 * PA6 = MISO
	 * PA7 = MOSI
	 */
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_6 | GPIO_Pin_5;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOA, &GPIO_InitStruct);

	// connect SPI1 pins to SPI alternate function
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);

	// enable clock for used IO pins
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);

	/* Configure the chip select pin
	   in this case we will use PE7 */
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIOE, &GPIO_InitStruct);

	GPIOE->BSRRL |= GPIO_Pin_7; // set PE7 high

	// enable peripheral clock
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

	/* configure SPI1 in Mode 0
	 * CPOL = 0 --> clock is low when idle
	 * CPHA = 0 --> data is sampled at the first edge
	 */
	SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // set to full duplex mode, seperate MOSI and MISO lines
	SPI_InitStruct.SPI_Mode = SPI_Mode_Master;     // transmit in master mode, NSS pin has to be always high
	SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; // one packet of data is 8 bits wide
	SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;        // clock is low when idle
	SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;      // data sampled at first edge
	SPI_InitStruct.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set; // set the NSS management to internal and pull internal NSS high
	SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; // SPI frequency is APB2 frequency / 4
	SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;// data is transmitted MSB first
	SPI_Init(SPI1, &SPI_InitStruct);

	SPI_Cmd(SPI1, ENABLE); // enable SPI1
}

/* This funtion is used to transmit and receive data
 * with SPI1
 * 			data --> data to be transmitted
 * 			returns received value
 */
uint8_t SPI1_send(uint8_t data){

	SPI1->DR = data; // write data to be transmitted to the SPI data register
	while( !(SPI1->SR & SPI_I2S_FLAG_TXE) ); // wait until transmit complete
	while( !(SPI1->SR & SPI_I2S_FLAG_RXNE) ); // wait until receive complete
	while( SPI1->SR & SPI_I2S_FLAG_BSY ); // wait until SPI is not busy anymore
	return SPI1->DR; // return received data from SPI data register
}

int main(void){

	uint8_t received_val = 0;
	uint_fast8_t n;


	//SIRALI BILGIYI ONDERILIYOR
	unsigned int data[16]={0x0FFF,0x0555,0x0FFF,0x0555,0x0FFF,0x0555,0x0FFF,0x0555,0x0FFF,0x0555,0x0FFF,0x0555,0x0FFF,0x0555,0x0FFF,0x0555};

	init_SPI1();
	GPIOE->BSRRH |= GPIO_Pin_7; // set PE7 (CS) low
	for(n=0; n<16; n=n+2)
	    {
		SPI1_send(data[n]>>4);
		SPI1_send((data[n]<<4) | (data[n+1])>>8);
		SPI1_send(data[n+1]);
	    }
	GPIOE->BSRRL |= GPIO_Pin_7; // set PE7 (CS) high
		GPIO_SetBits(GPIOD,GPIO_Pin_12);


	while(1){

		GPIOE->BSRRH |= GPIO_Pin_7; // set PE7 (CS) low
		SPI1_send(0x11);  // transmit data
		//received_val = SPI1_send(0x00); // transmit dummy byte and receive data
		GPIOE->BSRRL |= GPIO_Pin_7; // set PE7 (CS) high
		GPIO_ToggleBits(GPIOD,GPIO_Pin_14);

	}
}