C8051F005串口发送问题

xmrforever 2011-06-09 09:52:17
硬件检测过的没有问题,程序应该也没问题,检查好几遍了
现在的现象是发送'R',出来乱的东西,用十六进制接收全是AA
...全文
156 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
O丸子爹O 2011-06-15
  • 打赏
  • 举报
回复
给你一个我用F020的配置,希望对你有所帮助。
1. CMOS时钟22.1184M;
2. Timer2(CMOS时钟的12分频)作为UART的时钟;
3. 根据波特率的计算公式计算相应的寄存器的值。
xmrforever 2011-06-15
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 bjtea 的回复:]
前一公式造成波特率的误差为3.2%~11.5%,你简单按整数做除法,误差是11.5%;后一公式的误差为0.15%~0.46%,可以忽略不计。
[/Quote]
这个误差怎么算的啊?数据手册上没有介绍
bjtea 2011-06-15
  • 打赏
  • 举报
回复
不需要手册。你用计算器算一下,就能知道给TH1的赋值只能是整数,而计算得到的精确值是浮点数。由此存在很大的因为整型运算截尾造成的误差。如果你不截尾,而四舍五入进1位,误差只有3.2%,通讯还是可能进行的。
bjtea 2011-06-13
  • 打赏
  • 举报
回复
前一公式造成波特率的误差为3.2%~11.5%,你简单按整数做除法,误差是11.5%;后一公式的误差为0.15%~0.46%,可以忽略不计。
bjtea 2011-06-12
  • 打赏
  • 举报
回复
看来楼主不熟悉51硬件寄存器功能。
改变TH1就是设置波特率的主要一步。TH1的值,决定了定时器的溢出率,从而决定了波特率。
xmrforever 2011-06-12
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 bjtea 的回复:]
看来楼主不熟悉51硬件寄存器功能。
改变TH1就是设置波特率的主要一步。TH1的值,决定了定时器的溢出率,从而决定了波特率。
[/Quote]
起初我没有设置PCON |= 0x80; CKCON |= 0x10;
TH1 = 256 - SYSCLK / UART0BAUDTATE / 32 / 12;

后来设置了PCON |= 0x80; CKCON |= 0x10;
TH1 = 256 - SYSCLK / UART0BAUDTATE / 16;

按照数据手册上说的:
当定时器1被选为波特率源时,SMOD位(PCON.7)选择是否将定时器溢出率除以2。复位后SMOD位为逻辑0,因此缺省情况下选择低速波特率;
定时器1溢出率由系统时钟源(T1CLK)和重载值(TH1)决定。T1CLK的频率可以在SYSCLK、SYSCLK/12和外部振荡源中选择。

也就是说我不设置PCON 和 CKCON时TH1应该等于256 - SYSCLK / UART0BAUDTATE / 32 / 12;
为什么会出现误码呢?
而设置以后TH1的值为256 - SYSCLK / UART0BAUDTATE / 16;就对了呢?
xmrforever 2011-06-11
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 bjtea 的回复:]
PCON高位置1或置0,波特率差了一倍,该位称为波特率加倍位。所以,还是波特率错误。
[/Quote]
但是我的TH1的值也做改变了啊
之前的初始化TH1的值是256 - SYSCLK / UART0BAUDTATE / 32 / 12;

改了后是256 - SYSCLK / UART0BAUDTATE / 16;
bjtea 2011-06-10
  • 打赏
  • 举报
回复
PCON高位置1或置0,波特率差了一倍,该位称为波特率加倍位。所以,还是波特率错误。
xmrforever 2011-06-10
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 bjtea 的回复:]
大写的R的ASCII码为0x32,也就是说上位机应该收到0x32。 你接收不对,是上下位机的波特率不匹配吧?你可以先将上、下位机的波特率都设低一点,例如1200,这样容易匹配上。 与用25M没有什么关系。
[/Quote]
波特率都是9600,现在串口初始化改成5楼的代码就可以正常发送了
应该是分频的问题了
xmrforever 2011-06-10
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 woshi_ziyu 的回复:]
引用 5 楼 xmrforever 的回复:

串口初始化设置成这样就可以发送了
C/C++ code
TMOD &= 0x0f;//选择T1工作模式
TMOD |= 0x20;
SCON = 0x50;
PCON |= 0x80; CKCON |= 0x10;TH1 = 256 - SYSCLK / UART0BAUDTATE / 16;TR1 = 1;
……
[/Quote]
现在就是这里的问题,我改成这样就可以正常发送了,没有误码
改成原来的初始化就会有误码
woshi_ziyu 2011-06-10
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 xmrforever 的回复:]

串口初始化设置成这样就可以发送了
C/C++ code
TMOD &= 0x0f;//选择T1工作模式
TMOD |= 0x20;
SCON = 0x50;
PCON |= 0x80; CKCON |= 0x10;TH1 = 256 - SYSCLK / UART0BAUDTATE / 16;TR1 = 1;
TI……
[/Quote]
和这个无关呢
bjtea 2011-06-10
  • 打赏
  • 举报
回复
大写的R的ASCII码为0x32,也就是说上位机应该收到0x32。 你接收不对,是上下位机的波特率不匹配吧?你可以先将上、下位机的波特率都设低一点,例如1200,这样容易匹配上。 与用25M没有什么关系。
xmrforever 2011-06-10
  • 打赏
  • 举报
回复
串口初始化设置成这样就可以发送了
TMOD &= 0x0f;//选择T1工作模式
TMOD |= 0x20;
SCON = 0x50;
PCON |= 0x80; CKCON |= 0x10;TH1 = 256 - SYSCLK / UART0BAUDTATE / 16;TR1 = 1;
TI = 1;



我用的晶振是25M的,是不是分频太多会出现误码?
xmrforever 2011-06-10
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 bjtea 的回复:]
你需要说清,C8051的串口将信号发给谁?用了电平转换芯片吗?你用什么来接收信号的?
[/Quote]
发给电脑,用串口调试程序接收的,C8051这边用的TTL转232接口
接收的时候只看到接收在累计,用十六进制接收时接收的全是AA,我发送的是一个R
bjtea 2011-06-09
  • 打赏
  • 举报
回复
你需要说清,C8051的串口将信号发给谁?用了电平转换芯片吗?你用什么来接收信号的?
xmrforever 2011-06-09
  • 打赏
  • 举报
回复
源代码贴上来
//配置系统时钟
void SysClkInit(void)
{
int n = 0;
OSCXCN = 0x67;
for (n = 0; n < 255; n++) ;
while ( (OSCXCN & 0x80) == 0 );
// OSCICN &= ~0xFF;
OSCICN = 0x0C;
}

//系统配置
void SystemInit(void)
{
WDTCN = 0xDE; // 关闭 WDT
WDTCN = 0xAD;
}

//端口配置
void PortInit(void)
{
//交叉开关配置
XBR0 = 0x04;
XBR1 = 0x00;
XBR2 = 0x40;
// P0 口分配状况
// P0.0 = UART0 TX
// P0.1 = UART0 RX
PRT0CF = 0xE0;//P0.2-3-4按键输入
PRT1CF = 0x00;
PRT2CF = 0xFF;//P2.6按键输出
PRT3CF = 0xFF;//P3.6\P3.7按键输出
P0=0x1F;
P1=0;
P2=0;
P3=0;
}
void UartInit(void)//UART初始化
{
TMOD &= 0x0f;//选择T1工作模式
TMOD |= 0x20;
SCON = 0x50;
//PCON |= 0x80; // SMOD = 1
TH1 = 256 - SYSCLK / UART0BAUDTATE / 32 / 12;
TR1 = 1;
TI = 1;
}
xmrforever 2011-06-09
  • 打赏
  • 举报
回复
问题找到了,TX口的电压只有1.8V,应该是这个导致发送后的数据出错
但不知为何只有1.8v,应该是3.3V才对

27,374

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧