51单片机串口通信问题。

2019-07-15 20:39发布

预期实现功能:单片机通过两外部中断计数外部脉冲。两计数脉冲可在数码管上显示。脉冲数可由按键或指令flag发送至PC。出现问题为:不管单片机一何种方法向PC发送数据,只要有外部干扰,能自动向PC发送数据。数码管上显示的数值并不是按我想的15s变化一次。为什么?#include <reg52.h>  #include <string.h>#define uchar unsigned char#define uint  unsigned int
sbit M_RE= P2^5;       //接收器低电平有效sbit M_DE= P2^6;           //驱动器高电平有效sbit KEY1 = P3^2;         //按键S19
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};sbit HC138A0 = P2^0;     sbit HC138A1 = P2^1;    sbit HC138A2 = P2^2;     uchar led[8];
sbit D1=P1^0;          sbit flag=P1^1;          //单片机是否收到主机发过来的指令int Num1=0,Num2=0;m=0,D_all=0,X_all=0;/****************************/
//初始化设置 void coun()             {    EA=1;         //开总中断EX0=1;         //开外部中断0EX1=1;         //开外部中断1IT0=1;         //外部中断0的中断触发控制位:此为下降沿触发方式。IT1=1;         //外部中断1的中断触发控制位:此为下降沿触发方式。    ET0=1; //开定时/计数器T0中断    TR0=1;                 //T0运行控制位,置1,开始工作。           TMOD=0x01;         //T0定时,工作方式选择方式1。    TH0=(65536-50000)/256;         //一个机器周期时间为1/11.0592*12=1.085us        50000机器周期时间为50000*1.085us=54.25msTL0=(65536-50000)%256; }

  //初始化串口void init_serialcomm( void ){ SCON = 0x50 ;       //SCON: serail mode 1, 8-bit UART, enable ucvr   串口模式1,允许接收(选择串口的工作方式和某些控制功能)TMOD = 0x20 ;      //TMOD: timer 1, mode 2, 8-bit reload  定时1,方式2,PCON = 0x80 ;      //SMOD=1  波特率提高一倍 TH1 = 0xFa ;        //Baud:9600 fosc=11.0592MHz //        IE = 0x90 ;        //Enable Serial Interrupt  允许串口中断TR1 = 1 ;           // timer 1 run         // TI=1; ES=1;EA=1;                            }

//延时函数void delay(int z)               {    unsigned char x,y;    for(x=0;x<50;x++)    for(y=z;y>0;y--) ;}
//1ms延时void Delay_1ms(uint i){uchar x,j;for(j=0;j<i;j++)for(x=0;x<=148;x++);}

//向串口发送一个字符 void send_char_com( unsigned char ch){ SBUF=ch;while (TI== 0 );  TI= 0 ; }

//向串口发送一个数组,length为该数组长度 void send_array_com( unsigned char *str, unsigned int length){ uint k= 0 ;do{ send_char_com(*(str + k));   k++;} while (k<length);}

//显示函数   138译码器显示void display()   {  char i;//        X_all=1234; //        D_all=5678;led[0]=table[X_all/1000];    led[1]=table[X_all%1000/100];    led[2]=table[X_all%100/10];    led[3]=table[X_all%10];led[4]=table[D_all/1000];    led[5]=table[D_all%1000/100];    led[6]=table[D_all%100/10];    led[7]=table[D_all%10];
    for( i=0; i<8; i++)  //实现8位动态扫描循环    {             P0 = led;  //将字模送到P0口显示                    switch(i)                           {   case 0:HC138A0=0; HC138A1=0; HC138A2=0;  break;                case 1:HC138A0=1; HC138A1=0; HC138A2=0;  break;            case 2:HC138A0=0; HC138A1=1; HC138A2=0;  break;                            case 3:HC138A0=1; HC138A1=1; HC138A2=0;  break; case 4:HC138A0=0; HC138A1=0; HC138A2=1;  break;                case 5:HC138A0=1; HC138A1=0; HC138A2=1;  break;            case 6:HC138A0=0; HC138A1=1; HC138A2=1;  break;                            case 7:HC138A0=1; HC138A1=1; HC138A2=1;  break;         }        delay(10);}

}//条件发送(按键闭合或收到主机指令,单片机像主机发送指令)void send(){PS=1;if(KEY1 ==0)  {Delay_1ms(30);           //30ms软件防抖           while(!KEY1);
M_RE=1;M_DE=1;            // 串口处于发送状态
send_array_com(led,8);M_RE=0;M_DE=0;         //设置串口再次处于接收状态}
/*        if(flag=1)         //单片机接受到主机上的指令,想主机发送数据。{flag=0;M_RE=1;M_DE=1;            // 串口处于发送状态
send_array_com(led,8);M_RE=0;M_DE=0;         //设置串口再次处于接收状态} */ PS=0;
}
/*************主函数***************/
void main(){P0=table[0];display();D1=0;         //对灯D1赋值,开始时为亮,当有外部中断,则灯灭。
delay(50);         coun();          //初始化init_serialcomm(); //初始化串口    while(1)   {  if(m==300)    //   1200采样时间1分钟,达到时间后停止采样   (300为15s)    {EX0=0;EX1=0;m=0;  
D_all=Num1;X_all=Num2;   X_all-=D_all;Num1=0;Num2=0;EX0=1;EX1=1;
}send();display();


   }   }

/*************中断函数***************/void int0() interrupt 0  using 1{    EX0=0;    Num1++;    EX0=1; D1=1;}
void int1() interrupt 1 using 2{
TH0=(65536-50000)/256;TL0=(65536-50000)%256;m++;
}

void timer0() interrupt 2  using 3{    EX1=0;    Num2++;    EX1=1;}/*
//串口接收中断函数void serial () interrupt 4 using 0{ if (RI){            uchar temp;       RI = 0 ;
temp=SBUF; flag=1;if(temp='a')flag=1;
}  }  */

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
5条回答
yuying2015
1楼-- · 2019-07-16 00:37
粗劣看一下这里就有一个不严谨的错误coun();          //初始化
init_serialcomm(); //初始化串口
yuying2015
2楼-- · 2019-07-16 04:54
程序中共用的寄存器应该用或与操作才不容易犯这种正确的错误。coun()中TMOD设置了定时器0为方式1而在init_serialcomm()设置波特率初始化时又把定时器0设置成了方式0.共用寄存器应该写成TMOD|=0X01;TMOD|=0X10形式就不会因为其他地方没有意识到而被粗心更改
yuying2015
3楼-- · 2019-07-16 07:13
两个函数共用TMOD,你把第二个中的改成TMOD|=0X20
Crystal6927
4楼-- · 2019-07-16 07:45
 精彩回答 2  元偷偷看……
Oliverking
5楼-- · 2019-07-16 12:28
这个不错,多谢楼主

一周热门 更多>