嵌入式linux中SPI應用開發

在嵌入式設備中用到spi的器件有很多,目前常見的有刷卡器、藍牙模塊等,都是通過spi總線來通信的。本文來講解一下SPI應用程序開發的常見模式。


一 、 主要結構體

linux中,應用開發常用的結構體主要是struct spi_ioc_transfer:

struct spi_ioc_transfer {
	__u64		tx_buf;
	__u64		rx_buf;

	__u32		len;
	__u32		speed_hz;

	__u16		delay_usecs;
	__u8		bits_per_word;
	__u8		cs_change;
	__u32		pad;
};

#define SPI_MSGSIZE(N) \
	((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << _IOC_SIZEBITS)) \
		? ((N)*(sizeof (struct spi_ioc_transfer))) : 0)
#define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)])

只要對spi_ioc_transfer進行賦值,就可以進行讀寫操作了,很簡單。


二、 SPI設備的初始化

void spi_Init()
{
	int ret = 0;


	spifd = open(device, O_RDWR);
	if (spifd < 0)
		pabort("can't open device");

	/*
	 * spi mode
	 */
	ret = ioctl(spifd, SPI_IOC_WR_MODE, &mode);
	if (ret == -1)
		pabort("can't set spi mode");

	ret = ioctl(spifd, SPI_IOC_RD_MODE, &mode);
	if (ret == -1)
		pabort("can't get spi mode");

	/*
	 * bits per word
	 */
	ret = ioctl(spifd, SPI_IOC_WR_BITS_PER_WORD, &bits);
	if (ret == -1)
		pabort("can't set bits per word");

	ret = ioctl(spifd, SPI_IOC_RD_BITS_PER_WORD, &bits);
	if (ret == -1)
		pabort("can't get bits per word");

	/*
	 * max speed hz
	 */
	ret = ioctl(spifd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
	if (ret == -1)
		pabort("can't set max speed hz");

	ret = ioctl(spifd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
	if (ret == -1)
		pabort("can't get max speed hz");
}

首先open打開SPI的設備,然後通過ioctl函數進行數據位、速率、模式進行配置。


三 、SPI的讀寫

int spi_read()
{
    bt_devide_msg msg;
    unsigned char ucRegVal;
	int ret,i;
	unsigned char tx[20];
	for(i = 0;i<20;i++)
	{
	    tx[i] = 0xda;
	}
	unsigned char rx[ARRAY_SIZE(tx)] = {0, };
	struct spi_ioc_transfer tr = {
		.tx_buf = (unsigned long)tx,
		.rx_buf = (unsigned long)rx,
		.len = ARRAY_SIZE(tx),
		.delay_usecs = udelay,
		.speed_hz = speed,
		.bits_per_word = bits,
	};
	

	ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);

	if (ret < 1)
	{
		printf("can't read spi message\n");
		return -1;
	}
	
	if(rx[0] !=0xAA)
	{
        printf("read spi data: ");	
	    for (ret = 0; ret < ARRAY_SIZE(tx); ret++) 
		{
		    printf("%02X ", rx[ret]);
	    }
        printf("\n");
	}
	
	ucRegVal = rx[ARRAY_SIZE(tx)-1];

	get_data_process(rx);
							
  return 1;

write函數和這類似。


四、 測試函數

void main()
{
    spi_init();
    spi_read();
}
OK,就是這麼簡單

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章