通讯方式学习——单总线协议(2024.04.09)
参考链接1: 单总线器件DS18B20测温程序该怎么编写?这个视进行了详细讲解!
在此感谢各位前辈大佬的总结,写这个只是为了记录学习大佬资料的过程,内容基本都是搬运的大佬博客,觉着有用自己搞过来自己记一下,如果有大佬觉着我搬过来不好,联系我删。
通讯方式学习——单总线协议(2024.04.09)
- 1、单总线协议是什么?
- 1.1、初始化
- 1.2、写指令
- 1.3、读指令
1、单总线协议是什么?
单总线即one-wire总线,是美国DALLAS公司推出的外围串行扩展总线技术。与SPI、I²C串行数据通信方式不同.它采用单根信号线,既传输时钟又传输数据,而且数据传输是双向的,具有节省I/O口线、资源结构简单、成本低廉、便于总线扩展和维护等诸多优点。
单总线利用一根线实现双向通信。因此其协议对时序的要求较严格,如应答等时序都有明确的时间要求。基本的时序包括复位及应答时序、写一位时序、读一位时序。在复位及应答时序中,主器件发出复位信号后,要求从器件在规定的时间内送回应答信号;在位读和位写时序中,主器件要在规定的时间内读固或写出数据。
1.1、初始化
主机把数据线DQ拉低(置0)并保持最少480us后释放总线(置1),延时15-60us后的60-240us内对数据线电平检测是否为低电平(0),再延时240us保持起始时序的完整。
DQ=1; //数据线DQ初始化,保证万无一失
delay_us(10); //延时一会确保数据线电平稳定
DQ=0; //主机把数据线DQ拉低(置0)
delay_us(100); //延时一会确保数据线电平稳定
DQ=1; //主机把数据线DQ释放(置1)
delay_us(15~60); //延时一会确保数据线电平稳定
if(DQ==1) //判断数据线是否被拉低(应答信号) 从机未作出应答,进入该函数
{DQ_flag = 1; //数据线DQ未被拉低标志
}
delay_us(240); //延时一会确保数据线电平稳定
1.2、写指令
整个写周期:主机先把数据线DQ拉低大于1us表示周期开始,之后若主机想写0,则继续拉低电平最少60us直到写周期结束,然后释放数据线DQ为高电平;若主机想写1,在拉低总线电平1us后就释放总线为高电平直到写收起结束。
注意事项:传送数据时低位在前。
void write_data_8_byte(uchar command)
uchar i; //定义循环变量
for(i=0;i<8;i++) //每次传送1位
{DQ=0; //以主机拉低(置0)数据线DQ开始写DQ=command&0x01; //取最低位做与运算 同时省略了延时delay_us(4); //使从机有时间反应DQ=1; //送完当前位数据后释放总线(置1)command=command>>1; //移位,为下次数据发送做准备
}
1.3、读指令
整个读周期:主机先把数据线DQ拉低大于1us,然后释放数据线DQ。从机若发送0,则把数据线DQ拉低并保持至少从读周期开始的15us,然后释放数据线DQ为高电平;若从机发送1,则在主机释放数据线DQ后不拉低总线(置1)。
注意:主机需要在读周期开始的15us内检测总线电平的高低。
void read_data_8_byte(uchar command)
{uchar i,value; //定义循环变量、局部变量for(i=0;i<8;i++) //每次读1位{DQ=0; //以主机拉低(置0)数据线DQ至少1us开始读当前位数据value =value >>1; //移位兼延时,第一次右移无作用DQ=1; //主机释放数据线DQ,使得从机能够占用数据线DQif(DQ){value = value | 0x80; //将1放在value的最高位}delay_us(60);}return value; //将接收组装好的一个字节返回
}