使用mini210与STM32进行SPI通信
这个是mini210的spi驱动的应用程序
代码如下
这个是全双工的代码,可以对SPI0进行读写操作
SPI_IOC_MESSAGE(1)这个就是全双工通信的核心代码
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
static void pabort(const char *s)
{
perror(s);
abort();
}
static const char *device0 = "/dev/spidev0.0";
static const char *device1 = "/dev/spidev1.0";
static uint8_t mode = 1;
static uint8_t bits = 8;
static uint8_t lsb = 1;
static uint32_t speed = 4500000;
static uint16_t delay = 0;
static void transfer(int fd)
{
int ret;
uint8_t tx[] = {0xFF, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD,0xF0, 0x0D}; //发给STM32的数据
uint8_t 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 = delay,
.speed_hz = speed,
.bits_per_word = bits,
};
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
if (ret < 1)
pabort("can't send spi message");
for (ret = 0; ret < ARRAY_SIZE(tx); ret++) {
if (!(ret % 6))
puts("");
printf("%.2X ", rx[ret]);
}
puts("");
}
int main(int argc, char *argv[])
{
int ret = 0;
int fd;
//parse_opts(argc, argv);
fd = open(device0, O_RDWR);
if (fd < 0)
pabort("can't open device0");
/*
* spi mode
*/
ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
if (ret == -1)
pabort("can't set max speed hz");
ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
if (ret == -1)
pabort("can't get max speed hz");
/*
* bits per word
*/
ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
if (ret == -1)
pabort("can't set bits per word");
ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
if (ret == -1)
pabort("can't get bits per word");
ret = ioctl(fd, SPI_IOC_RD_LSB_FIRST, &lsb);
if(ret == -1)
{
perror("can't get lsb");
}
/*
* max speed hz
*/
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
if (ret == -1)
pabort("can't set max speed hz");
ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
if (ret == -1)
pabort("can't get max speed hz");
printf("spi mode: %d\n", lsb);
printf("bits per word: %d\n", bits);
printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);
transfer(fd);
close(fd);
return ret;
}
编译的时候最好使用 -static,即arm-linux-gcc -o spitest spitest.c -static, 不然执行时会出错
STM32的SPI的部分通信代码
使用DMA传输,全双工通信
uint8_t SPI1_Buffer_Rx[BufferSize];//接收的buffer
uint8_t SPI1_Buffer_Tx[BufferSize] = {0xaa,0xaa,0xaa,0x5a,0xa5,0xff,0xab,0xad};//发送的数据
/* SPI_SLAVE_Rx_DMA_Channel configuration ---------------------------------------------*/
DMA_DeInit(SPI1_Rx_DMA_Channel);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SPI1_DR_Base;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SPI1_Buffer_Rx;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
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_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(SPI1_Rx_DMA_Channel, &DMA_InitStructure);
DMA_DeInit(SPI1_Tx_DMA_Channel);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)SPI1_DR_Base;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SPI1_Buffer_Tx;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
DMA_Init(DMA1_Channel3, &DMA_InitStructure);
/* SPIy Config -------------------------------------------------------------*/
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
SPI_Cmd(SPI1, ENABLE);
/* Enable SPI1 DMA Tx request */
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, ENABLE);
DMA_Cmd(SPI1_Rx_DMA_Channel, ENABLE);
DMA_Cmd(SPI1_Tx_DMA_Channel, ENABLE);
while (!DMA_GetFlagStatus(SPIy_Tx_DMA_FLAG));//发送结束
while (!DMA_GetFlagStatus(SPIy_Rx_DMA_FLAG));//接收结束
for(i=0;i<8;i++)
{
sprintf(string, "read spi: %x\r\n", SPIy_Buffer_Rx[i]);
USART1_Printf(string);
}
关于mini210的SPI时钟,设置10M进去,只有8M多出来,不知道哪里设置不对,请知道的告诉我下