欢迎大家测试

u8 SPI1_ReadByte(u8 TxData)

{

u8 retry=0;

// while((SPI1->SR&1<<1)==0)//等待发送区空

// {

//  retry++;

//  if(retry>200)return 0;

// }

// SPI1->DR=TxData;     //发送一个byte

retry=0;

while((SPI1->SR&1<<0)==0) //等待接收完一个byte

{

retry++;

if(retry>200)return 0;

}

return SPI1->DR;          //返回收到的数据

}

工具:STM32 MINI板两块

注意:NSS软件管理模式,主机:SSM=1,SSI=1。

从机:SSM=1,SSI=0;

连线:主机 SCK SCK 从机

MISO MISO

MOSI MOSI

程序部分:

主机

#include "sys.h" //系统子函数

#include "usart.h"//串口子函数

#include "delay.h" //延时子函数

// SPI总线速度设置

#define SPI_SPEED_2   0

#define SPI_SPEED_8   1

#define SPI_SPEED_16  2

#define SPI_SPEED_256 3

u8 Master_Temp =0;

void SPI1_Init(void);    //初始化SPI口

void SPI1_SetSpeed(u8 SpeedSet); //设置SPI速度

u8 SPI1_ReadWriteByte(u8 TxData);//SPI总线读写一个字节

int main(void)

{

Stm32_Clock_Init(3); //系统时钟设置

delay_init(24);//延时函数初始化

uart_init(24,9600); //串口初始化

SPI1_Init(); //SPI1初始化

SPI1_SetSpeed(SPI_SPEED_256);//SPI速度两分频

while(1)

{

SPI1_ReadWriteByte(0x55);

SPI1_ReadWriteByte(0x66);

printf("Master_Temp  =%x\r\n",Master_Temp );

delay_ms(100);

}

}

//SPI口初始化

//这里针是对SPI1的初始化

void SPI1_Init(void)

{

RCC->APB2ENR|=1<<0; //复用

RCC->APB2ENR|=1<<2;       //PORTA时钟使能

RCC->APB2ENR|=1<<12;      //SPI1时钟使能

//这里只针对SPI口初始化

GPIOA->CRL&=0X000FFFFF;

GPIOA->CRL|=0XBBB00000;//PA5.6.7复用

GPIOA->ODR|=0X7<<5;    //PA5.6.7上拉

SPI1->CR1|=0<<10;//全双工模式

SPI1->CR1|=1<<9; //软件nss管理

SPI1->CR1|=1<<8;

SPI1->CR1|=1<<2; //SPI主机

SPI1->CR1|=0<<11;//8bit数据格式

SPI1->CR1|=1<<1; //空闲模式下SCK为1 CPOL=1

SPI1->CR1|=1<<0; //数据采样从第二个时间边沿开始,CPHA=1

SPI1->CR1|=0<<3; //Fsck=Fcpu/256

SPI1->CR1|=0<<7; //MSBfirst

SPI1->CR2|=1<<6;      //接收缓冲区非空中断使能

MY_NVIC_Init(1,0,SPI1_IRQChannel,4);

SPI1->CR1|=1<<6; //SPI设备使能

}

//SPI 速度设置函数

//SpeedSet:

//SPI_SPEED_2   2分频   (SPI 12M    --sys 24M)

//SPI_SPEED_8   8分频   (SPI 3M     --sys 24M)

//SPI_SPEED_16  16分频  (SPI 1.5M    --sys 24M)

//SPI_SPEED_256 256分频 (SPI  905.6K --sys 24M)

void SPI1_SetSpeed(u8 SpeedSet)

{

SPI1->CR1&=0XFFC7;//Fsck=Fcpu/256

if(SpeedSet==SPI_SPEED_2)//二分频

{

SPI1->CR1|=0<<3;//Fsck=Fpclk/2=36Mhz

}else if(SpeedSet==SPI_SPEED_8)//八分频

{

SPI1->CR1|=2<<3;//Fsck=Fpclk/8=9Mhz

}else if(SpeedSet==SPI_SPEED_16)//十六分频

{

SPI1->CR1|=3<<3;//Fsck=Fpclk/16=4.5Mhz

}

else      //256分频

{

SPI1->CR1|=7<<3; //Fsck=Fpclk/256=281.25Khz 低速模式

}

SPI1->CR1|=1<<6; //SPI设备使能

}

//SPIx 读写一个字节

//TxData:要写入的字节

//返回值:读取到的字节

u8 SPI1_ReadWriteByte(u8 TxData)

{

u8 retry=0;

while((SPI1->SR&1<<1)==0)//等待发送区空

{

retry++;

if(retry>200)return 0;

}

SPI1->DR=TxData;     //发送一个byte

retry=0;

while((SPI1->SR&1<<0)==0) //等待接收完一个byte

{

retry++;

if(retry>200)return 0;

}

return SPI1->DR;          //返回收到的数据

}

u8 SPI1_ReadByte(u8 TxData)

{

u8 retry=0;

while((SPI1->SR&1<<0)==0) //等待接收完一个byte

{

retry++;

if(retry>200)return 0;

}

return SPI1->DR;          //返回收到的数据

}

void SPI1_IRQHandler(void)

{

if((SPI1->SR&1<<0)==1)

{

Master_Temp = SPI1_ReadByte(0x00);

}

}

从机

#include "sys.h" //系统子函数

#include "usart.h"//串口子函数

#include "delay.h" //延时子函数

// SPI总线速度设置

#define SPI_SPEED_2   0

#define SPI_SPEED_8   1

#define SPI_SPEED_16  2

#define SPI_SPEED_256 3

u8 Slave_Temp=0;

void SPI1_Init(void);    //初始化SPI口

void SPI1_SetSpeed(u8 SpeedSet); //设置SPI速度

u8 SPI1_ReadWriteByte(u8 TxData);

int main(void)

{

Stm32_Clock_Init(3); //系统时钟设置

delay_init(24);//延时函数初始化

uart_init(24,9600); //串口初始化

SPI1_Init(); //SPI1初始化

SPI1_SetSpeed(SPI_SPEED_256);//SPI速度两分频

MY_NVIC_Init(0,0,SPI1_IRQChannel,4);   //设置抢占优先级为1,响应优先级为1,中断分组为4

while(1)

{

printf("Slave_Temp=%x\r\n",Slave_Temp);

delay_ms(100);

}

}

//SPI口初始化

//这里针是对SPI1的初始化

void SPI1_Init(void)

{

RCC->APB2ENR|=1<<0; //复用

RCC->APB2ENR|=1<<2;       //PORTA时钟使能

RCC->APB2ENR|=1<<12;      //SPI1时钟使能

//这里只针对SPI口初始化

GPIOA->CRL&=0X000FFFFF;

GPIOA->CRL|=0XBBB00000;//PA5.6.7复用

GPIOA->ODR|=0X7<<5;    //PA5.6.7上拉

SPI1->CR1|=0<<10;//全双工模式

SPI1->CR1|=1<<9; //软件nss管理

SPI1->CR1|=0<<8;//ssi为0

SPI1->CR1|=0<<2; //SPI从机

SPI1->CR1|=0<<11;//8bit数据格式

SPI1->CR1|=1<<1; //空闲模式下SCK为1 CPOL=1

SPI1->CR1|=1<<0; //数据采样从第二个时间边沿开始,CPHA=1

SPI1->CR1|=0<<3; //Fsck=Fcpu/256

SPI1->CR1|=0<<7; //MSBfirst

SPI1->CR2|=1<<6;      //接收缓冲区非空中断使能

MY_NVIC_Init(1,0,SPI1_IRQChannel,4);

SPI1->CR1|=1<<6; //SPI设备使能

}

//SPI 速度设置函数

//SpeedSet:

//SPI_SPEED_2   2分频   (SPI 12M    --sys 24M)

//SPI_SPEED_8   8分频   (SPI 3M     --sys 24M)

//SPI_SPEED_16  16分频  (SPI 1.5M    --sys 24M)

//SPI_SPEED_256 256分频 (SPI  905.6K --sys 24M)

void SPI1_SetSpeed(u8 SpeedSet)

{

SPI1->CR1&=0XFFC7;//Fsck=Fcpu/256

if(SpeedSet==SPI_SPEED_2)//二分频

{

SPI1->CR1|=0<<3;//Fsck=Fpclk/2=36Mhz

}

else if(SpeedSet==SPI_SPEED_8)//八分频

{

SPI1->CR1|=2<<3;//Fsck=Fpclk/8=9Mhz

}

else if(SpeedSet==SPI_SPEED_16)//十六分频

{

SPI1->CR1|=3<<3;//Fsck=Fpclk/16=4.5Mhz

}

else      //256分频

{

SPI1->CR1|=7<<3; //Fsck=Fpclk/256=281.25Khz 低速模式

}

SPI1->CR1|=1<<6; //SPI设备使能

}

u8 SPI1_ReadWriteByte(u8 TxData)

{

u8 retry=0;

while((SPI1->SR&1<<1)==0)//等待发送区空

{

retry++;

if(retry>200)return 0;

}

SPI1->DR=TxData;     //发送一个byte

retry=0;

while((SPI1->SR&1<<0)==0) //等待接收完一个byte

{

retry++;

if(retry>200)return 0;

}

return SPI1->DR;          //返回收到的数据

}

u8 SPI1_ReadByte(u8 TxData)

{

u8 retry=0;

//   while((SPI1->SR&1<<1)==0)//等待发送区空

//   {

//       retry++;

//       if(retry>200)return 0;

//   }

//  SPI1->DR=TxData;     //发送一个byte

//  retry=0;

while((SPI1->SR&1<<0)==0) //等待接收完一个byte

{

retry++;

if(retry>200)return 0;

}

return SPI1->DR;          //返回收到的数据

}

void SPI1_IRQHandler(void)

{

if((SPI1->SR&1<<0)==1)

{

Slave_Temp = SPI1_ReadByte(0x00);

SPI1_ReadWriteByte(0xaa);

}

}

改进:把主机改成查询接收也是可以的,这时只要一个发送,是真正意义上的全双工了。

主机:

#include "sys.h" //系统子函数

#include "usart.h"//串口子函数

#include "delay.h" //延时子函数

#include "TIMER.h"

// SPI总线速度设置

#define SPI_SPEED_2   0

#define SPI_SPEED_8   1

#define SPI_SPEED_16  2

#define SPI_SPEED_256 3

u8 Master_Temp =0;

void SPI1_Init(void);    //初始化SPI口

void SPI1_SetSpeed(u8 SpeedSet); //设置SPI速度

void SPI1_WriteByte(u8 TxData);//SPI总线读写一个字节

u8 SPI1_ReadByte(u8 TxData);

int main(void)

{

Stm32_Clock_Init(3); //系统时钟设置

delay_init(24);//延时函数初始化

uart_init(24,9600); //串口初始化

SPI1_Init(); //SPI1初始化

SPI1_SetSpeed(SPI_SPEED_256);//SPI速度两分频

while(1)

{

SPI1_WriteByte(0x55);

Master_Temp = SPI1_ReadByte(0x00);

printf("Master_Temp =%x\r\n",Master_Temp);

delay_ms(100);

}

}

//SPI口初始化

//这里针是对SPI1的初始化

void SPI1_Init(void)

{

RCC->APB2ENR|=1<<0; //复用

RCC->APB2ENR|=1<<2;       //PORTA时钟使能

RCC->APB2ENR|=1<<12;      //SPI1时钟使能

//这里只针对SPI口初始化

GPIOA->CRL&=0X000FFFFF;

GPIOA->CRL|=0XBBB00000;//PA5.6.7复用

GPIOA->ODR|=0X7<<5;    //PA5.6.7上拉

SPI1->CR1|=0<<10;//全双工模式

SPI1->CR1|=1<<9; //软件nss管理

SPI1->CR1|=1<<8;

SPI1->CR1|=1<<2; //SPI主机

SPI1->CR1|=0<<11;//8bit数据格式

SPI1->CR1|=1<<1; //空闲模式下SCK为1 CPOL=1

SPI1->CR1|=1<<0; //数据采样从第二个时间边沿开始,CPHA=1

SPI1->CR1|=0<<3; //Fsck=Fcpu/256

SPI1->CR1|=0<<7; //MSBfirst

//SPI1->CR2|=1<<6;      //接收缓冲区非空中断使能

//MY_NVIC_Init(8,0,SPI1_IRQChannel,4);

SPI1->CR1|=1<<6; //SPI设备使能

}

//SPI 速度设置函数

void SPI1_SetSpeed(u8 SpeedSet)

{

SPI1->CR1&=0XFFC7;//Fsck=Fcpu/256

if(SpeedSet==SPI_SPEED_2)//二分频

{

SPI1->CR1|=0<<3;//Fsck=Fpclk/2=36Mhz

}else if(SpeedSet==SPI_SPEED_8)//八分频

{

SPI1->CR1|=2<<3;//Fsck=Fpclk/8=9Mhz

}else if(SpeedSet==SPI_SPEED_16)//十六分频

{

SPI1->CR1|=3<<3;//Fsck=Fpclk/16=4.5Mhz

}else      //256分频

{

SPI1->CR1|=7<<3; //Fsck=Fpclk/256=281.25Khz 低速模式

}

SPI1->CR1|=1<<6; //SPI设备使能

}

//SPIx 读写一个字节

//TxData:要写入的字节

//返回值:读取到的字节

void SPI1_WriteByte(u8 TxData)

{

u8 retry=0;

while((SPI1->SR&1<<1)==0)//等待发送区空

{

retry++;

if(retry>200)return;

}

SPI1->DR=TxData;     //发送一个byte

}

u8 SPI1_ReadByte(u8 TxData)

{

u8 retry=0;

while((SPI1->SR&1<<0)==0) //等待接收完一个byte

{

retry++;

if(retry>200)return 0;

}

return SPI1->DR;          //返回收到的数据

}

linux spi双机通信,【转】STM32 SPI双机通信(主从全双工)相关推荐

  1. 【STM32】0.96寸OLED显示屏(7针SPI协议)软件模拟SPI

    Author:AXYZdong 自动化专业 工科男 有一点思考,有一点想法,有一点理性 [自制展示]2020鼠年大吉 文章目录 概述 3.1硬件设计 3.2软件设计 3.2.1编程要点 3.2.2代码 ...

  2. 通俗理解STM32 SPI通信(主从双机SPI通信)

    STM32 SPI通信 高速全双工的通信总线 SPI 通讯使用 3 条总线及片选线,3 条总线分别为 SCK.MOSI.MISO,片选线为NSS(CS) NSS 信号线由高变低 ,是 SPI 通讯的起 ...

  3. Zigbee(cc2530)和STM32 SPI通信,温度采集,组网

    实验板子: 1. zigbee底板3块(1终端.1路由.1协调器,均基于CC2530) 2. stm32核心板(采集温度) 说明:下面的程序都是在TI官方例程SampleApp工程下面进行的更改.Z- ...

  4. STM32学习100步之第七十二-七十六步——U盘、TF卡与单片机的通信(利用SPI总线通信)

    SPI通信 由图中可以看出,SPI有四条主要的信号线,即MISO(主机输入从机输出).MOSI(主机输出从机输入),CS是对于从机而言的,当为0时,允许通信,由主机控制是否选通,另外可以使用单片机的I ...

  5. STM32——SPI通信实验

    程序配置过程: 1.使能SPIx和IO口时钟: RCC_AHBxPeriphClockCmd()/RCC_APBxPeriphClockCmd(); 2.初始化IO口为复用功能: void GPIO_ ...

  6. STM32 SPI难点浅析

    我用的是战舰STM32开发板,两个知识点,一:是STM32 SPI的原理:二:用STM32自带的SPI对外部flash(W25Q64)的读写. 一:STM32 SPI的原理       先上图: 主模 ...

  7. STM32——SPI接口

    STM32--SPI接口 宗旨:技术的学习是有限的,分享的精神是无限的. 一.SPI协议[SerialPeripheral Interface] 串行外围设备接口,是一种高速全双工的通信总线.在ADC ...

  8. stm32 SPI架构

    STM32 芯片集成了专门用于 SPI 协议通讯的外设. 通讯引脚:SPI 硬件架构从 MOSI.MISO.SCK 及 NSS 线展开:STM32 芯片有多个 SPI 外设,它们的 SPI 通讯信号引 ...

  9. STM32 SPI NSS 作用

    STM32 SPI NSS 作用 原创 2017年06月16日 11:18:14 142 SSM可以控制内部NSS引脚与SSI(一个寄存器,软件模式)相连,还是与NSS外部引脚(真正的STM32引脚, ...

  10. STM32 SPI详解

    目录 1.SPI简介 2.SPI特点 2.1.SPI控制方式 2.2.SPI传输方式 2.3.SPI数据交换 2.4.SPI传输模式 3.工作机制 3.1.相关缩写 3.2.CPOL极性 3.3.CP ...

最新文章

  1. java内部类和匿名类
  2. python 修改xml_如何在python中更新/修改XML文件?
  3. 骑摩托的蒙娜丽莎 - 曼妙风骚的花式慢跑算法
  4. 如何向列表中添加数据值(管理员篇)
  5. 28,29_激活函数与GPU加速、Tanh和sigmoid、ReLU、Leaky ReLU、SELU、Softplus、GPU accelerated、案例、argmax
  6. 雪碧图sprity 合并多图使用心得
  7. 1000行MySQL学习笔记,收藏版!
  8. Unity枚举和字符串的相互转换
  9. 鞍部在哪里_智慧树知到在哪里可以寻找答案?
  10. 无线AP与无线路由器都有些什么区别?(一)
  11. Cocos2d—X游戏开发之VS2010 控制台输出中文,模拟器中文乱码问题解决
  12. C/C++[codeup 1785]字符串连接
  13. 8本新书,为你的2020年管理之路指点迷津
  14. 临床试验中的样本量估算---实践篇
  15. 超市管理系统的常用软件
  16. 第三方支付账务系统论述
  17. unity3D professional专业主题——黑色主题设置
  18. 数据源EPMSSqlDataSource的使用
  19. Qemu kvm_qemu详细教程
  20. matlab——遗传算法中的选择,交叉,变异等一系列问题解析(一)

热门文章

  1. 容器网络Calico进阶实践 | 褚向阳
  2. 从外部导入django模块
  3. Reactjs 入门基础(一)
  4. MahApps.Metro
  5. 找不到可安装的ISAM”的问题
  6. 引起路由器重启的“元凶”
  7. css 网格布局_我从CSS网格布局中学到的东西
  8. 愉快的舞会c++_如何在5分钟内建立一个令人愉快的加载屏幕
  9. jsp实现日历(二)
  10. PL/SQL编程:将两个数进行交换的存储过程