工具/软件:Code Composer Studio
有3个文件:
/*********
SPI_Raspi_Arduino
将 Raspberry Pi 配置为 SPI 主设备、然后
演示了基本的双向通信方案
Arduino 从站。 Raspberry Pi 发送数据
对执行加法和减法的命令
且 Ardunio 返回结果
编译字符串:
G++-o SPI_Raspi_Arduino SPI_Raspi_Arduino.cpp
秘书长的报告 /
#include
#include
#include
#include
#include
#include
使用命名空间 std;
#define DELAY_microsec 10.
/*********
内部管理变量
秘书长的报告 /
INT 结果;
int fd;
/*********
声明函数
秘书长的报告 /
int spiTxRx (unsigned char txDat);
int sendCommand (char i、int j、int k);
/*********
主程序
秘书长的报告 /
int main (空)
{
int i=0;
INT MAX=100;
/*********
设置 SPI
打开文件 spidev0.0 (芯片启用0)以进行读取/写入访问
使用文件描述符"fD"
配置传输速度(1MkHz)
秘书长的报告 /
FD =开路("/dev/spidev0.0、O_RDWR);
unsigned char SPI_MODE = SPI_MODE_3;
// SPI_MODE_0 => CPOL=0;CPHA=0
// SPI_MODE_1 => CPOL=0;CPHA=1
// SPI_MODE_2 => CPOL=1;CPHA=0
// SPI_MODE_3 => CPOL=1;CPHA=1
//将模式更改为所需的值
ioctl (FD、SPI_IOC_WR_MODE、&SPI_MODE);
unsigned int speed = 1000000;
ioctl (fd、SPI_IOC_WR_MAX_SPEED_Hz、&SPEED);
睡眠(1);
/*********
一个不断循环、该循环会重复发送演示
命令到 Arduino 并显示结果
秘书长的报告 /
while (1)
{
i++;
如果(i=MAX) i=0;
COUT <<"循环编号"<<(i)<<结束;
结果= sendCommand ('a'、510、655);
COUT <<"添加结果:"<< endl;
COUT <<"510 + 655 ="<<(int)(结果)<< endl;
结果= sendCommand ("S"、1000、250);
COUT <<"减影结果:"<< endl;
COUT <<"1000 - 250 ="<<(int)(结果)<< endl <endl;
睡眠(1);
}
}
/*********
spiTxRx
通过 SPI 器件发送一个字节、并返回一个字节
结果。
根据定义建立数据结构 SPI_Ioc_transfer
并 spidev.h 加载各种成员以传递数据
以及通过 IOCTL 将配置参数添加到 SPI 器件
局部变量 txDat 和 rxDat 由定义和传递
基准。
秘书长的报告 /
int spiTxRx (无符号字符 txDat)
{
unsigned char rxDat;
struct spi_oco_transfer spi;
memset (&SPI、0、sizeof (SPI));
spi.TX_Buf =(无符号长整型)&txDat;
spi.rx_Buf =(无符号长整型)&rxDat;
spi.len = 1;
ioctl (FD、SPI_IOC_MESSAGE (1)、&SPI);
返回 rxDat;
}
/*********
sendCommand
使用 spiTxRx 函数的协议演示
向 Arduino 发送格式化命令序列/数据包
并捕获结果
秘书长的报告 /
int sendCommand (char 命令、int j、int k)
{
unsigned char resultByte;
bool ack;
/*********
联合体允许变量占用相同的存储器空间
在8位和之间来回移动的便捷方法
16位值等
此处声明了三个联合体:两个表示要使用的参数
将命令传递给 Arduino、并接收命令
结果
秘书长的报告 /
UNION p1Buffer_T
{
int p1int;
unsigned char p1char [2];
} p1Buffer;
UNION p2Buffer_T
{
int p2int;
unsigned char p2char [2];
} p2Buffer;
联合结果 Buffer_T
{
int resultInt;
unsigned char resultchar [2];
} resultBuffer;
p1Buffer.p1Int = j;
p2Buffer.p2Int = k;
resultBuffer.resultInt = 0;
/*********
一个初始握手序列发送一个字节启动代码
('c')并不停循环、直到它接收到一个字节
确认代码('A')并将 ACK 标志设置为 true。
(请注意、循环还在发送命令字节时发送命令字节
仍然处于握手序列、以避免浪费发送
周期。)
秘书长的报告 /
操作
{
ACK = false;
spiTxRx ('c');
usleep (delay_microsec);
resultByte = spiTxRx (command);
if (resultByte ='A')
{
ACK = true;
}
usleep (delay_microsec);
}
while (ack == false);
/*********
每次发送一个字节的参数。
秘书长的报告 /
spiTxRx (p1Buffer.p1Char[0]);
usleep (delay_microsec);
spiTxRx (p1Buffer.p1Char[1]);
usleep (delay_microsec);
spiTxRx (p2Buffer.p2Char[0]);
usleep (delay_microsec);
spiTxRx (p2Buffer.p2Char[1]);
usleep (delay_microsec);
/*********
再按两个零、这样 Arduino 就可以返回
结果
秘书长的报告 /
resultByte = spiTxRx (0);
resultBuffer.resultChar[0]= resultByte;
usleep (delay_microsec);
resultByte = spiTxRx (0);
resultBuffer.resultChar[1]= resultByte;
返回 resultBuffer.resultInt;
}
/*
*==== empty.c ======
*
#define MSGSIZE 10 //数据包中的字节数,包括 pkt. number 作为第一个字节
#define MAX_PKT_NUM 20 //从0开始前数据包的最大数量
/* for usleep()*/
#include
#include
#include
/*驱动程序头文件*/
#include
//#include
//#include
#include
#include
#include
/* XDCtools 头文件*/
#include
#include
//#include
//#include
/*板头文件*/
#include "Board.h"
//全局变量
uint8_t rxBuf[1];//接收缓冲区
uint8_t txBuf[1];
//{55、77、88、99};//传输缓冲区
/*********
根据 SPI_Raspi_Arduino 进行了改编
将 ATMEGA 配置为 SPI 从器件并进行演示
基本双向通信方案
Raspberry Pi SPI 主设备将命令传输到
对一对整数和执行加法和减法
Ardunio 传输结果
秘书长的报告 /
/*********
全局变量
-receiveBuffer[]和 dat 用于捕获传入数据
进行了比较
-marker 用作指针来跟踪电流
数据包中的位置
(小部分 /
unsigned char receiveBuffer[5];
unsigned char dat;
无符号字符标记= 0;
/*********
联合体允许变量占用相同的存储器空间 A
在8位和之间来回移动的便捷方法
16位值等 此处声明了三个联合体:
其中两个用于在命令中传递给 Arduino 的参数
另一个用于接收结果
(小部分 /
UNION
{
int p1int;
unsigned char p1char [2];
} p1Buffer;
UNION
{
int p2int;
unsigned char p2char [2];
} p2Buffer;
UNION
{
int resultInt;
unsigned char resultchar [2];
} resultBuffer;
/*
//回调函数
静态空转移回调(SPI_Handle handle、SPI_Transaction *事务)
{
静态 char pktNum=0;//用于保存数据包编号
txBuf[0]= pktNum;
pktNum++;
如果(pktNum=MAX_PKT_NUM) pktNum=0;
//开始另一个传输
SPI_TRANSFCTION (handle、transaction);
//将 LED 切换为指示器
GPIO_TOGGLE (Board_GPIO_LED1);
}
*
/*********
SpiHandler
使用标记变量将跟踪当前位置保持在中
传入数据包并执行相应的操作
0 -等待接收起始字节-收到后发送
确认字节
1 -添加或减法的命令
2-5 -要添加或减去的两个整数参数
-当接收到最后一个字节(5)时,调用
ExecuteCommand 函数并加载的第一个字节
SPDR 中
6 -发送结果的第一个字节并加载
SPDR 中的第二个字节
7 -发送结果的第二个字节并进行复位
标记
秘书长的报告 /
void ExecuteCommand (void);//Fwd 定义
//void spiHandler()
静态空转移回调(SPI_Handle handle、SPI_Transaction *事务)
{
开关(标记)
{
情况0:
DAT = rxBuf[0];
如果(dat ='c')
{
txBuf[0]='A';
Marker++;
}
中断;
案例1:
receiveBuffer[marker-1]= rxBuf[0];
Marker++;
中断;
案例2:
receiveBuffer[marker-1]= rxBuf[0];
Marker++;
中断;
案例3:
receiveBuffer[marker-1]= rxBuf[0];
Marker++;
中断;
案例4:
receiveBuffer[marker-1]= rxBuf[0];
Marker++;
中断;
情况5:
receiveBuffer[marker-1]= rxBuf[0];
Marker++;
ExecuteCommand();
txBuf[0]= resultBuffer.resultChar[0];
中断;
案例6:
Marker++;
txBuf[0]= resultBuffer.resultChar[1];
中断;
案例7:
DAT = rxBuf[0];
标记=0;
}
//将 LED 切换为指示器
GPIO_TOGGLE (Board_GPIO_LED1);
//开始另一个传输
SPI_TRANSFCTION (handle、transaction);
}
/*********
ExecuteCommand
当接收到完整的5字节命令序列时
从 receiveBuffer 重新构成字节变量
解析命令(添加或减)并执行整数
指示的操作-结果将位于 resultBuffer 中
秘书长的报告 /
空 ExecuteCommand (空)
{
p1Buffer.p1Char[0]= receiveBuffer[1];
p1Buffer.p1Char[1]= receiveBuffer[2];
p2Buffer.p2Char[0]= receiveBuffer[3];
p2Buffer.p2Char[1]=接收缓冲区[4];
if (receiveBuffer[0]='A')
{
resultBuffer.resultInt = p1Buffer.p1Int + p2Buffer.p2Int;
}
否则(receiveBuffer[0]=='s')
{
resultBuffer.resultInt = p1Buffer.p1Int - p2Buffer.p2Int;
}
否则{
resultBuffer.resultInt = 0;
}
}
/*
*==== mainThread ====
*
void * mainThread (void * arg0)
{
/* 1秒延迟*/
uint32_t 时间= 1;
int i=0;
char ack;
SPI_Handle 句柄;
SPI_Params 参数;
SPI_Transaction 事务;
/*调用驱动程序初始化函数*/
GPIO_init();
// I2C_init ();
// SDSPI_init ();
spi_init();
// uart_init();
// Watchdog_init();
//初始化 SPI 并指定非默认参数
SPI_PARAMS_INIT (params);
params.bitrate = 1000000;
params.frameFormat = SPI_POL1_PHA1;
params.mode = SPI_SLAVE;
//在接收到'c'并发送'a'的位置设置同步锁定,直到
//满足锁定要求
transaction.count = 1;
txBuf[0]='0';rxBuf[0]= 0;
transaction.txBuf = txBuf;
transaction.rxBuf = rxBuf;
//现在设置为数据包模式
params.transferMode = SPI_MODE_CALLACK;
params.transferCallbackFxn = transferCallback;
System_printf ("在 ROV 中启动 SysMin 内容。\n");
/* SysMin 仅在您调用 flush 或 exit 时才会打印到控制台*/
system_flush();
//打开 SPI 并执行传输
句柄= SPI_OPEN (Board_SPI0、¶ms);
//启动第一个传输
SPI_TRANSFCTION (句柄、事务);
/*
对于(i=0;i<40;i++){
transaction.txBuf = txBuf+I;
transaction.rxBuf = rxBuf+I;
SPI_TRANSFCTION (句柄、事务);
}
*
/*打开用户 LED */
GPIO_WRITE (Board_GPIO_LED0、Board_GPIO_LED_ON);
GPIO_WRITE (Board_GPIO_LED1、Board_GPIO_LED_ON);
同时(2){
睡眠(时间);
GPIO_TOGGLE (Board_GPIO_LED0);
}
}
pi@raspberrypi $./RPI_SPI2
环路1
添加结果:
510 + 655 = 1165
减法结果:
1000 - 250 = 750
环路2
添加结果:
510 + 655 = 1165
减法结果:
1000 - 250 = 750
环路3
添加结果:
510 + 655 = 1165
减法结果:
1000 - 250 = 750
环路4
添加结果:
510 + 655 = 24929
减法结果:
1000 - 250 = 24929
环路编号5
添加结果:
510 + 655 = 24929
减法结果:
1000 - 250 = 24929
环路6
添加结果:
510 + 655 = 24929
减法结果:
1000 - 250 = 24929