Protues仿真C51单片机串口通信,发送信息无响应

Protues仿真C51单片机串口通信,发送信息无响应
#include<reg52.h>
#include <math.h>
#define uchar unsigned char 
#define uint unsigned int
#define PI 3.14
sbit ADD_A = P1^0;//channel selection signal
sbit ADD_B = P1^1;
sbit ADD_C = P1^2;
sbit START = P1^4;//start signal. When start:0-1, register clear; when start:1-0, AD convertion starts; when AD converting, start remain 0 
sbit EOC = P1^5;//EOC=1, convertion is over; EOC=0, convertion is in progress
sbit OE = P1^6;//OE=1, output is available; OE=0, output is disavailable
sbit CLK = P1^7;
sbit C_A = P0^0;
sbit C_B = P0^1;
sbit C_C = P0^2;
sbit C_D = P0^3;
sbit EN = P1^3;
uchar getdata;
uchar test = 1;
uchar flag_serial,temp;

//time delay
void delay_ms(uint t)
{
     uint x,y;
     for(x = t;x > 0;x--)
         for(y = 110;y > 0;y--);
}

//AD channel selection
void AD_Channel_Select(uchar channel)
{
    switch(channel)
    {
        case 0:
                    ADD_A = 0;
                    ADD_B = 0;
                    ADD_C = 0;
                    break;
        case 1:
                    ADD_A = 1;
                    ADD_B = 0;
                    ADD_C = 0;
                    break;
        case 2:
                    ADD_A = 0;
                    ADD_B = 1;
                    ADD_C = 0;
                    break;
        case 3:
                    ADD_A = 1;
                    ADD_B = 1;
                    ADD_C = 0;
                    break;
        case 4:
                    ADD_A = 0;
                    ADD_B = 0;
                    ADD_C = 1;
                    break;
        case 5:
                    ADD_A = 1;
                    ADD_B = 0;
                    ADD_C = 1;
                    break;
        case 6:
                    ADD_A = 0;
                    ADD_B = 1;
                    ADD_C = 1;
                    break;
        case 7:
                    ADD_A = 1;
                    ADD_B = 1;
                    ADD_C = 1;
                    break;
        default:
            break;
    }
}

void CD_Channel_Select(uchar C_channel)
{
    switch(C_channel)
    {
        case 0:
                    C_A = 0;
                    C_B = 0;
                    C_C = 0;
                    C_D = 0;
                    break;
        case 1:
                    C_A = 1;
                    C_B = 0;
                    C_C = 0;
                    C_D = 0;
                    break;
        case 2:
                    C_A = 0;
                    C_B = 1;
                    C_C = 0;
                    C_D = 0;
                    break;
        case 3:
                    C_A = 1;
                    C_B = 1;
                    C_C = 0;
                    C_D = 0;
                    break;
        case 4:
                    C_A = 0;
                    C_B = 0;
                    C_C = 1;
                    C_D = 0;
                    break;
        case 5:
                    C_A = 1;
                    C_B = 0;
                    C_C = 1;
                    C_D = 0;
                    break;
        case 6:
                    C_A = 0;
                    C_B = 1;
                    C_C = 1;
                    C_D = 0;
                    break;
        case 7:
                    C_A = 1;
                    C_B = 1;
                    C_C = 1;
                    C_D = 0;
                    break;
        case 8:
                    C_A = 0;
                    C_B = 0;
                    C_C = 0;
                    C_D = 1;
                    break;
        case 9:
                    C_A = 1;
                    C_B = 0;
                    C_C = 0;
                    C_D = 1;
                    break;
        case 10:
                    C_A = 0;
                    C_B = 1;
                    C_C = 0;
                    C_D = 1;
                    break;
        case 11:
                    C_A = 1;
                    C_B = 1;
                    C_C = 0;
                    C_D = 1;
                    break;
        case 12:
                    C_A = 0;
                    C_B = 0;
                    C_C = 1;
                    C_D = 1;
                    break;
        case 13:
                    C_A = 1;
                    C_B = 0;
                    C_C = 1;
                    C_D = 1;
                    break;
        case 14:
                    C_A = 0;
                    C_B = 1;
                    C_C = 1;
                    C_D = 1;
                    break;
        case 15:
                    C_A = 1;
                    C_B = 1;
                    C_C = 1;
                    C_D = 1;
                    break;
        default:
            break;
    }
}

void ad0809()
{
    OE = 1;
    START = 0;//start 0809
    START = 1;
    START = 0;
    delay_ms(1);
    while(!EOC);//wait for end of convertion
    OE = 1;
    getdata = P2;//read data from p2
    OE = 0;    
}

void Timer_Init()
{
    TMOD = 0x22;
    
    TH0 = (256-40);
  TL0 = (256-40);
    ET0 = 1;
    TR0 = 1;

}
void Chuankou_Init()
{
    TH1 = 0xfd;
    TL1 = 0xfd;
    
    TR1 = 1;
    EA = 1;
    ES = 1;
    
    REN = 1;
    SM0 = 0;
    SM1 = 1;
}
void T0_CLK() interrupt 1
{
   CLK =~ CLK;
}

void ser() interrupt 4
{
    RI = 0;
    temp = SBUF;
    flag_serial = 1;
}

void main()
{
    Timer_Init();//timer and SCON initialization
    Chuankou_Init();
    EN = 0;//make 4067 work
    AD_Channel_Select(0);//choose channel of 0809
    delay_ms(10);
    flag_serial=1;
    while(1)
    {
        uchar i=0;
        for(i=0;i<16;i++)
        {
            CD_Channel_Select(i);
            delay_ms(10);
            ad0809();
            if(flag_serial==1)
            {
                ES=0;
                SBUF=getdata;
                while(!TI);
                TI=0;
                ES=1;
            }
        }
        delay_ms(800);
    }
}
仿真接线如下,0809和4067是进行AD转换的

img

将示波器接到单片机P3.1口,仿真结果如下

img

请问问题出在哪里?

中断里改变的全局变量,定义的时候加上volatile以防止优化。比如程序里的flag_serial

下面这个


uchar flag_serial,temp;

在前面加上 volatile 试下

volatile uchar flag_serial,temp;

因为取数据的问题,经常碰到变量被莫名优化了,造成变量或者标志位明明置位,但判断条件不成立的问题

```

max232的收发没接到单片机上,不行你就在线仿真,单步运行程序,看是否执行发送那儿,proteus8以下版本支持和keil在线联调

我按你的代码和原理图仿了一下,串口是可以正常发送的。你示波器那个波形可能是发送的0x00?UART发送0x00的波形就是这样的。发个别的数据试试?

双击AT89C52(我使用的芯片)芯片,把下方附加层次模块的勾勾去掉就可以了。