单片机c8051f 串口问题 请大侠帮忙啊

我把程序贴出来看一下
#include "c8051f330.h"
#include "uart.h"
#include "const.h"
void SysPort_Init(void)
{
P0MDOUT = 0x10;
P1MDOUT = 0x08;
XBR0 = 0x01;
XBR1 = 0x40;

}
void Oscillator_Init(void)
{

OSCICN |= 0x03;
OSCICL=OSCICL+22;
}
void main()
{ unsigned char val;
SysPort_Init();
Oscillator_Init();
PCA0MD&=~0x40;//禁止看门狗定时器
Uart0_Init();
EA=1;

Uart0_SendString("HELLO");

while(1)
{
if(Uart0_RecvChar(&val))
{
Uart0_SendChar(val);
}
}
}
void Uart0_Init()
{
SCON0 = 0x10;//允许接收
TH1=0xA0;//9600波特率
CKCON &= ~0x0B;

TL1 = TH1;
TMOD &= ~0xf0; // 定时器设置
TMOD = 0x20;
TR1 = 1; // 启动定时器,串口开始工作
TI0 = 1; // 清除中断标志
RI0 = 0;
}
unsigned char Uart0_RecvChar(unsigned char *chr)
{
if(RI0)
{
RI0 = 0; // 清除RI1标志位
*chr = SBUF0; // 读取数据
return TRUE; // 返回接收数据成功
}
else
return FALSE; // 接收数据失败,无数据
}
void Uart0_SendChar(unsigned char chr)
{
while(!TI0); // 等待发送1个字节数据完成
SBUF0 = chr; // 发送数据到uart0
TI0 = 0; // 清除中断标志
}
void Uart0_ISR(void) interrupt 4
{
if (RI0)// 判断是否是接收中断
{
RI0 = 0;// 清除接收中断标志
}
if (TI0)// 判断是否是发送完成中断
{
TI0 = 0; // 清除发送完成中断标志
}
}
单片机可以发送数据给串口 但是从串口发出的数据 单片机无法接收到 不能反过来发送给串口显示

当你有数据接收到了以后立即触发中断,但是你在中断函数里面立即将RI0清零处理了,这样一来你的RI0几乎总是等于零的,这样

if(RI0)
{
RI0 = 0; // 清除RI1标志位
*chr = SBUF0; // 读取数据
return TRUE; // 返回接收数据成功
}
else
return FALSE; // 接收数据失败,无数据
}

这个条件永远不成立,所以你得不到数据,有两种解决办法,第一将中断关闭,这样也可以运行程序,但是不完美,第二在中断函数里面将SBUF0的数据存到一个全局变量里面,同时用一个标志位指示数据的接收情况。

然后。。。。然后,,,你应该明白了。。祝你成功。。追问

我很同意你的说法啊 但是我试过了 还是不行 我改成这样了 不用函数 直接main()里面接收

追答

你的函数智能运行一次么,,加个while(1)。。

温馨提示:内容为网友见解,仅供参考
第1个回答  2012-08-10
在单片机给串口发送数据的那个中断里
把SBUF的值给一个变量

然后在主函数里,把变量值赋给SBUF(此时SBUF的物理位置变了,从发送变成了接收)

酱紫单片机就能反过来发给串口闹~~~追问

这样应该是可以的 但是我主要是想知道 我在主函数那里写的
while(1)
{
if(Uart0_RecvChar(&val))
{
Uart0_SendChar(val);
}
}
} 这个 从串口一旦收到数据 就反过来发给串口 这样为什么不对呢 百思不得其解啊

C8051F310单片机进行串口通信,我在波特率9600下正常,但是在115200下传输...
1、物理层的电平转换方面出了问题。所以第一步可以用示波器来查查。2、如果是单片机和单片机通信,相同配置,则可能串口服务程序全双工处理不当造成。3、如果是单片机和PC通信,串口中断服务程序全双工处理不当造成。还有可能115200配置不正确或速率差较大,可考虑用1+8+1+1,多一个停止位或者增加空闲位...

单片机c8051f35系列串口初始化程序问题
最后一个是时钟源48分频的情况。第二个问题,对于串口你可能理解的不够透彻,单片机通过串口发送数据时,是先将数据发送到数据缓冲寄存器SBUF,“ 当UART0发送完一个字节数据后该位被硬件置‘1’ ” 这句话的真正意思是 “单片机的SBUF发送完一个字节数据后该位被硬件置‘1’ ” 。注意 “SBUF” ...

c8051f350单片机ad转换在串口上显示电压 的精度和分辨率的问题
单片机电压表难在线性度,测量基准要足够稳定,外加好的软件算法。10位AD别指望好的表现。纯属个人观点。

C8051F021 单片机串口通信问题
keil软仿串口无问题,查你的硬件吧。如图:发68,回68。你不会是没有电平转换就直连电脑了吧?修改:貌似图的分辨率太大了,看不到大图。然后,这里有问题:SBUF0=data1; \/\/发送数据 while(TI0==0);TI0=0; \/\/发送标志清零 你这时刚刚把数据送到SBUF0里,TI0还是1(TI0上一次发送完,...

关于C8051F005单片机扩展串口的疑问
第二个串口只用做主动发送,那么用一个IO就能模拟了,计算一下延时时间,符合波特率要求对方电脑就能收到,在电脑和单片机之间都需要增加串口转RS232的电平转换。

关于51单片机通过串口发送数据的问题 我没有用循环发送 但是连上电脑...
呵呵,您使用的是C8051F系列单片机。因此,初始化时应当禁用WDT。在初始化里增加以下语句:PCA0MD &= ~0x40;PCA0MD = 0x00;这样,单片机就不会不停地复位了。

C8051f单片机 串口中断与外部中断
完全是可以一起使用的,配置交叉开关 当交叉开关配置寄存器XBR0、XBR1、XBR2 和XBR3 中外设的对应使能位被设置为逻辑‘1’时,交叉开关将端口引脚分配给外设。可能你还没有完全理解交叉开关的使用。外设的引脚就是通过优先权来合理分配的。配置程序:XBR0 |= 0x04;XBR1 |= 0x04;XBR2 |= 0x40;...

C8051F310单片机进行串口通信,我在波特率9600下正常,但是在115200下传输...
单片机内部时钟误差较大,建议使用外部晶振,且选择可以配置成你所需波特率而误码较率较小的晶振如11.0592MHz,22.1184MHz等

高手进!USB的蓝牙适配器与8051F单片机连接应用问题
MCE0=1;设置没有。还有可能是,你要知道C8051F的运算速度是很快的,你需要把串口的传输频率调节到蓝牙模组可以识别的频率范围,还有就是在发送完一字节,就是在每次清除TI0之后最好做一个延时。要考虑到蓝牙模组对于串口数据的处理速度的问题,它还没把数据拿走,你一发数据就出问题了 ...

c8051f320单片机不能下载程序了,有可能是芯片被上锁了,该怎么解锁呢...
下载程序要冷启动,首先保证你的串口联通的,如果你使用了usb转串口,那么要保证ch340一直处于上电的状态,在下程序的时候 将单片机重启一下即可。。。

相似回答