打印

51串口通信的一个程序,出现点儿问题,求助!

[复制链接]
2251|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
leaoking|  楼主 | 2009-8-25 10:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这两天在学单片机的串口通信,可是写了一个程序,功能实现不了,21ic的强人帮忙看一下,谢谢!
题目的要求是这样的:
由上位机发送1给单片机时,蜂鸣器以400ms频率发声,发2时以200ms频率发声,发3时以100ms频率发声,发4时关闭蜂鸣器。
#include<reg52.h>
unsigned char a,b;
sbit fmq=P2^3;

void ser() interrupt 4
{
a=SBUF;
b=1;  
}

void init()
{
TMOD=0X20;//设置定时器1为方式2
TH1=0XFD;
TL1=0XFD;//装初值,设定波特率为9600
TR1=1;//启动T1 (确定TCON中的TR1位)
SM0=0;
SM1=1;//确定串口工作方式为方式1(编程SCON寄存器)
EA=1;
ES=1;
}
void delay(unsigned char z)
{
unsigned char x,y;
for(x=100;x>0;x--)
   for(y=z;y>0;y--);
}
void main()
{
init();
REN=1;//(启动串行口接受数据)
while(1)
{
  if(b==1)
  {
   while(!RI);
   RI=0;
   b=0;
    }
   if(a==0X01)
  
   {
    a=0;
    while(1)
    {
     fmq=0;
     delay(400);
     fmq=~fmq;
     delay(400);
    }
   }
   if(a==0X02)
   {
    a=0;
    while(1)
    {
     fmq=0;
     delay(200);
     fmq=~fmq;
     delay(200);
    }
   }
   if(a==0X03)
   {
    a=0;
    while(1)
    {
     fmq=0;
     delay(100);
     fmq=~fmq;
     delay(100);
    }
   }
   if(a==0X04)
   {
    a=0;
    while(1)
    {
     fmq=1;
    }
   }
  }   
}

程序的结果是这样的,当第一次第二次发送数据的时候,程序能够按照预期的走,但是到第三次发送数据的时候,蜂鸣器没有反应,复位之后,再发送,好使。

相关帖子

沙发
emailli| | 2009-8-25 17:22 | 只看该作者
这个程序架构存在严重问题。

先不说这个程序架构的问题。

先说说你这个程序本身写的问题吧。

你的
while(1)
    {
     fmq=0;
     delay(100);
     fmq=~fmq;
     delay(100);
    }
这几个循环怎么退出???

使用特权

评论回复
板凳
for_fun| | 2009-8-25 20:05 | 只看该作者
同意2楼的说法:你的循环一旦进入,无法退出!所以复位之后在发送才好使!
看看我的程序怎么样?

#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit fm=P2^3;
uint a,flag,count;
void init()
{
        TMOD=0x20;//设置定时器T1为工作方式2
        TH1=0xfd;//装初始值设置波特率为:9600bps
        TL1=0xfd;
        TR1=1;
        SM0=0;
        SM1=1;
        REN=1;
        EA=1;
        ES=1;
}

void delay_ms(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
}

void main()
{
        init();
        while(1)
        {
                if(flag==1)//如果标志位置1,说明接收到数据了
                {
                        flag=0;
                        while(a=='1')//发送1给单片机时,蜂鸣器以400ms频率发声
                        {
                                delay_ms(400);
                                fm=~fm;
                        }
                        while(a=='2')//发2时以200ms频率发声
                        {
                                delay_ms(200);
                                fm=~fm;
                        }
                        while(a=='3')//发3时以100ms频率发声
                        {
                                delay_ms(100);
                                fm=~fm;
                        }
                        while(a=='4')//发4时关闲蜂鸣器
                        {
                                fm=1;
                        }       
                }
        }
}

void ser() interrupt 4
{
        RI=0;
        a=SBUF;//单片机接收到数据后,将数据传入变量a
        flag=1;//标志位置1
}

使用特权

评论回复
地板
etz2009| | 2009-8-25 21:00 | 只看该作者
学习一下
  楼上分析的有道理

使用特权

评论回复
5
for_fun| | 2009-8-25 21:22 | 只看该作者
回4楼: 我的思路和lz差不多,只是给循环加了个退出条件!

使用特权

评论回复
6
alger2009| | 2010-1-19 14:04 | 只看该作者
看到你的程序头有点大,建议注意格式

使用特权

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

本版积分规则

个人签名:我既然学的是电子就一定要成为电子工程师!

7

主题

56

帖子

0

粉丝