打印
[AVR单片机]

关于单总线通讯问题

[复制链接]
3313|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
406554677|  楼主 | 2011-6-3 22:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近一直在写单总线 和DS1990 iButton卡通讯的问题.在网上参考了很多例子都没有解决,烦死我了,在这里想请教一下各位,我的程序到底哪里出错了(本人初学,暂时先读出序列号前8位,看看到底怎么和IB卡通讯的.)拜托各位帮下忙.感激不尽啊.(使用ATMEGA48,内部8M晶振)#include<avr/io.h>
#include<util/delay.h>
#include<yanshi.h>
#include<avr/interrupt.h>
#define uchar unsigned char
#define uint unsigned int
#define set1(a,b) a|=(1<<b)
#define set0(a,b) a&=~(1<<b)
void w1_init(void)   //复位
{

DDRD=set0(DDRD,PD2);

while(PIND&0X04);

DDRD=set1(DDRD,PD2);

PORTD=set1(PORTD,PD2);

_delay_us(1);

PORTD=set0(PORTD,PD2);//      

_delay_us(550);//延时至少480us

DDRD=set0(DDRD,PD2);//释放数据线            

_delay_us(60);//延时大于60us

while(PIND&0X04);

_delay_us(500);//延时保证时序完整性        

DDRD=set1(DDRD,PD2);

PORTD=set1(PORTD,PD2);

PORTD=set0(PORTD,PD2);
}
void write1(void)
{

DDRD=set1(DDRD,PD2);//拉成低电平

PORTD=set1(PORTD,PD2);

_delay_us(1);

PORTD=set0(PORTD,PD2);

_delay_us(5);//保持至少1us
  DDRD=set0(DDRD,PD2);//释放数据线

_delay_us(65);//等待足够时间使da1990采样数据线

DDRD=set1(DDRD,PD2);//拉成低电平

PORTD=set1(PORTD,PD2);

_delay_us(1);

PORTD=set0(PORTD,PD2);
}
void write0(void)
{

DDRD=set1(DDRD,PD2);//拉成低电平

PORTD=set1(PORTD,PD2);

_delay_us(1);

PORTD=set0(PORTD,PD2);

_delay_us(65);//等待足够时间使ds1990采样数据线

DDRD=set1(DDRD,PD2);//拉成低电平

PORTD=set1(PORTD,PD2);

_delay_us(1);

PORTD=set0(PORTD,PD2);

}
void write_ds1990(uchar command)
{

uchar n=0;

for(n=0;n<8;n++)

{

if(command&0x01)

write1();

else

write0();

command>>=1;

_delay_us(2);

}
}

uchar ds1990_bitread(void)
{

DDRD=set1(DDRD,PD2);

PORTD=set1(PORTD,PD2);

_delay_us(1);

PORTD=set0(PORTD,PD2);

_delay_us(2);//保持至少1us

DDRD=set0(DDRD,PD2);//释放数据线

_delay_us(8);//延时使主机再15us的后阶段读取数据线

if(PIND&0x04)

{

return 1;

}

else

{

return 0;

}
  DDRD=(DDRD,PD2);

PORTD=set1(PORTD,PD2);

PORTD=set0(PORTD,PD2);


}

uchar ds1990_byteread(void)
{

uchar n,Readback=0;

for(n=0;n<8;n++)

{

Readback>>=1;

if(ds1990_bitread())

Readback|=0x80;

_delay_us(61);

}

return Readback;
}                        

uchar main(void)
{

while(1)

{
        sei();

uchar a;

uchar b;

        w1_init();
        write_ds1990(0x33);
        DDRD=set1(DDRD,PD0);
        b=ds1990_byteread();
for(a=0;a<8;a++)
{

if((b&0x01))

{

PORTD=set1(PORTD,PD0);

delay_nms(1000);

PORTD=set0(PORTD,PD0);

delay_nms(1000);

}

else

{

PORTD=set1(PORTD,PD0);

  delay_nms(100);

  PORTD=set0(PORTD,PD0);

  delay_nms(100);
                          PORTD=set1(PORTD,PD0);

  delay_nms(100);

  PORTD=set0(PORTD,PD0);

  delay_nms(1000);

}

b>>=1;

}
}
}

相关帖子

沙发
NE5532| | 2011-6-5 10:18 | 只看该作者
有示波器没?

使用特权

评论回复
板凳
joyme| | 2011-6-7 15:56 | 只看该作者
关于1-wire通讯,官网上有例子,网上也有源码参考
你只需将延时函数和通讯口设置好就应该没有问题

另硬件上是否有问题,上拉电阻一定要接的

使用特权

评论回复
地板
airwill| | 2011-6-11 09:23 | 只看该作者
我反感搞这么多 delay 的代码.
因为一旦有中断, 你的 delay 就不准了.
我推荐, 利用 AVR 不能中断嵌套的特性, 直接放在中断里响应时间和信号的变化.

使用特权

评论回复
5
hotpower| | 2011-6-14 21:26 | 只看该作者
用uart做硬件单总线控制器就不用delay了

使用特权

评论回复
6
79424066| | 2011-6-17 10:02 | 只看该作者
单总线通信主要是延时精确。

使用特权

评论回复
7
李冬发| | 2011-6-19 15:41 | 只看该作者
用uart做硬件单总线控制器就不用delay了
hotpower 发表于 2011-6-14 21:26

对MCU有要求。标准51核基本无法实现。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

1

帖子

1

粉丝