怎么实现单片机和PC机进行SPI通讯?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了怎么实现单片机和PC机进行SPI通讯?相关的知识,希望对你有一定的参考价值。

想开发一个数据采集的设备,但是用串口与PC通讯数据传输速度太低了,想用SPI进行通讯,如何才能实现?

实现单片机和PC机进行SPI通讯方法:
1:电路设计
设计的电路,利用两片AT89C52芯片,一片做为发送模块,一片做为接收模块。分别编写发送和接收程序,实现数据的发送和接受。通过LED显示接收到的数据。通过示波器观察输出的波形。
2:编写程序
根据设计好的电路及题目要求分别编写数据发送程序和数据接收程序。 ①:数据发送程序 #define
uchar unsigned char
#define uint unsigned int

#define ulong unsigned long
//--------------------------- #include <REG52.H>
#include<STDIO.H>
//--------------------------- sbit SPICLK = P1^0; //时钟信号 sbit MOSI = P1^1; //主器件数据输出,从器件数据输入 sbit MISO = P1^2; //主器件数据输入,从器件数据输出
sbit SS = P1^3; //从器件使能信号
void Dat_Transmit(uchar dat) //发送数据程序
uchar i,datbuf;
datbuf=dat;
SS=1; while(SS); for(i=0;i<8;i++)
while(SPICLK); if(datbuf&0x80) MISO=1; else
MISO=0;
datbuf=(datbuf<<1); while(~SPICLK);


void main(void)
uchar i; while(1)
for(i=0;i<10;i++)
Dat_Transmit(i);



②:数据接收程序 #define uchar unsigned char
#define uint unsigned int #define ulong
unsigned long
//--------------------------- #include <REG52.H>
#include<STDIO.H>
//--------------------------- sbit SPICLK = P1^0; //时钟信号 sbit MOSI = P1^1; //主器件数据输出,从器件数据输入 sbit MISO = P1^2; //主器件数据输入,从器件数据输出 sbit SS = P1^3; //从器件使能信号

//--------------------------- void Nop(void)
;

void Delay(uchar t) while(t--);


uchar Data_Receive(void) //数据接收程序
uchar i,dat=0,temp; bit
bt;

SPICLK=1; MISO=1; SS=0;
//选中器件
Nop(); Nop();
for(i=0;i<8;i++) SPICLK=1;
Nop()
Nop(); Nop(); SPICLK=0; Nop(); Nop();
bt=MISO; if(bt)
temp=0x01;
else
temp=0x00;
dat=(dat<<1);

dat=(dat|temp);

SS=1; SPICLK=1;
return dat;


void main(void)
uchar exdat; uchar i=0;

uchar code
table[10]=0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
0x7F,0x6F; P2=0;
while(1) exdat=Data_Receive(); P0=table[exdat];
for(i=0;i<200;i++)
Delay(200);


3:电路仿真
将数据发送程序生成的HEX文件载入到发送数据的模块,将数据接收程序生成的HEX文件载入到接收数据的模块。在输出端口连接LED灯等到输出信息,利用示波器观察输出波形。
4:SPI总线简介
SPI ( Serial Peripheral Interface ——串行外设接口) 总线是Motorola公司推出的一种同步串行接口技术。SPI总线系统是一种同步串行外设接口,允许MCU(微控制器)与各种外围设备以串行方式进行通信、数据交换。外围设备包括FLASHRAM、A/ D 转换器、网络控制器、MCU 等。SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议。其工作模式有两种:主模式和从模式。SPI是一种允许一个主设备启动一个从设备的同步通讯的协议,从而完成数据的交换。也就是SPI是一种规定好的通讯方式。这种通信方式的优点是占用端口较少,一般4根就够基本通讯了(不算电源线)。同时传输速度也很高。一般来说要求主设备要有SPI控制器(也可用模拟方式),就可以与基于SPI的芯片通讯了。
利用SPI总线可在软件的控制下构成各种系统。如1个主MCU和几个从MCU、几个从MCU相互连接构成多主机系统(分布式系统)、1个主MCU和1个或几个从I/O设备所构成的各种系统等。在大多数应用场合,可使用1个MCU作为主控机来控制数据,并向1个或几个从外围器件传送该数据。从器件只有在主机发命令时才能接收或发送数据。其数据的传输格式是高位(MSB)在前,低位(LSB)在后。
当一个主控机通过SPI与几种不同的串行I/O芯片相连时,必须使用每片的允许控制端,这可通过MCU的I/O端口输出线来实现。但应特别注意这些串行I/O芯片的输入输出特性:首先是输入芯片的串行数据输出是否有三态控制端。平时未选中芯片时,输出端应处于高阻态。
若没有三态控制端,则应外加三态门。否则MCU的MISO端只能连接1个输入芯片。其次是输出芯片的串行数据输入是否有允许控制端。因为只有在此芯片允许时,SCK脉冲才把串行数据移入该芯片;在禁止时,SCK对芯片无影响。若没有允许控制端,则应在外围用门电路对SCK进行控制,然后再加到芯片的时钟输入端;当然,也可以只在SPI总线上连接1个芯片,而不再连接其它输入或输出芯片。
SPI接口是在CPU和外围低速器件之间进行同步串行数据传输,在主器件的移位脉冲下,数据按位传输,高位在前,低位在后,为全双工通信,数据传输速度总体来说比I2C总线要快,速度可达到几Mbps。
5:SPI总线工作原理
SPI总线系统是一种同步串行外设接口,它可以使MCU与各种外围设备以串行方式进行通信以交换信息。SPI有三个寄存器分别为:控制寄存器SPCR,状态寄存器SPSR,数据寄存器。外围设备、网络控制器、LCD显示驱动器、A/D转换器和MCU等。
接口包括以下四种信号:
(1)MOSI – 主器件数据输出,从器件数据输入;

(2)MISO – 主器件数据输入,从器件数据输出;

(3)SCLK – 时钟信号,由主器件产生;
(4) SS –从器件使能信号,由主器件控制,有的IC会标注为CS(Chip select)。 在点对点的通信中,SPI接口不需要进行寻址操作,且为全双工通信,显得简单高效。
参考技术A   通过通信端口。目前单片机普遍支持的pc机通信端口有rs232和ethernet

  在单片机内依照通信协议写程序就可以和pc进行通信

  现在更有一些适配器,插在pc上,让pc扩展出can, spi, 等端口,这些端口在单片机上很普遍,这样也可以进行通信

  最新的单片机也开始支持usb,某些支持usb的单片机只能读取u盘之类的设备,而另一些同时也可以和pc进行通信。
参考技术B PC就那几种接口,如果非要用SPI的话,需要自己做板卡通过PCI/PCIE插槽实现。建议采用USB方式,速度比较快。本回答被提问者和网友采纳 参考技术C 赞同 ivyxtvv的回答,
单片机与PC机通过SPI通信的实际意义是什么

如果用USB的话,速度会提升很大。个人认为通信关键在于使用最简单、经济的连接方式,实现实用、高效的数据交互!

个人不提倡你用SPI方式实现单片机与PC的通信追问

决定改用USB了,确实省事儿不少

多线程技术的PLC与PC的通讯方式




基于多线程技术的PLC与PC的通讯方式


1.系统构成 


推进系统中,PC机选用工控计算机。它是整个控制系统的核心,是上位机。其主要利用良好的图形用户界面,显示从PLC接收的开关量和控制手柄的位置,进行一些较复杂的数据运算,并且向PLC发出控制指令。 


PLC是该系统的下位机,负责现场高速数据采集(控制手柄的位置),实现逻辑、定时、计数、PID调节等功能,通过串行通讯口向PC机传送PLC工作状态及有关数据,同时从PC机接受指令,向蜂鸣器、指示灯、滑油泵、控制手柄的位置等发出命令,实现PC机对控制系统的管理,提高了PLC的控制能力和控制范围,使整个系统成为集散控制系统。 


2.通讯协议 



计算机与PLC进行通讯时,计算机与PLC之间是以帧为单位进行信息交换的,其中控制字符ENQ、ACK、NAK,可以构成单字符帧发送和接受,其余的信息帧发送和接受时都是由字符STX、命令字、数据、字符ETX以及和校验5部分组成。 


校验和在信息帧的尾部用来判断传输的正确与否,和校验码的计算方法是将命令码到ETX之间的所有字符的ASCⅡ码(十六进制数)相加,取所得和的最低2位数,在后面的通信程序设计里面还会提到。进行差错检验的方法很多,常用的有奇偶校验码,水平垂直冗余校验LRC,目前广泛使用的是CRC校验码,它能查处99%以上18位或更长的突出错误,而在计算机与PLC点对点的短距离通讯时,出错的几率较小,因而采用校验和法,基本能满足要求。 



3.多线程技术及在VC++串口通信程序中的实现 


在Windows的一个进程内,包含一个或多个线程,每个线程共享所有的进程资源,包括打开的文件、信号标识及动态分配的内存等等。


Windows内部的抢先调度程序在活动的线程之间分配CPU时间,Windows区分两种不同类型的线程,一种是用户界面线程(UserInterfaceThread),它包含消息循环或消息泵,用于处理接收到的消息;另一种是工作线程(WorkThread)它没有消息循环,用于执行后台任务、监视串口事件的线程即为工作线程。 


本系统采用MFC编程方法,MFC是把串口作为文件设备来处理的,它用CreateFile()打开串口,并获得一个串口句柄,用SetCommState()进行端口配置,包括缓冲区设置,超时设置和数据格式等。然后调用函数ReadFile()和WriteFile()进行数据的读写,用WaitForSingleObject()监视通信事件。在用ReadFile()和WriteFile()读写串口时,一般采用重叠方式。因为同步I/O方式是当程序执行完毕才返回,这样会阻塞其他线程,降低程序执行效率。而重叠方式能使调用的函数立即返回,I/O操作在后台进行,这样线程就可以处理其他事务,同时也实现了线程在同一串口句柄上实现读写操作。 


使用重叠I/O方式时,线程要创建OVERLAPPED结构供读写函数使用,该结构最重要的成员是hEvent事件句柄。它将作为线程的同步对象使用,读写函数完成时hEvent处于有信号状态,表示可进行读写操作;读写函数未完成时,hEvent被置为无信号。 


利用Windows的多线程技术,在辅助线程中监视串口,有数据到达时依靠事件驱动,读入数据并向主线程报告;并且,依靠重叠读写操作,让串口读写操作在后台运行。 


4.上位计算机通信程序设计 



BOOLCPlcComDlg::ReadFromPLC(char*Read_char,char*Read_address,intRead_bytes) 


{CSerialSerial;//用于串行通讯的类 


if(Serial.Open(1))//初始化串行通讯口COM1 


{Serial.SendData(&ENQ_request,1);//发送联络讯号 


Sleep(20);//等待20ms秒 


Serial.ReadData(&read_BUFFER,1);//读取PLC响应讯号 


if(read_BUFFER==ACK){ 


…… 


Serial.SendData(&STX_start,1);//向PLC发送“开始”标志代码 

Serial.SendData(&CMD0_read,1);//发送“读”命令代码 


datasum_check+=CMD0_read; 


for(i=0;i<4;i++){ 



…… 


Serial.SendData(&ETX_end,1);//发送结束标志代码 


Change_to_ASCII(senddatasum_CHECK,datasum_check);//将“和”转化成ASCⅡ代码 


Sleep(40);//等待PLC的反应 


…… 


Serial.ReadData(&Read_char[i>,1);//读Read_bytes个字节 


if(*readdatasum_CHECK==*readdatasum_check)//“和”效验 


{AfxMessageBox("数据读取成功!"); 


returnTRUE;} 


else{AfxMessageBox("校验错误!"); 


returnFALSE;}} 


} 




以上是关于怎么实现单片机和PC机进行SPI通讯?的主要内容,如果未能解决你的问题,请参考以下文章

STC单片机 SPI通讯,主机不能从从机读取正确的数

单片机的SPI通信怎么用

STM32 和 STC单片机SPI通信字节最后一位出错

51单片机串口通讯

51单片机怎样实现SPI通讯

STM32的SPI从机接收数据错误是怎么回事