|
发表于 2014-7-2 16:17:30
|
显示全部楼层
这是我编写某单总线发送数据、接收数据并进行响应的函数。你看看你用定时器,是不是更乱。
发送:
void HDQ_WRITE(uchar val) //写一个字节,低位在前发送,正确无误无需再检查2014.01.16
{
uchar i;
uchar temp;
Delay10us(7); //如果直接发送的话,寄存器地址的第8个数字脉冲没有足够延时
for(i=0;i<8;i++) //导致从低电平变成高电平的时间只有数us。所以延时70us
{
temp=val>>i;
temp&=0x01;
HDQ_TXD=1;
Delay10us(3); //30us
if(temp)HDQ_TXD=0;
Delay10us(8); //80us
HDQ_TXD=0;
Delay10us(8); //80us
}
}
接收并响应:
void exint1() interrupt 2 //INT1中断入口,读取总线数据的寄存器地址。无误无需再检查2014.01.16
{
uchar TMPH,TMPL;
TMPH=0; //高电平计数器
TMPL=0; //低电平计数器
_nop_();
_nop_();
_nop_();
while(HDQ_RXD==0) //进中断后,等待第一个低电平结束,准备测量下一个高电平有效数据的宽度
{
Delay10us(1);
TMPL++;
if(TMPL>25)break; //为防止长时间失去响应设置的中断点
}
_nop_(); //进中断的低电平是TBR信号产生的,注意反向
_nop_();
_nop_();
while(HDQ_RXD) //对高电平的宽度进行测量,以10us进行计数
{
Delay10us(1);
TMPH++;
if(TMPH>25)break; //为防止长时间失去响应设置的中断点
}
if(TMPH<6)ADDR=ADDR|(0x01<<STEP); //如果测得的宽度小于60us则数据位是1
STEP++;
if(STEP==8) //第8个高电平后发送对应的数据
{
EX1=0; //关闭中断1
if(ADDR==0x3)M37512=0; //判断不是M37512芯片
if(ADDR==0x2)M37512=0;
if(ADDR==0x5)M37512=0;
if(ADDR==0x17)M37512=0;
HDQ_WRITE(Pana_data[ADDR]); //根据主机发来的寄存器地址,发出对应的数据
Delay10us(8);
STEP=0;
ADDR=0;
IE1=0; //清除中断1标志位
EX1=1; //使能中断1
}
if(TMPH>25||TMPL>25)STEP=0; //如果不是正常进入的中断,则清除计数以便从头再来
} |
|