三,SPI口的使用
SPI的实现方式有两种,硬件实现和软件实现,本采样系统采用软件实现,也就是IO口模拟SPI协议。下面是手册的说明,具体的介绍本芯片的SPI的具体情况。SPI是单片机与采样模块之间的通信协议,单片机作为主机,采样模块作为从机来进行通信。主机发送命令,而从机是接收命令,返回数据的。
下面是翻译。
****************************************************************************/
串行外围接口(SPI0)
串行外围接口(SPI)模块提供对灵活的fll双工同步串行总线的访问。SPI可以作为
3线或4线模式下的主(时钟驱动器)或辅助(时钟接收器)接口,并支持多个主/辅助设备-
ces在单个SPI总线上。芯片选择(NSS)信号可配置为在二次模式下选择SPI或禁用SPI的输入
在具有多个主接口的环境中的主模式操作,避免了在多个主接口时SPI总线上的争用
设备尝试同时传输数据。NSS也可以在主界面中配置为固件控制的芯片选择输出
模式,或禁用以减少所需的管脚数。其他通用端口L/O引脚可用于选择多个secon
戴瑞装置。
●支持3线或4线主或辅助接口模式
●在任一模式下支持高达12 Mbps的外部时钟频率
●支持所有时钟相位和极性模式
●8位可编程时钟速率(主)
●可编程接收超时(辅助)
●发送和接收时的四字节FIFO
●在同一数据线上支持多个主接口
****************************************************************************/
下图是SPI的四个接口,SCLK,MISO,MOSI,CS等四个脚,这几个脚很关键,实现数据采集就靠他们了。
顺便说一下采样的原理,没用过的小伙伴可以看一下,用过的就跳过就行了。ADC的采样原理,ADC把模拟量变为数字量,用数字量近似表示模拟量,这个过程称为量化。量化误差是ADC的有限位数对模拟量进行量化而引起的误差。实际上,要准确表示模拟量,ADC的位数需很大甚至无穷大。一个分辨率有限的ADC的阶梯状转换特性曲线与具有无限分辨率的ADC转换特性曲线(直线)之间的最大偏差即是量化误差。如下图,
****************************************************************************/
本系统用的AD模块是XPT2046,一共有四个通道,本系统用其中两个通道。如下图,可以看出它的具体的接线方式,还有具体的通道。要把它玩起来,还需要了解它的时序,如下图,有具体的四根线的时序图,接下来就是程序了,如下图
/****************************************************************************
#include"XPT2046.h"
/****************************************************************************
*函数名:SPI_Write
*输 入:dat:写入数据
*输 出:无
*功 能:使用SPI写入数据
****************************************************************************/
void SPI_Write(uchar dat)
{
uchar i;
CLK = 0;
for(i=0; i<8; i++)
{
DIN = dat >> 7; //放置最高位
dat <<= 1;
CLK = 0;//上升沿放置数据
CLK = 1;
}
}
/****************************************************************************
*函数名:SPI_Read
*输 入:无
*输 出:dat:读取 到的数据
*功 能:使用SPI读取数据
****************************************************************************/
uint SPI_Read(void)
{
uint i, dat=0;
CLK = 0;
for(i=0; i<12; i++)//接收12位数据
{
dat <<= 1;
CLK = 1;
CLK = 0;
dat |= DOUT;
}
return dat;
}
/****************************************************************************
*函数名:Read_AD_Data
*输 入:cmd:读取的X或者Y
*输 出:endValue:最终信号处理后返回的值
*功 能:读取触摸数据
****************************************************************************/
uint Read_AD_Data(uchar cmd)
{
uchar i;
uint AD_Value;
CLK = 0;
CS = 0;
SPI_Write(cmd);
for(i=6; i>0; i--); //延时等待转换结果
CLK = 1; //发送一个时钟周期,清除BUSY
_nop_();
_nop_();
CLK = 0;
_nop_();
_nop_();
AD_Value=SPI_Read();
CS = 1;
return AD_Value;
}