搜索
bottom↓
回复: 5

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

[复制链接]

出0入0汤圆

发表于 2015-5-18 14:26:21 | 显示全部楼层 |阅读模式
本帖最后由 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[11]={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[0]==0x55&&dat_in[1]==0x51)
                {
                plus=dat_in[0]+dat_in[1]+dat_in[2]+dat_in[3]+dat_in[4]+dat_in[5]+dat_in[6]+dat_in[7]+dat_in[8]+dat_in[9];
                sum = (unsigned char)plus&0x0011;
               
                if(dat_in[10]==sum)
                        {
                        XH=dat_in[2];
                        XL=dat_in[3];
                        YH=dat_in[4];
                        YL=dat_in[5];
                        ZH=dat_in[6];
                        ZL=dat_in[7];
                        }                
                }
        }


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

        for(n=0;n<10;n++)
                {
                dat_in[n]=dat_in[n+1];
                }
        dat_in[10]=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[0]);
                SendData(dat_in[1]);
                SendData(dat_in[2]);
                SendData(dat_in[3]);
                SendData(dat_in[4]);
                SendData(dat_in[5]);
                SendData(dat_in[6]);
                SendData(dat_in[7]);
                SendData(dat_in[8]);
                SendData(dat_in[9]);
                SendData(dat_in[10]);


        //        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[11]中的每个数据便依次向前移动一位,输入的数据被追加到最后一位dat_in[10]中。并每隔一段时间从串口返回数组dat_n[11]的全部数据。

程序运行以后,串口返回 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[n]=dat_in[n+1];
        //        }

       
        dat_in[0]=dat_in[1];
        dat_in[1]=dat_in[2];
        dat_in[2]=dat_in[3];
        dat_in[3]=dat_in[4];
        dat_in[4]=dat_in[5];
        dat_in[5]=dat_in[6];
        dat_in[6]=dat_in[7];
        dat_in[7]=dat_in[8];
        dat_in[8]=dat_in[9];
        dat_in[9]=dat_in[10];
       
        dat_in[10]=in;

        // check();
        }

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

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2015-5-18 14:33:52 | 显示全部楼层
另外,标题开始不合格,已经修改,但是外面还是显示的原标题,请版主手下留情。。。

出0入0汤圆

发表于 2015-5-18 19:42:03 | 显示全部楼层
stc的芯片出问题是很正常的啦~~~~~~~~~~~~~`

出0入0汤圆

发表于 2015-5-19 08:32:42 | 显示全部楼层
这个是逻辑问题。

主函数,一直在发

接收时,是中断触发的

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


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

出0入0汤圆

 楼主| 发表于 2015-5-19 11:24:27 | 显示全部楼层
devcang 发表于 2015-5-19 08:32
这个是逻辑问题。

主函数,一直在发

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

出0入0汤圆

 楼主| 发表于 2015-5-19 11:45:42 | 显示全部楼层
devcang 发表于 2015-5-19 08:32
这个是逻辑问题。

主函数,一直在发

33M确实是极限了,没办法,使用的另一个模块的波特率是115200限定死的,试过11M 22M,数据量一大就处理不过来了。
并且这个故障,在我使用11M和22M的时候也仍然存在。模块还没有连接,只是手动发送的单字节数据,就有这种故障。
中断里不使用FOR循环,而是一行行单列,就没有问题,33M也没问题,使用那个模块发送大量数据也没问题,仅仅是偶尔有数据丢失,但是不影响使用。只要是使用FOR循环,就会出现那种问题。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 08:26

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表