打印
[程序源码]

求大家帮忙用51的IO口输出个波形,,我已阵亡

[复制链接]
2070|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 h_8816002 于 2017-1-5 15:19 编辑

大家好!
       我想通过51输出一组波形,但是久久无法成功,找不出问题所在,烦请大家帮我一下,万分感谢。。。。好气啊!
       目标波形:
                    图1    图2
                      大家请看,这个信号的启动信号是一个 120ms的低电平+6ms的高电平,然后
                  图3      图4
                      这是数据位,图3是数据位,图4是数据校验位。
这个控制信号:逻辑1定义为”高电平持续时间:低电平持续时间=3:1“;逻辑0定义为”高电平持续时间:低电平持续时间=1:3“
因此可以读出这个控制信号的数据是 1000 0000(先发送低位)
按照这个规则,我想输入图1-图3为止的波形也就是不输出那个8位校验位,于是我的程序如下:
#include <reg52.h>

sbit sda=P2^4;        //数据总线
unsigned int addr;

void read_xl();

void delay_xms(unsigned int t)        //+76us
{
unsigned char a,b,c;
for(a=0;a<t;a++)
for(b=0;b<3;b++)
for(c=0;c<205;c++);
}


void main()
{
sda=1;
addr=0x80; //装载数据
read_xl();
while(1);
}


void read_xl()
{
unsigned char i;
sda=0;                                //启动序列
delay_xms(120);                  // 120ms
sda=1;
delay_xms(6);
for(i=0;i<8;i++)  //8位数据
{
  sda=1;
  if(addr&1)   //判断数据是0还是1
  {
  delay_xms(6);           //高电平处理
  sda=0;
  delay_xms(2);
  }
  else
  {
  delay_xms(2);          //低电平处理
  sda=0;
  delay_xms(6);
  }
  addr>>=1;                         //数据右移
}
sda=0;
}
可是输出波形是乱七八糟的:  图5    图6
大家看这是输出波形
       启动位是对了,数据从低位开始 0000 0001 ,但是最后这个逻辑1不符合3:1的协议,也就是说接收错了。
请大家教我,我程序里哪里有错误,该怎么改,好纠结,谢谢大家

TEK0012.BMP (76.05 KB )

TEK0012.BMP

TEK0013.BMP (76.05 KB )

TEK0013.BMP

相关帖子

沙发
NE5532| | 2017-1-5 13:09 | 只看该作者
乱七八糟,你到底是定时不准,还是脉冲结构不对?前者校准延时,后者找程序流程问题,请参考《程序调试黑宝书》

使用特权

评论回复
板凳
ningling_21| | 2017-1-5 14:41 | 只看该作者
本帖最后由 ningling_21 于 2017-1-5 14:45 编辑

本来要求是6:2,但是现在是12:4。。。。
可以试试把

  • delay_xms(2);          //低电平处理
  •   sda=0;
  •   delay_xms(6);



改为


  • delay_xms(1);          //低电平处理
  •   sda=0;
  •   delay_xms(3);


使用特权

评论回复
地板
h_8816002|  楼主 | 2017-1-5 15:18 | 只看该作者
ningling_21 发表于 2017-1-5 14:41
本来要求是6:2,但是现在是12:4。。。。
可以试试把

这个已经更正了,现在的问题是波形结构不对,最后末尾的逻辑1是错误的。人惹俺百思不得其解= =

使用特权

评论回复
5
huang51| | 2017-1-5 15:52 | 只看该作者
程序设计思路有问题,要求精准的延时,怎么能用这么不靠普的延时函数来实现呢?换一种思路:如设置一个定时器,开启定时中断,定时周期采用你需要的输出波形的最小脉宽,其它的应该不是问题了吧

使用特权

评论回复
6
bkn1860| | 2017-1-5 16:00 | 只看该作者
用定时器中断搞

使用特权

评论回复
7
ningling_21| | 2017-1-5 16:10 | 只看该作者
h_8816002 发表于 2017-1-5 15:18
这个已经更正了,现在的问题是波形结构不对,最后末尾的逻辑1是错误的。人惹俺百思不得其解= = ...

"逻辑0定义为”高电平持续时间:低电平持续时间=1:3 "

是高电平:低电平= 1:3 还是 低电平:高电平=3:1 ?

楼主好像顺序搞错了

使用特权

评论回复
8
gx_huang| | 2017-1-5 16:14 | 只看该作者
这个不难呀,关键要静下心来。
产生这个波形很容易,解码这个波形,又要处理其它任务,才难一些。

使用特权

评论回复
9
h_8816002|  楼主 | 2017-1-5 16:15 | 只看该作者
ningling_21 发表于 2017-1-5 16:10
"逻辑0定义为”高电平持续时间:低电平持续时间=1:3 "

是高电平:低电平= 1:3 还是 低电平:高电平=3: ...

谢谢你啦,我纠正过来了,是程序执行序列错了,
else
  {
  delay_xms(2);          //低电平处理
  sda=0;
  delay_xms(6);
  }
这里应该先拉低在释放高,笨到用手写了一遍for循环,一个一个波形去画才发现。。唉

使用特权

评论回复
10
h_8816002|  楼主 | 2017-1-5 16:17 | 只看该作者
huang51 发表于 2017-1-5 15:52
程序设计思路有问题,要求精准的延时,怎么能用这么不靠普的延时函数来实现呢?换一种思路:如设置一个定时 ...

嗯,好的,我的坏习惯,,喜欢用延时函数。确实用定时器中断比较精确,直接以最小中断周期的倍数计数中断就行,我这就改过来,谢谢啦

使用特权

评论回复
11
潜龙出山| | 2017-1-5 16:28 | 只看该作者
h_8816002 发表于 2017-1-5 16:17
嗯,好的,我的坏习惯,,喜欢用延时函数。确实用定时器中断比较精确,直接以最小中断周期的倍数计数中断 ...

建议楼主赶紧把思想转换一下,实现非阻塞编程,不要让单片机空转。
如果我让你在编码过程中,同时实现一个LED闪烁,你怎么搞?

使用特权

评论回复
12
strang| | 2017-1-5 17:13 | 只看该作者
延时太浪费CPU资源了,如果在要求不高的情况下可以用

使用特权

评论回复
13
pywmiss| | 2017-1-6 10:04 | 只看该作者
毫秒级的...用定时中断计时吧..
我上次搞一个微秒级的....也是**飞狗跳...
要的是2.5usu总时间内...也是跟你一定的1:3,3:1
后来找了个师傅一起,,,一步步改程序终于搞定了:就是先高电平 ...或者先低电平...都 要考虑到....加上循环回去的时间...因为用的是16M的单片机...时间比较紧

使用特权

评论回复
14
一个拥抱| | 2017-1-6 10:53 | 只看该作者
用定时器输出波形

使用特权

评论回复
15
刺客_阿瑞| | 2017-1-6 12:40 | 只看该作者
建议使用定时器进行控制。

使用特权

评论回复
16
我叫荧火| | 2017-1-12 17:05 | 只看该作者
工作这么久没用过delay_xms

使用特权

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

本版积分规则

22

主题

143

帖子

5

粉丝