串口通信的问题
我最近碰到2个问题,实在搞不懂,所以请教一下各位大哥。。。
1、我通过我的硬件键盘,按键,然后在串口调试助手上显示相应的键值,但是上面显示的数值前面,总有一些诡异的符号。比如我按6,就会显示66666。
我希望只显示出一个正常的6,应该怎么弄呢?
2、我每次按完一次键以后,程序就终止了,我想要按完6个键,程序才会终止,应该怎么做呢?
主程序如下:
main()
{
a=0;
while(a<6)
{
P1=0x70;
TMOD=0x20; //设置定时器1为工作方式2
TH1=0xf3;
TL1=0xf3;
TR1=1;
REN=1;
SM0=0;
SM1=1;
EA=1; /*CPU开中断*/
IT0=1; /*脉冲触发方式(负跳变有效)*/
EX0=1; /*允许外部中断0中断*/
}
}
中断程序内就是一个键盘扫描程序,这是扫描完以后的一个输出代码,请教。。。
SBUF=num;
printf("%d",num);
while(!TI);
TI=0;
a++;
[解决办法]
中断函数,有点混乱,而且有个致命的问题,虽然可能不是造成现在问题的原因,但是对整个系统稳定很严重的。
中断函数里面尽量简洁,但是你用了若干个delay(10)延时10ms函数来消抖。这样你用了几十毫秒等待,再加上你发送UART 的while(!TI); 假如波特率比较低的话,同样需要一定的时间。这个几十ms ,在中断里面延时,是极其少见,没人这样用。
再次,在一般工业应用上,外部中断,连一般的处理也不会做。你在里面处理了按键扫描。而且也比较臃肿。当然这个问题没上面的延时那么严重。
中断里面处理事情越多,压栈也就越大,占用CPU越长,不利于系统的稳定性,到时什么怪现象都会有的,所以我建议,先将程序结构搞好。将按键处理和串口发送另开辟函数,放在主程序里,然后中断只是立标志供主循环判断用。
这样改了之后,假如再出问题,就比较简单了,程序结构也清晰。
[解决办法]
串口初始化怎么写在while里?
[解决办法]
/**********************************************************************************
* 获取按键值应用数码管显示并通过RS-232发送到PC上进行显示
*
*
*
*
*
* 文 件: TEST.C
* 作 者: soon
* 部 门: 计算机07级04班
* 编写日期: 2009.5.4
* 模块版本:
* 适用芯片: CPU 89C52RC
* 修改记录:
* ================================================================================
* 版 本| 日 期 | 修改人 | 描 述
* ================================================================================
* | | |
* | | |
* | | |
* ================================================================================
*
* 注意事项:在进行发送字符到PC机上时,由于通信波特率为9600,所以在我按键按下的时间
* 内,进行发送的字符较多。所以,必须进行延时处理,使其只通发送一个字符到
* PC机。本程序进行处理的时间只能进行发送与接收是以字符格式进行的,当格式
* 格式不对时,所进行延时的时间需要进行重新设置。
*
*
*
*
**********************************************************************************/
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
uchar buff[4]={0XC0,0xCF,0XA4,0XB0}; /*定义要进行数码显示的数字*/
uchar buff2[3]={'1','2','3'}; /*定义要进行在串口调试工具中进行显示的字符*/
uchar buff3[]=" "; /*用于在串口调试工具中输出空格*/
sbit key1=P3^5; /*按键1*/
sbit key2=P3^6; /*按键2*/
sbit key3=P3^7; /*按键3*/
uchar buf; /*用于保存按键的编号*/
uchar chose; /*用于确定是否有按键按下*/
uchar i; /*用于循环控制*/
void sender(uchar buf); /*声明串口发送函数*/
void dispchar(uchar buf); /*声明数码显示函数*/
void key(void ); /*声明获取按键编号函数*/
void delytime(uint time); /*声明延时函数*/
/***********************************主函数*************************************/
void main(void )
{
/*进行设置波特率为9600*/
TMOD=0X20;
TL1=0XFD;
TH1=0XFD;
SCON=0XD8;
PCON=0X00;
EA=1; /*允许中断*/
TR1=1; /*启动T1中断*/
ES=1; /*允许串口中断*/
REN=0; /*禁止接收数据*/
P2=0X7F; /*选中第四个数码显示管*/
P0=0XC0; /*初始化显示*/
while(1)
{
key(); /*获取按键编号*/
dispchar(buf); /*进行显示*/
if(chose==1)
{
delytime(25000); /*进行延时,这样就只进行显示一次字符,否则进行多次显示*/
sender(buff2[buf-1]); /*在串口调试工具中进行显示字符*/
for(i=0;i<4;i++) /*在串口调度工具中输出空格*/
sender(buff3[i]);
}
}
}
/**********************************************************************************
* 发送函数
*描述:该函数用于发送字符到PC机。
*
*参数: 要进行发送的字符
*
*返回值:无
*
* 注意事项:
**********************************************************************************/
void sender(uchar buf)
{
SBUF=buf;
while(TI==0);
TI=0; /*软件清零*/
}
/**********************************************************************************
* 进行数码管显示
*描述:该函数用于在数码管上进行显示字符。
*
*参数:要进行显示的字符
*
*返回值:无
*
* 注意事项:
**********************************************************************************/
void dispchar(uchar buf)
{
P0=buff[buf];
}
/**********************************************************************************
* 获取接键值
*描述:该函数用于获取接键值。
*
*参数: 无
*
*返回值:无
*
*注意事项:由于本人的实验板只有三个按键,所以,对按键的判断没有采用其它的算法。
* 当按键数量有一定的数量时,请采用其它的算法。这样在时间溢率上才能达
* 所需的要求。
**********************************************************************************/
void key(void )
{
if(key1==0)
{
delytime(300); /*进行延时,去抖动*/
if(key1==0) /*再次进行扫描*/
{
buf=1;
chose=1;
}
}
else if(key2==0)
{
delytime(300);
if(key2==0)
{
buf=2;
chose=1;
}
}
else if(key3==0)
{
delytime(300);
if(key3==0)
{
buf=3;
chose=1;
}
}
else /*进行保存最后一次按键的编号,否则就只有暂短的显示,又恢复到0*/
{
buf=buf;
chose=0;
}
}
/**********************************************************************************
* 延时函数
*描述:该函数用于延时。
*
*参数:要进行延时的时间
*
*返回值:无
*
*注意事项:本延时函数不是一个精准的延时函数,若对延时时间要求太严格,请应用汇编
* 语言进行,那样写出的延时才能准确
**********************************************************************************/
void delytime(uint time)
{
while(time)
{
time--;
}
}
/**********************************************************************************
||
||
||
|| END
||
||
||
||
**********************************************************************************/
这是本人在学单片机的时候写的,楼主可以试着改改不需要的函数,在按键实验中请注意去抖动和进行适量的延时,否则会出现多个值,这是因为按下按键的时候与发送值的时间不是一个数量级的。
很久没有用过单片机,也只能给你提供这么点信息,因为本人是把单片机做为入门嵌入式的一个经过,入门嵌入式后就再也没有用过单片机了。