世俱杯 2025

登录 免费注册 世俱杯 2025 | 行业黑名单 | 帮助
维库电子市场网
技术交流 | 电路欣赏 | 工控天地 | 数字广电 | 通信技术 | 电源技术 | 测控之家 | EMC技术 | ARM技术 | EDA技术 | PCB技术 | 嵌入式系统
驱动编程 | 集成电路 | 器件替换 | 模拟技术 | 新手园地 | 单 片 机 | DSP技术 | MCU技术 | IC 设计 | IC 产业 | CAN-bus/DeviceNe

各位高手帮我看一看这个串行口问题啊!!是什么情况.

作者:win2000_li 栏目:单片机
各位高手帮我看一看这个串行口问题啊!!是什么情况.
#include<reg52.h>
#include<string.h>

#define TBUF_SIZE 4
#define RBUF_SIZE 4

unsigned CHAR tbuf[TBUF_SIZE];//发送缓冲区
unsigned CHAR rbuf[RBUF_SIZE];//接收缓冲区

unsigned CHAR r_head;
unsigned CHAR t_head; //发送缓冲区的头计数器
unsigned CHAR t_len;  //要发送数据的长度
unsigned CHAR TEMP = 0;      //临时计数器
unsigned CHAR remp = 0;      //临时计数器

unsigned CHAR count;
unsigned CHAR code Ret[4] = "00ok";
unsigned CHAR code Err[4] = "0err";
unsigned CHAR rxdata[6];

bit rflag;


/*******串行口初化函数**************/
void com_initialize(void)
{
    EA = 0;            
    t_head  = 0;        //清除接收和发送缓冲区
    t_len = 0;

    PCON    = 0x00;       //SMOD = 0
    SCON    = 0xD0;       //串行口方式3,11位异步收发。允许接收,清除发送中断标志,清除接收中断村志
    T2CON   = 0x34;       //0011,0100定时器2的溢出脉冲作串口发送时钟,和接收时钟.启动定时器2

#if 1   
    RCAP2H  = 0x0ff;                         //22.1184MHZ 单倍速9600
    RCAP2L  = 0x0b8;
#else
    RCAP2H  = 0x0ff;                         //22.1184MHZ 双倍速9600
    RCAP2L  = 0x071;
#endif    

    ES=1;      //允许串行中断/
    TR2 = 1;  //启动T2
    EA = 1;      
}


/*启动发送*/
void com_send_data(unsigned CHAR *senddata, unsigned CHAR len)
{    
    unsigned CHAR i;
    t_len = len;    //发送的长度
    for(i = 0; i < t_len; i++)
    {
        tbuf[i] = senddata[i];
    }
    rflag = 0;
    memset(rbuf,0,4);
    TI = 1;         //开始发送                              
}

unsigned CHAR CHECKSUM(unsigned CHAR *puInBuf, unsigned CHAR puInBufLen)
{
    unsigned CHAR i;
    unsigned CHAR ucRet = 0;
    for (i = 0; i <= puInBufLen-1; i++)
    {
        ucRet ^= puInBuf[i];        
    }
    return(ucRet);
}
/*******************中断处理函数********************/
//串行口中断(完成数据的接收和发送)
void com_isr(void) interrupt 4 using 2
{
     if(RI)
    {
        RI = 0;
        rbuf[r_head++]=SBUF;    
        if(r_head == 4)
        {
            rflag =1;
            r_head = 0;
        }
        /*ch=SBUF;
          if(ch > 127)
          {
              rbuf[count++] = ch;
            CHECKSUM = ch - 128;
          }
          else
          {
              rbuf[count++] = ch;
            CHECKSUM ^= ch;
            if((count == RBUF_SIZE)&&(!CHECKSUM))
            {
                rflag = 1;
                count = 0;
            }
          }
        */
    }
    else if(TI)
    {
        TI = 0;
        if(t_head >= t_len)
        {
            t_head = 0;
        }
        else
        {
            SBUF = tbuf[t_head++];    
        }
    }
}


void main(void)
{
    unsigned int i=10000;
    unsigned CHAR j;
    com_initialize();
    while(1)
    {
        if(rflag)//如果取数标志已置位,就将读到的数从串口发出
        {    
            j = !CHECKSUM(&rbuf, 4);
            SWITCH(j)
            {
                case 0:
                    //P1 = rbuf[1];
                    com_send_data(&Err, 4);
                    while(--i);            
                break;
    
          &nbs
2楼: >>参与讨论
win2000_li
还有!
控制的IO口状态,也不能达到控制的效果啊!!
命令格式:30 30 31 31
第一个是地址,二个是输出,三个是P1.0输出1。四个是校验和

3楼: >>参与讨论
hotpower
有时间看看~~~
 
4楼: >>参与讨论
win2000_li
先谢谢了!!!我可能是还没有把串行口的时序搞清楚啊!!!
自已还要努力!!!

谢谢!!!

希望能指点一下!!!

5楼: >>参与讨论
hotpower
估计是while(--i);搞得鬼.
将其屏蔽掉试试.//while(--i);

再:
while(--i);
先为何i没初值???(首次i=10000,其他i=0xffff)

而且while(--i);可能要丢数据,因为51的串口没有FIFO

6楼: >>参与讨论
win2000_li
改了的,有所改善
但是还有问题啊!

如:
    我发: 00 00 01 01 ---HEX

有时收到: 01 00 00 01 ---HEX

应该收到: 00 00 01 01 ---HEX

把设备重新上电复位后,问题就消除了。

不知为什么?是不是发送数据时,第一次只收到前三个,第二次才补上第一个,但是导致出错啊!!

不好意思!因为第一次搞串口,所以不懂,请大家指点!!!    

7楼: >>参与讨论
hotpower
这就是十六进制发送需要同步的问题
 
8楼: >>参与讨论
win2000_li
那个这问题的解决呢!?
请兄弟指点小弟一下你的思想!!!!

参与讨论
昵称:
讨论内容:
 
 
相关帖子
关于可能遭到痛殴的贴子---菜鸟发贴前必读[转]
再提汇编软复位问题?
问个关于485加TVS的弱弱的问题!
《匠人手记》之三《一阶滤波算法之深入研究》已经发布
用运放LMV324为什么声音会失真???急????


Copyright © 1998-2006 tgdrjb.cn 浙ICP证030469号