【求助】看似简单的串口程序搞了一下午,请帮忙看看吧
本帖最后由 tim4146 于 2013-3-21 17:57 编辑硬件连接:笔记本端是FT232,出来的TTL电平,将RXD,TXD交叉连接到单片机的TXD,RXD,杜邦线连的。晶振12M,调试助手设置的是9600的波特率,对应程序重装初值0XFD.
程序如下:
#include <reg51.h>
#include <intrins.h>
sbit P33=P3^3;
unsigned char tmp;
void send_char(unsigned char txd);
void delay20ms(void) //误差 0us
{
unsigned char a,b;
for(b=215;b>0;b--)
for(a=45;a>0;a--);
_nop_();//if Keil,require use intrins.h
_nop_();//if Keil,require use intrins.h
}
main()
{ unsigned char TEMP=0X00;//临时
TMOD = 0x20; // 定时器1工作于8位自动重载模式, 用于产生波特率
TH1 = 0xFD; // 波特率4800
TL1 = 0xFD;
SCON = 0x50; // 设定串行口工作方式
PCON &= 0xef; // 波特率不倍增
TR1 = 1; // 启动定时器1
IE = 0x00; // 禁止任何中断
//P0=0X00;
while(1)
{
if(RI) // 是否有数据到来
{
RI = 0; //清零
tmp = SBUF; // 暂存接收到的数据
send_char(tmp); // 回传接收到的数据
}
if(!P33) //开发板上有个按钮,扫描按钮是否按下
{
delay20ms(); //延时去抖动
while(!P33); //松开时执行下一步
P0=~P0; //取反,使LED灯亮暗交替变换 这步能执行。
send_char(TEMP);//发送一个0X00回去,发现收到的是乱码
}
}
}
void send_char(unsigned char txd)
// 传送一个字符
{
SBUF = txd;
while(!TI); // 等特数据传送
TI = 0; // 清除数据传送标志
}
实现目标:1、在串口调试助手中发送一个字节的字符,单片机收到之后将其发送回去让电脑的串口收到;
2、检测一个按钮,在按钮松开时改变P0的电平达到LED亮暗交替的效果,并且随后给上位机发送0X00。
悲催的现实:调试助手发送一个字节之后发现单片机那边没反应;按钮按下松开之后LED灯正常切换状态,但是调试助手收到的一个字节的 内容是乱码(十六进制显示不是我预先设定的0x00) 楼主你没贴你单片机具体晶振是多少。。。 zjsxwc 发表于 2013-3-21 17:50 static/image/common/back.gif
楼主你没贴你单片机具体晶振是多少。。。
晶振12M,调试助手设置的是9600的波特率,对应程序重装初值0XFD.
刚刚吃过晚饭,还的继续弄出来,本来是调试蓝牙模块的,发现串口直接相连都调不出来...哎 tim4146 发表于 2013-3-21 17:58 static/image/common/back.gif
晶振12M,调试助手设置的是9600的波特率,对应程序重装初值0XFD.
刚刚吃过晚饭,还的继续弄出来,本来是 ...
12M晶振用9600Bps误差很大的,一般用4800Bps,保险点用更低的波特率试试
11.0592MHz的晶振的才能用9600Bps 12M晶振,9600的误差太大,根本无法通信 zjsxwc 发表于 2013-3-21 18:04 static/image/common/back.gif
12M晶振用9600Bps误差很大的,一般用4800Bps,保险点用更低的波特率试试
11.0592MHz的晶振的才能用9600Bp ...
查表得知12M和11.0592M晶振相对9600波特率的初值都是FDH,所以直接换了晶振再试的,发现还是有问题,改成4800波特率下(TH1 = 0xF9; TL1 = 0xF9;),还是乱了。兄台,你手上有开发板吗,直接烧进去帮我看看吧 binaimei2007 发表于 2013-3-21 18:12 static/image/common/back.gif
12M晶振,9600的误差太大,根本无法通信
为了做纯粹的通信,也为了降低波特率,我采用1200波特率,定时器初值E6。
程序:
#include <reg51.h>
#include <intrins.h>
void send_char(unsigned char txd);
void delay500ms(void) //误差 0us
{
unsigned char a,b,c;
for(c=23;c>0;c--)
for(b=152;b>0;b--)
for(a=70;a>0;a--);
}
main()
{ unsigned char TEMP=0XAA;//临时
TMOD = 0x20; // 定时器1工作于8位自动重载模式, 用于产生波特率
TH1 = 0xe6; // 波特率1200
TL1 = 0xe6;
SCON = 0x50; // 设定串行口工作方式
PCON &= 0xef; // 波特率不倍增
TR1 = 1; // 启动定时器1
IE = 0x00; // 禁止任何中断
while(1)
{
delay500ms();
send_char(TEMP); //这步没效果,不懂
}
}
void send_char(unsigned char txd)
// 传送一个字符
{
SBUF = txd;
while(!TI); // 等特数据传送
TI = 0; // 清除数据传送标志
}
结果:
按理是500ms发送一次,实际收到的频率发现有丢失的现象,收到的内容不是预先设定的值... //时钟22.1184M
void UartInit(void)
{
AUXR1 |= 0;
SCON = 0x52; //
TMOD|=0x20;
TI=0;
TH1=0xfd; //19200bps
// TH1 =0xfa; //9600bps
TR1 = 1;
}
这是22.1184M用的一个初始化程序,11.0592M的话,波特率减半可以正常工作 wmm20031015 发表于 2013-3-21 18:55 static/image/common/back.gif
//时钟22.1184M
void UartInit(void)
{
谢谢你,但是
AUXR1
是什么? 给你1个例子,自己看void HardInit(void)
{
EA = 0; //关闭所有中断
/*定时器1,2模式设置*/
TMOD = (((unsigned char)0x02)<<1)| //timer0工作方式选择,0-13位定时器/计数器工作模式,1-8位定时器/计数器工作模式
//2-16位定时器/计数器工作模式,3-用作2个8位定时器/计数器工作模式
(((unsigned char)0x00)<<2)| //timer0,0-定时器,1-计数器
(((unsigned char)0x00)<<3)| //timer0,1-T/C启动受双重信号的控制,0-T/C启动仅受TRx位控制
(((unsigned char)0x01)<<5)| //timer1工作方式选择,0-13位定时器/计数器工作模式,1-8位定时器/计数器工作模式
//2-16位定时器/计数器工作模式,
(((unsigned char)0x00)<<6)| //timwer1,0-定时器,1-计数器
(((unsigned char)0x00)<<7); //timwer1,1-T/C启动受双重信号的控制,0-T/C启动仅受TRx位控制
/*定时器0设置*/
TH0 = 0xf7;
TL0 = 0x85;
/*定时器1设置*/
//作为波特率发生器
//SMOD = 0; //不加倍
TL1 = 0xFD; //11.0592MHz 0xFDH-9600 */
TH1 = 0xFD;
/*定时器2设置*/
T2CON = 0x00; //自动重装,16位
RCAP2H = 0xBC; //50ms中断一次
RCAP2L = 0x00;
TH2 = 0xBC;
TL2 = 0x00;
/*串口设置*/
SCON = 0x50;
PCON &= 0x7F;
/*外部中断0,1设置*/
//IT0 = 1; //跳变触发
//IT1 = 1; //跳变触发
/*中断优先级设置*/
PX0 = 0; //外部中断0的优先级位
PT0 = 0; //定时器0优先级位
PX1 = 0; //外部中断1的优先级位
PT1 = 0; //定时器1的优先级位
PS = 0; //串口中断的优先级位
PT2 = 0; //定时器2的优先级位
/*中断使能设置*/
EX0 = 0; //外部中断允许位
ET0 = 1; //定时器0中断允许位
EX1 = 0; //外部中断1允许位
ET1 = 0; //定时器1中断允许位
ES = 1; //串行通讯中断允许位
ET2 = 1; //定时器2中断允许位
EA = 1; //开总中断
TR0 = 0; //定时器0启动
TR1 = 1; //定时器1启动
TR2 = 1; //定时器2不启动
}注意:使用了中断,晶振11.0592 感谢各位的帮助,我最后调试出来了。软件本身应该是没有问题的,硬件出现了问题。 tim4146 发表于 2013-3-21 19:01 static/image/common/back.gif
谢谢你,但是
AUXR1
是什么?
新唐的51里的一个寄存器,其他51注释掉就行了 你直接就把手体电脑串口和单片机接在一起了???
页:
[1]