总线时序
所谓总线时序,即CPU通过总线进行操作(读/写、释放总线、中断响应)时,总线上各信号之间在时间顺序上的配合关系,它是同CPU的操作功能有关的。微处理器所完成的操作可分为如下几种:
1.系统复位和启动操作
2.最小方式下的总线读时序
3.最小方式下的总线写时序
4.最小方式下的总线保持
5. 外部中断响应时序
6.最大方式下的总线读时序
7.最大方式下的总线写时序
8.最大方式下的总线请求/允许时序
DSP芯片TMS320F2812 DSP片外扩展 64K * 16位SRAM(基本配置),最大可扩展到512K * 16位。内部RAM不够用时,用来扩充内存,当然是并行的。
总线制是2根线控制很多根,多线制是每个控制点都有单独的线
总线 是火灾自动报警系统信号传输线路与消防联动系统合二为一,即在一个回路中既有探测器、手动报警按钮,又有控制消防联动设施动作与接受动作回授信号的控制模块回路。也就是设备是并联在一根总线上的
本文主要介绍了目前工业自动化控制系统中广泛使用的几种现场总线及其总线电缆的特点,并以基金会现场总线FF-H1(低速)和Profibus PA总线电缆为例,探讨了现场总线电缆的设计。
MIC总线是专门为了解决现代军事及工业领域中极其复杂和恶劣的工作环境下电力/数据的分配和管理而开发的一种具有结构简单及高可靠性的现场总线;在详细分析MIC总线的体系结构和通信协议之后,提出了基于PXI总线体系结构的MIC总线通讯模块的软硬件设计方案;系统可通过PXI总线灵活配置MIC的各种通讯模式参数,具有即插即用、高可靠性和小型化易集成等特点;实验证明,主模块PIM工作模式与远程从模块间数据通讯稳定且可靠,对国内MIC总线的研究与应用有重要意义。
在做 通信过程中,我们很少会用到这样方法,一般在我们选择MCU的时候都会带有你所需要的通信接口。但是,对于一些简单的通信应该用的场合,一 般在一些 的数据通信过程中,传感器厂商会将通信协议做一些改变,这些通信协议也没有一个标准的协议规定。以至于传感器的兼容性很差,甚至有时候找不 到能够与其通信的MCU,这个时候有一种方法就是用 / 来模拟通信总线(由于I/O速度的限制一般只适用于低速的通信总线)的 。之前,用I2C通信做一个温湿度测量的工程,本篇文章就以一个例子来看看如何用I/O口对总线时序进行模拟。
我们平时计算机常用的RS232/工作在异步工作状态时是有严格的数据时钟限制,也就是我们所说的波特率,通信的两个设备有相同的波特率才能正确的通信。对于同步通信一般没有严格的时间限制,总线通过高低电平来分辨数据是"0"还是"1",有两个关键的时刻:上升沿,下降沿。它 是用过上升沿和下降沿的时刻来读写数据的,也就是说这样的话通信频率不是固定的,因为通信的设备"数"的是上升沿和下降沿的数目,然后读写数据线上的数 据。笔者做过实验,将I2C通信的频率降到了10Hz左右,这样用能够很好的捕捉到每一个时钟,通信的结果也是正确的。
好了,直接来看案例吧。
通常我们的I2C的通信时序应该如下图所示,在时钟线拉高的情况下,将数据线拉低就会产生一个启动信号。但是传感器SHT的启动信号却是一个数据线拉低后,时钟线产生一个脉冲,而后再将数据线拉高,这样做的好处是在一定程度上确保了总线正确的启动,但是几乎与之匹配的MCU。这个时候就需要通过I/O模拟的方式来与SHT11完成通信。
#define IIC_SCL RC0 //I2C时钟线
#define IIC_SDA RC1 //I2C数据线
#define IIC_SCL_DIR TRISC0 //I2C时钟线传输方向
#define IIC_SDA_DIR TRISC1 //I2C数据线传输方向
#define PORT_INPUT 1
#define PORT_OUTPUT 0
#define IIC_SCL_HIGH() IIC_SCL_DIR = PORT_INPUT //时钟线拉高
#define IIC_SCL_LOW() IIC_SCL_DIR = PORT_OUTPUT;IIC_SCL=0//时钟线拉低
#define IIC_SDA_HIGH() IIC_SDA_DIR = PORT_INPUT //数据线拉高
#define IIC_SDA_LOW() IIC_SDA_DIR = PORT_OUTPUT;IIC_SDA=0//数据线拉低
/***************
*SHT11启动时序
***************/
void SHT_START(void)
{
IIC_SCL_HIGH();
IIC_SDA_HIGH();
delay_us(5);
IIC_SDA_LOW();
delay_us(5);
IIC_SCL_LOW();
delay_us(5);
IIC_SCL_HIGH();
delay_us(5);
IIC_SDA_HIGH();
delay_us(5);
IIC_SCL_LOW();
}
/***************
*SHT11发送数据时序
***************/
void SHT_SEND(uchar data)
{uchar i,data1;
for(i=0;i<8;i++)
{
data1=data<<i;
if(!(data1&0x80))
IIC_SDA_LOW();
if(data1&0x80)
IIC_SDA_HIGH();
IIC_SCL_LOW(); //写完1位数据将时钟线拉低,等待发送
delay_us(5);
IIC_SCL_HIGH(); //时钟线上升沿,发送1位数据
delay_us(5); //等待1位数据发送完成
}
IIC_SCL_LOW();
IIC_SDA_HIGH(); //8位数据发送完成,数据线拉高,等待SLAVE器件响应
delay_us(5);
IIC_SCL_HIGH(); //时钟线拉高,产生上升沿读取数据线是否SLAVE器件有响应
//while(IIC_SDA==1);
delay_us(5);
IIC_SCL_LOW();
IIC_SDA_HIGH(); //数据线拉高,时钟线拉低,等待转换完成
}
/***************
*SHT11接收数据时序
***************/
uint SHT_REC(void)
{
uint i;
uint REC1=0,REC0=0,REC=0;
for(i=0;i<8;i++)
{
IIC_SCL_HIGH(); //转换完成,SLAVE器件将数据线拉低,时钟线产生上升沿读取高8位数据
REC1=(REC1<<1)+IIC_SDA;
delay_us(5);
IIC_SCL_LOW(); //将时钟线拉低,等待下一个上升沿的到来
delay_us(5);
}
SHT_ASK(); //高8位数据接收完毕,发送应答信号
for(i=0;i<8;i++)
{
IIC_SCL_HIGH(); //转换完成,SLAVE器件将数据线拉低,时钟线产生上升沿读取低8位数据
REC0=(REC0<<1)+IIC_SDA;
delay_us(5);
IIC_SCL_LOW();
delay_us(5);
}
SHT_STOP(); //低8位数据接收完毕,结束
REC=(REC1<<8)+REC0;
return REC;
}
/***************
*SHT11应答时序
***************/
void SHT_ASK(void)
{
IIC_SCL_LOW();
IIC_SDA_LOW(); //数据线拉低
delay_us(5);
IIC_SCL_HIGH(); //时钟线拉高才生应答信号
delay_us(5);
IIC_SDA_HIGH();
IIC_SCL_LOW();
delay_us(5);
}
/***************
*SHT11停止时序
***************/
void SHT_STOP(void)
{
IIC_SDA_HIGH();
IIC_SCL_LOW();
delay_us(5);
IIC_SCL_HIGH();
delay_us(5);
IIC_SDA_HIGH();
IIC_SCL_LOW();
}
原文链接: