打印

串口发送出现在问题求助

[复制链接]
1875|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lxc806705|  楼主 | 2011-7-29 08:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我做了一个AD采样电压测量的板子,程序里面有3个中断:定时器0,定时50ms,记20次做为1个发送串口信息的定时标志
AD中断,采样电压,中断程序很短,大概540个时钟采样一次
串口中断,只发送不接收。
流程是:等待秒标志,标志置位后后打开AD中断,采样电压,完毕后关闭AD中断,这时AD中断里给一个标志。等待AD给出的标志置1,然后开始发送串口数据帧。
帧的结构大概是:0xff 0x02 0x01 0x00 AD数据 0xff,这样
现在的问题是除了开始的0x01,0x00外其他在串口助手里显示都正确,唯独0x01,0x00显示成了0xff,0xff。我加入短延时仍然存在这个问题。
后来我又尝试把IP=0x10,即串口中断为最高优先级级,这首0x01,0x00正确了,但是秒标志出来不了了,估计是定时器0中断无法进入。
抓狂中,求好心人指教!

相关帖子

沙发
lxc806705|  楼主 | 2011-7-29 08:44 | 只看该作者
我用的是STC12C5A60S2这个片子,会跟这个有关系吗?

使用特权

评论回复
板凳
lxc806705|  楼主 | 2011-7-29 09:22 | 只看该作者
为何发的帖子老是没人气啊55555555555555:'(

使用特权

评论回复
地板
delin17| | 2011-7-29 12:20 | 只看该作者
贴程序。。

使用特权

评论回复
5
刘前辈| | 2011-7-29 12:49 | 只看该作者
本帖最后由 刘前辈 于 2011-7-29 12:58 编辑

程序有问题。我实验了一下,无论怎样的优先级设置,串口ISR 和定时器中断都不可能互相影响。一个中断ISR最多开销1ms;看LZ这架势,每个ISR开销了几十ms?!——不可能吧!

LZ发送 0xff 0x02 0x01 0x00 AD数据 0xff 帧时,应该是发送一字节关闭中断等待TI下一字节触发,这个等待空间就可能响应定时器就中断;一般发送一字节间隔1ms,而处理时间只需要1%。1ms 可以干很多事。但是如果程序设计不让出中断,一定要所有字节发完再退出中断,那只好怪自己了。



、、

使用特权

评论回复
6
lxc806705|  楼主 | 2011-8-1 08:27 | 只看该作者
好的,这两天没上网,我贴一下程序大家帮忙看一下啊

使用特权

评论回复
7
lxc806705|  楼主 | 2011-8-1 08:27 | 只看该作者
#include <stc12c5a60s2.h>
#include <intrins.h>

#define uchar unsigned char
#define uint unsigned int

#define ADC_POWER 0x80
#define ADC_FLAG 0x10
#define ADC_START 0x08
#define ADC_SPEED 0x40

sfr ADC_LOW2=0xbe;         //ADC_RESL[1:0]

uchar ch;
uint mscnt,flag,adflag;
unsigned long dath[8],datl[8];

void InitUART()
{
        TMOD=0x21;
        SCON=0x50;
        TH0=0xdc;
        TL0=0x00; //timer 50ms
        TH1=0xfd;
        TL1=0xfd;
        TR0=1;
        TR1=1;
        ET0=1;
        ES=1;
        EA=1;
}

void InitADC()
{
//        P1M1=0xff;
//        P1M0=0x00;                        //P1 as input,high impedance state,for ADC,this can induce the extern interrupt
        P1ASF=0xff;                        //P1 all act as ADC
        ADC_RES=0;
        ADC_LOW2=0;
        ADC_CONTR=0x84;
        _nop_();_nop_();_nop_();_nop_();
}

void send(uchar serial_data)
{
        SBUF=serial_data;
        while(!TI) ;
        TI=0;
}

void timer0_int() interrupt 1
{
        TH0=0xdc;
        TL0=0x00;
        mscnt++;
        if(mscnt==100) {mscnt=0;flag=1;}
}

void adc_int() interrupt 5
{
        ADC_CONTR&=~ADC_FLAG;
        dath[ch]=ADC_RES;
        datl[ch]=ADC_LOW2;
        ch++;
        if(ch==8) {ch=4;adflag=1;EADC=0;ADC_CONTR=0x80;}
        else ADC_CONTR=ADC_POWER|ADC_START|ADC_SPEED|ch;
        _nop_();_nop_();_nop_();_nop_();
}

void main()
{
        unsigned long d4,d5,d6,d7;
        uchar s4[2],s5[2],s6[2],s7[2];
        uchar a,b4,b5,b6,b7,b,check;

        InitUART();
        InitADC();
        ch=4;

        while(1)
        {
                while(!flag) ;

                ADC_CONTR=ADC_POWER|ADC_START|ADC_SPEED|ch;//adc start,from channel 4
                _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
                _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
                EADC=1;

                while(!adflag) ;

                d4=(375*(dath[4]*4+datl[4]))>>7;
                d5=(375*(dath[5]*4+datl[5]))>>7;
                d6=(625*(dath[6]*4+datl[6]))>>10;
                d7=(375*(dath[7]*4+datl[7]))>>8;

                a=(d5>d4)?0x01:0x02;

                b4=((d4<2600)&&(d4>2000))?0x00:0x40;
                b5=((d5<2600)&&(d5>2000))?0x00:0x10;
                b6=((d6<600)&&(d6>400))?0x00:0x04;
                b7=((d7<1300)&&(d7>1000))?0x00:0x01;
                b=b4|b5|b6|b7;

                s4[0]=d4%256;
                s4[1]=d4/256;

                s5[0]=d5%256;
                s5[1]=d5/256;

                s6[0]=d6%256;
                s6[1]=d6/256;

                s7[0]=d7%256;
                s7[1]=d7/256;

                send(0xeb);
                send(0x90);

                send(0x02);         //extern 24v
                send(0x01);
               
                send(0x00);
                send(0x0d);       
                       
                send(s4[0]);
                send(s4[1]);

                send(s5[0]);
                send(s5[1]);

                send(s6[0]);
                send(s6[1]);
                       
                send(s7[0]);
                send(s7[1]);

                send(b);

                send(a);

                check=0x02^0x01^s4[0]^s4[1]^s5[0]^s5[1]^s6[0]^s6[1]^s7[0]^s7[1]^a^b;
                send(check);

                adflag=0;
                flag=0;
        }
}

使用特权

评论回复
8
lxc806705|  楼主 | 2011-8-1 08:31 | 只看该作者
程序有问题。我实验了一下,无论怎样的优先级设置,串口ISR 和定时器中断都不可能互相影响。一个中断ISR最多开销1ms;看LZ这架势,每个ISR开销了几十ms?!——不可能吧!

LZ发送 0xff 0x02 0x01 0x00 AD数据 0xff  ...
刘前辈 发表于 2011-7-29 12:49

我是一个一个字节发送的,主要是搞这一行2没多久,所以程序都写得比较老实哈哈

使用特权

评论回复
9
lxc806705|  楼主 | 2011-8-1 13:04 | 只看该作者
手工顶一下:D

使用特权

评论回复
10
lxc806705|  楼主 | 2011-8-2 08:32 | 只看该作者
刘前辈能否帮看下程序啊

使用特权

评论回复
11
joyme| | 2011-8-2 09:25 | 只看该作者
程序的逻辑顺序混乱,初始化AD的代码放到initADC里,和置位adflag后并处理完AD显示之后,不能在while循环里一直执行

按下面的逻辑重写试试,另建议UARTSend也用中断
while(!adflag)
{
     ADDataProcess();
     while(!flag)
     UARTSend();
     adflag = 0;
     InitADC();
}

使用特权

评论回复
12
lxc806705|  楼主 | 2011-8-2 11:14 | 只看该作者
程序的逻辑顺序混乱,初始化AD的代码放到initADC里,和置位adflag后并处理完AD显示之后,不能在while循环里一直执行

按下面的逻辑重写试试,另建议UARTSend也用中断
while(!adflag)
{
     ADDataProcess();
     w ...
joyme 发表于 2011-8-2 09:25

多谢,我重新调整下循环。

使用特权

评论回复
13
shell.albert| | 2011-8-2 11:21 | 只看该作者
把其他的程序抛开,单独使用AD试试,单独开启中断,看能不能进中断,还有就是中断的开启。

我还得还是要一小段一小段测试都没有问题了,再合成一个整体。

使用特权

评论回复
14
lxc806705|  楼主 | 2011-8-2 13:19 | 只看该作者
我独立做了1个程序,只开三个中断但是吧其中的计算步骤去了然后还是会出现字节错误

使用特权

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

本版积分规则

0

主题

154

帖子

1

粉丝