SFuu 发表于 2015-5-18 14:26:21

STC单片机求助!数组向前位移时出现问题.

本帖最后由 SFuu 于 2015-5-18 14:29 编辑

在编程时遇到一个莫名其妙的问题,自己实在是看不出哪里有错,麻烦各位帮忙看一下不胜感激。
如下:

芯片STC15W204S

程序代码如下:
#include "reg51.h"
#include "intrins.h"

typedef unsigned char BYTE;
typedef unsigned int WORD;

#define FOSC 33177600L          //系统频率
//#define FOSC 11059200L          //系统频率
#define BAUD 115200             //串口波特率

#define NONE_PARITY   0       //无校验
#define ODD_PARITY      1       //奇校验
#define EVEN_PARITY   2       //偶校验
#define MARK_PARITY   3       //标记校验
#define SPACE_PARITY    4       //空白校验

#define PARITYBIT NONE_PARITY   //定义校验位

//sfr AUXR= 0x8e;               //辅助寄存器
sfr T2H   = 0xd6;               //定时器2高8位
sfr T2L   = 0xd7;               //定时器2低8位

sfr P_SW1   = 0xA2;             //外设功能切换寄存器1

#define S1_S0 0x40            //P_SW1.6
#define S1_S1 0x80            //P_SW1.7


bit busy;

unsigned char XH,XL,YH,YL,ZH,ZL;
unsigned char dat_in={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned short plus;
unsigned char sum;

void SendData(BYTE dat);
void SendString(char *s);

void delayms(unsigned long ms)                //@11.0592MHz
        {
        unsigned char i, j;

        while(ms--)
                {
                i = 11;
                j = 189;
                while(i--)
                        {
                        while(j--);
                        }
                }
        }

void check()
        {
        if(dat_in==0x55&&dat_in==0x51)
                {
                plus=dat_in+dat_in+dat_in+dat_in+dat_in+dat_in+dat_in+dat_in+dat_in+dat_in;
                sum = (unsigned char)plus&0x0011;
               
                if(dat_in==sum)
                        {
                        XH=dat_in;
                        XL=dat_in;
                        YH=dat_in;
                        YL=dat_in;
                        ZH=dat_in;
                        ZL=dat_in;
                        }              
                }
        }


void incoming(unsigned char in)
        {
        unsigned char n;

        for(n=0;n<10;n++)
                {
                dat_in=dat_in;
                }
        dat_in=in;
        // check();
        }

void main()
{
    ACC = P_SW1;
    ACC &= ~(S1_S0 | S1_S1);    //S1_S0=0 S1_S1=0
    P_SW1 = ACC;                //(P3.0/RxD, P3.1/TxD)
   
//ACC = P_SW1;
//ACC &= ~(S1_S0 | S1_S1);    //S1_S0=1 S1_S1=0
//ACC |= S1_S0;               //(P3.6/RxD_2, P3.7/TxD_2)
//P_SW1 = ACC;
//
//ACC = P_SW1;
//ACC &= ~(S1_S0 | S1_S1);    //S1_S0=0 S1_S1=1
//ACC |= S1_S1;               //(P1.6/RxD_3, P1.7/TxD_3)
//P_SW1 = ACC;

#if (PARITYBIT == NONE_PARITY)
    SCON = 0x50;                //8位可变波特率
#elif (PARITYBIT == ODD_PARITY) || (PARITYBIT == EVEN_PARITY) || (PARITYBIT == MARK_PARITY)
    SCON = 0xda;                //9位可变波特率,校验位初始为1
#elif (PARITYBIT == SPACE_PARITY)
    SCON = 0xd2;                //9位可变波特率,校验位初始为0
#endif

    T2L = (65536 - (FOSC/4/BAUD));   //设置波特率重装值
    T2H = (65536 - (FOSC/4/BAUD))>>8;
    AUXR = 0x14;                //T2为1T模式, 并启动定时器2
    AUXR |= 0x01;               //选择定时器2为串口1的波特率发生器
    ES = 1;                     //使能串口1中断
    EA = 1;

    SendString("STC15F2K60S2\r\nUart Test !\r\n");
    while(1)
                {
                SendData(dat_in);
                SendData(dat_in);
                SendData(dat_in);
                SendData(dat_in);
                SendData(dat_in);
                SendData(dat_in);
                SendData(dat_in);
                SendData(dat_in);
                SendData(dat_in);
                SendData(dat_in);
                SendData(dat_in);


        //        SendData(XH);
        //        SendData(XL);
        //        SendData(YH);
        //        SendData(YL);
        //        SendData(ZL);
                delayms(1000);

                }
}

/*----------------------------
UART 中断服务程序
-----------------------------*/
void Uart() interrupt 4 using 1
{
    unsigned char indata;
        if (RI)
    {
      RI = 0;               //清除RI位
      indata = SBUF;            //P0显示串口数据
                incoming(indata);
               
    }
    if (TI)
    {
      TI = 0;               //清除TI位
      busy = 0;               //清忙标志
    }
}

/*----------------------------
发送串口数据
----------------------------*/
void SendData(BYTE dat)
{
    while (busy);               //等待前面的数据发送完成
    ACC = dat;                  //获取校验位P (PSW.0)
    if (P)                      //根据P来设置校验位
    {
#if (PARITYBIT == ODD_PARITY)
      TB8 = 0;                //设置校验位为0
#elif (PARITYBIT == EVEN_PARITY)
      TB8 = 1;                //设置校验位为1
#endif
    }
    else
    {
#if (PARITYBIT == ODD_PARITY)
      TB8 = 1;                //设置校验位为1
#elif (PARITYBIT == EVEN_PARITY)
      TB8 = 0;                //设置校验位为0
#endif
    }
    busy = 1;
    SBUF = ACC;               //写数据到UART数据寄存器
}

/*----------------------------
发送字符串
----------------------------*/
void SendString(char *s)
{
    while (*s)                  //检测字符串结束标志
    {
      SendData(*s++);         //发送当前字符
    }
}

程序想实现重串口输入一个字节数据,数组dat_in中的每个数据便依次向前移动一位,输入的数据被追加到最后一位dat_in中。并每隔一段时间从串口返回数组dat_n的全部数据。

程序运行以后,串口返回 00 00 00 00 00 00 00 00 00 00 00,
输入FF,串口返回 00 00 00 00 00 00 00 00 00 00 FF,

到这里再输入一个数据,便开始出现问题:
再次输入一个FF,串口返回的数据本应该为 00 00 00 00 00 00 00 00 00 FF FF,接着输入FF应该返回 00 00 00 00 00 00 00 00 FF FF FF 以此类推,输入88 返回 00 00 00 00 00 00 00 FF FF FF 88。

但是奇怪的是,写进芯片,实际上返回的前10位永远为00,最后一位为最新输入的数据。比如依次输入01,02,03则返回00 00 00 00 00 00 00 00 00 00 01,00 00 00 00 00 00 00 00 00 00 02,00 00 00 00 00 00 00 00 00 00 03。

不知道是什么原因。incoming()函数怎么看也没有问题。

但是把incoming()函数修改成下面这种最笨的方法就一切正常了。

void incoming(unsigned char in)
        {
        unsigned char n;

        //for(n=0;n<10;n++)
        //        {
        //        dat_in=dat_in;
        //        }

       
        dat_in=dat_in;
        dat_in=dat_in;
        dat_in=dat_in;
        dat_in=dat_in;
        dat_in=dat_in;
        dat_in=dat_in;
        dat_in=dat_in;
        dat_in=dat_in;
        dat_in=dat_in;
        dat_in=dat_in;
       
        dat_in=in;

        // check();
        }

求助各位高手,这到底是怎么回事。。哪里写错了了吗?数组那样移动,我在编的程序里用着没有任何问题,只不过芯片是89C52。
世界观要被颠覆了,谢谢大家了.

SFuu 发表于 2015-5-18 14:33:52

另外,标题开始不合格,已经修改,但是外面还是显示的原标题,请版主手下留情。。。

lxa0 发表于 2015-5-18 19:42:03

stc的芯片出问题是很正常的啦~~~~~~~~~~~~~`

devcang 发表于 2015-5-19 08:32:42

这个是逻辑问题。

主函数,一直在发

接收时,是中断触发的

会在接收处理的过程,同时发送。。。。。。。。。。。。


--------------------------------------------------------------------------------------------------------------------------------------------------------------
我不同意STC就是一文不值的说法。就算芯片再好,逻辑没有处理好,结果还是一塌糊涂的。STC虽然有问题,但多数情况都可以软件避免。话说回来,楼主使用33MHz,STC确实吃力。

SFuu 发表于 2015-5-19 11:24:27

devcang 发表于 2015-5-19 08:32
这个是逻辑问题。

主函数,一直在发


我的主函数是不停的读取数组dat_n的值 然后周期性发送,只要数组变化,应该在下次发送时就变成新的数据啊。

SFuu 发表于 2015-5-19 11:45:42

devcang 发表于 2015-5-19 08:32
这个是逻辑问题。

主函数,一直在发


33M确实是极限了,没办法,使用的另一个模块的波特率是115200限定死的,试过11M 22M,数据量一大就处理不过来了。
并且这个故障,在我使用11M和22M的时候也仍然存在。模块还没有连接,只是手动发送的单字节数据,就有这种故障。
中断里不使用FOR循环,而是一行行单列,就没有问题,33M也没问题,使用那个模块发送大量数据也没问题,仅仅是偶尔有数据丢失,但是不影响使用。只要是使用FOR循环,就会出现那种问题。
页: [1]
查看完整版本: STC单片机求助!数组向前位移时出现问题.