|
技术交流 | 电路欣赏 | 工控天地 | 数字广电 | 通信技术 | 电源技术 | 测控之家 | 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 于 2007/1/22 10:43:00 发布:
还有! 控制的IO口状态,也不能达到控制的效果啊!! 命令格式:30 30 31 31 第一个是地址,二个是输出,三个是P1.0输出1。四个是校验和 |
3楼: | >>参与讨论 |
作者: hotpower 于 2007/1/22 12:47:00 发布:
有时间看看~~~ |
4楼: | >>参与讨论 |
作者: win2000_li 于 2007/1/22 13:35:00 发布:
先谢谢了!!!我可能是还没有把串行口的时序搞清楚啊!!! 自已还要努力!!! 谢谢!!! 希望能指点一下!!! |
5楼: | >>参与讨论 |
作者: hotpower 于 2007/1/22 16:41:00 发布:
估计是while(--i);搞得鬼. 将其屏蔽掉试试.//while(--i); 再: while(--i); 先为何i没初值???(首次i=10000,其他i=0xffff) 而且while(--i);可能要丢数据,因为51的串口没有FIFO |
6楼: | >>参与讨论 |
作者: win2000_li 于 2007/1/22 17:21:00 发布:
改了的,有所改善 但是还有问题啊! 如: 我发: 00 00 01 01 ---HEX 有时收到: 01 00 00 01 ---HEX 应该收到: 00 00 01 01 ---HEX 把设备重新上电复位后,问题就消除了。 不知为什么?是不是发送数据时,第一次只收到前三个,第二次才补上第一个,但是导致出错啊!! 不好意思!因为第一次搞串口,所以不懂,请大家指点!!! |
7楼: | >>参与讨论 |
作者: hotpower 于 2007/1/22 18:01:00 发布:
这就是十六进制发送需要同步的问题 |
8楼: | >>参与讨论 |
作者: win2000_li 于 2007/1/23 10:00:00 发布:
那个这问题的解决呢!? 请兄弟指点小弟一下你的思想!!!! |
|
|
Copyright © 1998-2006 tgdrjb.cn 浙ICP证030469号 |