单片机串口通信问题。只能发送,不能接收是什么原因?附程序
#include<c8051f020.h>/*SFR定义*/#defineBAUDRATE9600/*UART0的波特率*/#defineSYSCLK22118400/*...
#include <c8051f020.h> /*SFR定义*/
#define BAUDRATE 9600 /*UART0的波特率*/
#define SYSCLK 22118400 /*系统时钟*/
void SYSCLK_Init (void);
void PORT_Init (void);
void UART0_Init (void);
void delay(unsigned int m);
bit ReceiveBit; /*接收标志位*/
unsigned char temp;
void main(void)
{
WDTCN = 0xde; /*关看门狗*/
WDTCN = 0xad;
SYSCLK_Init (); /*初始化系统时钟*/
PORT_Init (); /*初始挂交叉开关和I/O口*/
UART0_Init (); /*初始化UART0*/
EA=1;
ES0=1;
while(1)
{
while (ReceiveBit==1)
{ /*是否接收到一个数据*/
ES0=0; /*关串口中断0*/
EA=0; /*关总中断*/
ReceiveBit=0; /*清接收标志位*/
delay(60000); /*延时*/
delay(60000);
delay(60000);
SBUF0=temp; /*将接收到数据送出*/
while(TI0==0); /*发送标志位是否产生*/
TI0=0; /*清发送标志位*/ /*是否接收到一个数据*/
}
}
}
void SYSCLK_Init (void)
{
int i; /*延时计数器*/
OSCXCN = 0x67; /*打开外部晶体振荡器*/
for (i=0; i < 256; i++) ; /*延时*/
while (!(OSCXCN & 0x80)) ; /*查询外部晶体是否稳定起振*/
OSCICN = 0x88; /*用外部晶体作为系统时钟,并使能时钟丢失检测*/
}
void PORT_Init (void)
{
XBR0 = 0x04; /*使能UART0*/
XBR1 = 0x00;
XBR2 = 0x40; /*使能交叉开关和弱上拉*/
P0MDOUT |= 0x01; /*使能TX0作为推挽输出*/
}
void UART0_Init (void)
{
SCON0 = 0x50; /*SCON0:模式1,8位UART,时能RX*/
TMOD = 0x20; /*TMOD: 定时器工作再模式2, 8位重载*/
TH1 = -(SYSCLK/BAUDRATE/16); /*设置定时1用作波特率的重载值*/
TR1 = 1; /*开定时器1*/
CKCON |= 0x10; /*定时器1用系统时钟作为它的时基*/
PCON |= 0x80; /*SMOD00 = 1*/
}
/*串口中断0子程序*/
void UART0_ISR (void) interrupt 4
{
if(!TI0) //是发送中断还是接收中断
{
RI0 = 0; /*清接收标志位*/
temp =SBUF0; /*保存接收到的数据*/
ReceiveBit=1; /*置接收标志*/
}
TI0 = 0; /*清发送标志位*/
}
/*延时子程序*/
void delay(unsigned int m)
{
unsigned int n;
n=0;
while(n < m)
{n++;}
return;
} 展开
#define BAUDRATE 9600 /*UART0的波特率*/
#define SYSCLK 22118400 /*系统时钟*/
void SYSCLK_Init (void);
void PORT_Init (void);
void UART0_Init (void);
void delay(unsigned int m);
bit ReceiveBit; /*接收标志位*/
unsigned char temp;
void main(void)
{
WDTCN = 0xde; /*关看门狗*/
WDTCN = 0xad;
SYSCLK_Init (); /*初始化系统时钟*/
PORT_Init (); /*初始挂交叉开关和I/O口*/
UART0_Init (); /*初始化UART0*/
EA=1;
ES0=1;
while(1)
{
while (ReceiveBit==1)
{ /*是否接收到一个数据*/
ES0=0; /*关串口中断0*/
EA=0; /*关总中断*/
ReceiveBit=0; /*清接收标志位*/
delay(60000); /*延时*/
delay(60000);
delay(60000);
SBUF0=temp; /*将接收到数据送出*/
while(TI0==0); /*发送标志位是否产生*/
TI0=0; /*清发送标志位*/ /*是否接收到一个数据*/
}
}
}
void SYSCLK_Init (void)
{
int i; /*延时计数器*/
OSCXCN = 0x67; /*打开外部晶体振荡器*/
for (i=0; i < 256; i++) ; /*延时*/
while (!(OSCXCN & 0x80)) ; /*查询外部晶体是否稳定起振*/
OSCICN = 0x88; /*用外部晶体作为系统时钟,并使能时钟丢失检测*/
}
void PORT_Init (void)
{
XBR0 = 0x04; /*使能UART0*/
XBR1 = 0x00;
XBR2 = 0x40; /*使能交叉开关和弱上拉*/
P0MDOUT |= 0x01; /*使能TX0作为推挽输出*/
}
void UART0_Init (void)
{
SCON0 = 0x50; /*SCON0:模式1,8位UART,时能RX*/
TMOD = 0x20; /*TMOD: 定时器工作再模式2, 8位重载*/
TH1 = -(SYSCLK/BAUDRATE/16); /*设置定时1用作波特率的重载值*/
TR1 = 1; /*开定时器1*/
CKCON |= 0x10; /*定时器1用系统时钟作为它的时基*/
PCON |= 0x80; /*SMOD00 = 1*/
}
/*串口中断0子程序*/
void UART0_ISR (void) interrupt 4
{
if(!TI0) //是发送中断还是接收中断
{
RI0 = 0; /*清接收标志位*/
temp =SBUF0; /*保存接收到的数据*/
ReceiveBit=1; /*置接收标志*/
}
TI0 = 0; /*清发送标志位*/
}
/*延时子程序*/
void delay(unsigned int m)
{
unsigned int n;
n=0;
while(n < m)
{n++;}
return;
} 展开
4个回答
展开全部
SBUF0 = temp; //将接收到数据送出.
while(TI0 == 0); //发送标志位是否产生.
TI0 = 0; //清发送标志位
……
上述程序,会死机的。
while(TI0 == 0); //发送标志位是否产生.--永远等不到 TI0 = 1
一旦为1,立即就进入中断,在中断函数中,马上清零了。
while(TI0 == 0); //发送标志位是否产生.
TI0 = 0; //清发送标志位
……
上述程序,会死机的。
while(TI0 == 0); //发送标志位是否产生.--永远等不到 TI0 = 1
一旦为1,立即就进入中断,在中断函数中,马上清零了。
更多追问追答
追问
哦,那你认为该怎么改?去掉那一部分,改成while(1)?
追答
仿照接收,也为发送,增加一个标志位。
//串口中断0子程序
void UART0_ISR (void) interrupt 4
{
if(!TI0) { //是发送中断还是接收中断.
RI0 = 0; //清接收标志位.
temp = SBUF0; //保存接收到的数据.
ReceiveBit = 1; //置接收标志.
}
else {
TI0 = 0; //清发送标志位.
TTT_Bit = 1; //置发送标志位.
}
}
展开全部
不能接收,不仅仅是程序的问题。
首先看,总线上有没有信号,先用示波器量一下。
如果有,再对照uart的设置说明仔细检查程序的配置。
串口通讯还是比较容易排查问题的,仔细看一下。
首先看,总线上有没有信号,先用示波器量一下。
如果有,再对照uart的设置说明仔细检查程序的配置。
串口通讯还是比较容易排查问题的,仔细看一下。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
你看看你的程序里面,“串口允许接收位”有没有置位,配合你的单片机数据手册看看。。。。。。。。
追问
SCON0 = 0x50;这里就有接收允许,位四就是的
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
2011-08-12
展开全部
麻烦`采纳.··.··.·
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询