|
楼主 |
发表于 2009-11-13 10:49:15
|
显示全部楼层
现在修改好的代码如下:
下位机:
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar timer_start_flag; //定时器0启动标志位
uchar timer_stop_flag; //定时器0停止标志位
uchar num; //循环计数值
uchar receive_data; //接收数据
uchar counter; //定时50毫秒溢出值
uchar timer_1s_flag; //定时1秒溢出标志位
void System_Init() //系统初始化
{
timer_start_flag=0;
timer_stop_flag=0;
timer_1s_flag=0;
num=0;
receive_data=0;
counter=0;
timer_1s_flag=0;
TMOD=0x21; //定时器1 工作方式2 定时器0 工作方式1
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
SCON=0x50; //串口方式1 允许串口接收
TH1=0xfd; //9600波特率
TL1=0xfd;
ET0=1; //开定时器0中断
ET1=1; //开定时器1中断
ES=1; //开串口中断
EA=1; //开总中断
TR0=0; //关闭定时器0
TR1=1; //启动定时器1
}
void Serial_Send(uchar send_data) //串口发送函数
{
ES=0;
SBUF=send_data;
while(!TI);
TI=0;
ES=1;
}
void serial_receive() interrupt 4 using 0 //串口中断接收函数
{
RI=0;
receive_data=SBUF;
switch(receive_data)
{
case 0xa0: //CPU收到0A0H就启动定时器0
timer_start_flag=1;
break;
case 0xa1: //CPU收到0A1H就关闭定时器0
timer_stop_flag=1;
break;
}
}
void timer0() interrupt 1 using 1 //定时0中断函数
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
counter++;
if(counter==20) //定时1秒到了吗?
{
counter=0;
timer_1s_flag=1;
}
}
void main()
{
System_Init();
while(1)
{
if(timer_start_flag==1)
{
timer_start_flag=0;
TR0=1;
}
if(timer_stop_flag==1)
{
timer_stop_flag=0;
TR0=0;
}
if(timer_1s_flag==1)
{
timer_1s_flag=0;
Serial_Send(num); //发送循环计数值
num++;
if(num==60)
{
num=0;
}
}
}
}
上位机代码:
unit Myserial;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, SPComm, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button3: TButton;
ComboBox1: TComboBox;
Edit2: TEdit;
Comm1: TComm;
Label2: TLabel;
Button2: TButton;
Button4: TButton;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
procedure Button4Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject); //打开串口
begin
try
comm1.CommName:='com'+inttostr(combobox1.ItemIndex);
comm1.BaudRate:=9600;
comm1.ParityCheck:=false;
comm1.ByteSize:=_8;
comm1.StopBits:=_1;
comm1.startcomm;
button1.Enabled:=false; //串口打开按钮
button2.Enabled:=true; // RUN按钮
button3.Enabled:=true; // 串口关闭按钮
button4.Enabled:=true; // STOP按钮
except
showmessage('打开串口错误');
end;
end;
procedure TForm1.Button2Click(Sender: TObject); //启动跑马表
if not comm1.WriteCommData(char($a0),1) then
showmessage('启动失败');
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
comm1.stopcomm ;
button1.enabled := true ;
end;
procedure TForm1.Comm1ReceiveData(Sender: TObject; Buffer: Pointer; //串口接收循环计数值
BufferLength: Word);
var
viewstring:string;
rbuf:array[0..7] of byte;
i:integer;
begin
viewstring:='';
move(buffer^,pchar(@rbuf)^,bufferlength);
for i:=0 to bufferlength-1 do
begin
viewstring:=inttohex(rbuf,2);
edit2.Text:=viewstring;
end;
end;
procedure TForm1.Button4Click(Sender: TObject); //停止跑马表
begin
if not comm1.WriteCommData(char($a1),1) then
showmessage('停止失败');
end;
end.
29楼大虾:
在下位机串口发送函数中,我认为在串口发送前需要关闭串口中断ES。否则,单片机发完数据后,会向CPU申请中断,从而进入串口中断接收函数,导致程序出乱。单片机发完数据后,再开串口中断ES。
程序运行后的现象:
数值显示框显示:00 01 02 03.....一直到59,然后又从0开始显示(正常,这正是我想要达到的目的!)。
但我现在有个问题,我是这样想的:
上位机接收到的数据存放到数组rbuf中,那么现在数组rbuf中的数据类型是十进制的byte型还是十六进制的byte型啊?
还有就是上位机接收程序里经执行这条代码:viewstring:=inttohex(rbuf,2);后
viewstring 再赋给数值edit2显示框后为什么不是按十六制形式显示,也就是00 01 02 ...09 0a 0b .....一直到3B(也就是十进制的59)?
难道edit2数值显示框会自动将viewstring中的十六进制字符串转换为十进制字符串显示?
这两个问题令我不解!
请各位大虾帮我解答下,谢谢! |
|