我想用C8051F021做串口通信,使用的晶振是11.0592MHz,波特率设置为4800Kbps,代码如下,问题是用串口助手无法收取数据。
#include "c8051f020.h"
unsigned char data1;
void SYSCLK_Init();
void PORT_Init();
void UART0_Init();
void SYSCLK_Init()
{
unsigned int i;
OSCXCN=0x67; //0X67=0110,0111
for(i=0;i<256;i++); //等待>1ms
while(!(OSCXCN&0x80)); //等待XTLVLD变为1
OSCICN=0x88; //时钟失效监测器,选择外部时钟源作为系统时钟
}
void PORT_Init()
{
XBR0 = 0x04; //URAT总线TX0置到P0.0口,RX0置到P0.1口
XBR1 = 0x00;
XBR2 = 0x40; //允许功能选择开关有效
P0MDOUT = 0x01; //P0.0(Tx)推挽方式 P0.1(Rx)和P0上的其余端口设置为漏极开路
}
void UART0_Init()
{
SCON0=0x50; //串口方式1 ,允许接收
TMOD =0x20; //选用定时器1作为波特率发生器
PCON =0x80; //SMOD0=1
TH1=0xF4; //时钟频率11.0592MHz,波特率为4800
TL1=0xF4;
TR1=1; //定时器1启动
ES0=1; //开启串口0中断
TI0=1; //声明TX0就绪,可以发送
}
void UART0_ISR() interrupt 4
{
if(RI0) //接收数据
{
RI0=0; //中断接收标志清零
data1=SBUF0; //接收数据,暂时存储在data1
SBUF0=data1; //发送数据
while(TI0==0);
TI0=0; //发送标志清零
}
}
main()
{ EA=0; //关 全局中断
WDTCN=0xDE; //禁用看门狗
WDTCN=0xAD;
SYSCLK_Init();
PORT_Init();
UART0_Init();
EA=1; //开全局中断
while(1);
}
在if(RI0)设置中断后,下一步直接就跳出了函数,RI0的值始终是0。请教大家是什么问题,解决后我会再加分。
我按照大家的方法试了,没有起作用。我想是不是串口0坏了,就直接用串口1吧,Tx接P2.0,Rx接P2.1。但向SBUF1里送0x50,数据还是会从P0.0口出来,我都没有使能Uart0EN,而且还把ES0=0。请帮我看下代码有问题吗?
void main (void)
{ ...
while(1)
{SBUF1=0x50;}
}
void PORT_Init (void)
{ XBR0 = 0x00;
XBR1 = 0x00;
XBR2 = 0x44;
P2MDOUT |= 0x01; }
void UART1_Init (void)
{
TR1=0;
EIE2&=~0x40; //清ES1为0
EIP2&=~0x40; //清PS1为0,Uart1中断为低优先级
SCON1 = 0x52; // SCON1: mode 1, 8-bit UART, enable RX
TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit reload
TH1=0xF4;
TL1=0xF4; // init Timer1
PCON|=0x10;
// CKCON|=0x10; //TIM=1,使用系统时钟
EIE2= 0x40; // Enable UART1 interrupts
EIP2= 0x40; // Make UART high priority
TR1 = 1; // START Timer1
}
keil软仿串口无问题,查你的硬件吧。
如图:发68,回68。
你不会是没有电平转换就直连电脑了吧?
修改:貌似图的分辨率太大了,看不到大图。
然后,这里有问题:
SBUF0=data1; //发送数据
while(TI0==0);
TI0=0; //发送标志清零
你这时刚刚把数据送到SBUF0里,TI0还是1(TI0上一次发送完,没有清0),而就算TI0是1,但你刚把数据送到SBUF0里,怎么可能为1呢?(TI0是发送“完成”中断标志),程序退出中断后,过一会(按4800波特率发完一个字节的时间)TI0才是1,然后你中断里又没有处理TI0为1的情况,所以程序会一直进中断,但不会有什么动作,除非是RI0为1.
void sendchar(uchar ch)
{
SBUF=ch;
while(TI==0);
TI=0;
}
///////////送字符串///////
void sendstring(uchar *p)
{
while(*p)
{
sendchar(*p);
p++;
}
sendchar(0x0D);
sendchar(0x0A);
}
////////////串口中断,只是接收产生的,////////
void receive() interrupt 4 using 1
{
if(RI)
{
if(rx<rxin)
{
systembuf[rx]=SBUF;
rx++;
}
RI=0;
}
}
void main()
{
---------
sendstring(字符串)
-----------
}
void UART0_ISR() interrupt 4
{
if(RI0) //接收数据
{
RI0=0; //中断接收标志清零
data1=SBUF0; //接收数据,暂时存储在data1
// SBUF0=data1; //发送数据
cansenddata=1;
// while(TI0==0);
// TI0=0; //发送标志清零
}
}
在主函数中发数据
while(1)
{
if(cansenddata)
{
cansenddata=0;
SBUF=ch;
while(TI==0);
TI=0;
}
}
有源的晶振是四个脚的,有1:VCC 2:GND 3:NC(不连接) 4:输出,具体怎么排的忘记了,不要接起振电容,有源的比较贵,无源的一半都是1元,有源的要好几快呢。输出接到XTAL2上,XTAL1悬空