p3.3模拟串口接收 救命呀

lg159027   2008-7-7 22:35 楼主
这样子是可以的,没有用到中断口,如果程序外的理事多点就会出问题的,那么需要用到外部中断
#include
#include   
#include   
#include   

#define uint unsigned int
#define uchar unsigned char
//#define REN_485 P21  //为0则可以接受,否则发送
#define TIMER0_ENABLE TL0=TH0; TR0=1;
#define TIMER0_DISABLE TR0=0;
unsigned char  S485_SEND_BUFFER[80] ,rev_num;

code unsigned char C51BOX2[3]_at_ 0x43 ;

bit          REN_485         ;
//#define F_TM F0
bit F_TM;
uchar time_count;
sbit BT_SND =P1^0;
sbit BT_REC =P3^3;

sbit ACC0= ACC^0;
sbit ACC1= ACC^1;
sbit ACC2= ACC^2;
sbit ACC3= ACC^3;
sbit ACC4= ACC^4;
sbit ACC5= ACC^5;
sbit ACC6= ACC^6;
sbit ACC7= ACC^7;

void IntTimer0() interrupt 1 using 1
{
F_TM=1;
time_count++;
}

//发送一个字符
void PSendChar(uchar inch)
{
  
  uchar ii;
  time_count=0;
  REN_485=1;
  ii=0;
  F_TM=0;
  BT_SND=0; //start bit
  TIMER0_ENABLE; //启动
  while(!F_TM);

  while(ii<8)
  {
      if(inch&1)
       {
         BT_SND=1;
       }
      else
       {
         BT_SND=0;
        }
       F_TM=0;
      while(!F_TM);
      ii++;
      inch>>=1;
   }
  BT_SND=1;
  F_TM=0;
  while(!F_TM);
  TIMER0_DISABLE; //停止timer
}

//接收一个字符
uchar PGetChar()
{
uchar rch,ii;
TIMER0_ENABLE;
F_TM=0;
ii=0;
rch=0;
while(!F_TM); //等过起始位

while(ii<8)
{
  rch>>=1;
  if(BT_REC)
  {
   rch|=0x80;
  }
  ii++;
  F_TM=0;
  while(!F_TM);
}
F_TM=0;
while(!F_TM)
{
  if(BT_REC)
  {
   break;
  }
}
TIMER0_DISABLE; //停止timer
return rch;
}

//检查是不是有起始位
bit StartBitOn()
{
return (BT_REC==0);

}

void main()
{
uchar gch,i;
TMOD=0x22; //定时器1为工作模式2(8位自动重装),0为模式2(8位8位自动重装)
PCON=00;
TR0=0; //在发送或接收才开始使用
TF0=0;
TH0=0xA0;
TL0=0xA0;
ET0=1;
EA=1;

rev_num=0 ;        

        
while(1)
{      
    REN_485=0;
  if(StartBitOn())
  {
      
         gch=PGetChar();
         if (gch>0)
         {
            S485_SEND_BUFFER[rev_num]        = gch ;
            rev_num++  ;
          }
         if  (rev_num>= 10 )
          {
        for (i=0;i<= rev_num;i++)
                {
                   PSendChar(S485_SEND_BUFFER);
                   S485_SEND_BUFFER=0 ;
                }
           rev_num =0;
          }
  }
}
}
请兄弟们解难呀,我用外部中断去处理了,总是收不到数呢,
#include
#include   
#include   
#include   

#define uint unsigned int
#define uchar unsigned char
//#define REN_485 P21  //为0则可以接受,否则发送
#define TIMER0_ENABLE TL0=TH0; TR0=1;
#define TIMER0_DISABLE TR0=0;
unsigned char  S485_SEND_BUFFER[80] ,rev_num;

code unsigned char C51BOX2[3]_at_ 0x43 ;

bit          REN_485,Rev_falg         ;
//#define F_TM F0
bit F_TM;
uchar time_count;
sbit BT_SND =P1^0;
sbit BT_REC =P3^3;

sbit ACC0= ACC^0;
sbit ACC1= ACC^1;
sbit ACC2= ACC^2;
sbit ACC3= ACC^3;
sbit ACC4= ACC^4;
sbit ACC5= ACC^5;
sbit ACC6= ACC^6;
sbit ACC7= ACC^7;

void PGetChar() ;
void PSendChar(uchar inch) ;

void IntTimer0() interrupt 1 using 1
{
        F_TM=1;

}

void S485_ini1(void) interrupt 2 using 3
{
     EX1=0;                      //关闭中断口1
          Rev_falg =1 ;
        BT_REC=0  ;
        PGetChar() ;
}

//发送一个字符
void PSendChar(uchar inch)
{
  
  uchar ii;
  time_count=0;
   rev_num=0 ;
  REN_485=1;
  ii=0;
  F_TM=0;
  BT_SND=0; //start bit
  TIMER0_ENABLE; //启动
  while(!F_TM);

  while(ii<8)
  {
      if(inch&1)
       {
         BT_SND=1;
       }
      else
       {
         BT_SND=0;
        }
       F_TM=0;
      while(!F_TM);
      ii++;
      inch>>=1;
   }
  BT_SND=1;
  F_TM=0;
  while(!F_TM);
  TIMER0_DISABLE; //停止timer
}

//接收一个字符
void PGetChar()
{
uchar rch,ii;
//TIMER0_ENABLE;
F_TM=0;
ii=0;
rch=0;
while(!F_TM); //等过起始位

while(ii<8)
{
  rch>>=1;
  if(BT_REC)
  {
   rch|=0x80;
  }
  ii++;
  F_TM=0;
  while(!F_TM);
}
F_TM=0;
while(!F_TM)
{
  if(BT_REC)
  {
   break;
  }
}
TIMER0_DISABLE; //停止timer
  S485_SEND_BUFFER[rev_num]        = rch;
  rev_num++  ;

EX1=1;  
}

//检查是不是有起始位
bit StartBitOn()
{
return (BT_REC==0);

}

void main()
{
uchar gch,i;
TMOD=0x22; //定时器1为工作模式2(8位自动重装),0为模式2(8位8位自动重装)
PCON=00;
TR0=0; //在发送或接收才开始使用
TF0=0;
TH0=0xA0;
TL0=0xA0;
ET0=1;
   EX1=1;                      //开中断口1
EA=1;

rev_num=0 ;        

          Rev_falg=0 ;      
while(1)
{      


}
}
怎么办呀

回复评论 (4)

你可以先拿示波器量一下看外部中断脚有没有中断信号 ,如果连中断信号都没有,当然不会有数据的
点赞  2008-7-8 14:40
有外部中断信号 但是不能执行到定时器中断,好奇怪呢
点赞  2008-7-8 14:47
有外部中断信号,但你能确定它进int1中断程序了吗?
还有:
....
//接收一个字符
void PGetChar()
{
uchar rch,ii;
//TIMER0_ENABLE; >>>>>>>>>这句为什么要注释掉呢?这样不是没人启动定时器了吗?
F_TM=0;
ii=0;
rch=0;
while(!F_TM); //等过起始位
....
点赞  2008-7-9 14:54
先改这个看效果再说
void PGetChar()
{
uchar rch,ii;
//TIMER0_ENABLE;  <----这个被注释掉了。


你的程序架构比较混乱。
在外1里面调用PGetChar(),在PGetChar里面等定0中断。这里面的中断优先级和中断嵌套都很复杂呀。怎么想起来的?

调试方法:用一个按键,按照串口协议来模拟串口输入,这样时序很长,你可以用调试器跟踪,也可以输出个什么来判断。其实就是波特率特别特别小而已。
点赞  2008-7-9 16:23
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复