实例9中,我是通过STC-ISP软件中串口助手调试单片机程序的,不太直观,能否在PC上用PASCAL写一个程序通过串口与单片机沟通呢。完全可以,可以用免费的开发环境LAZARUS开发,安装 lazSerial 后,进行快速开发。上位机和下位机,完全使用PASCAL开发,代码可以复用,非常方便。
// MainForm.pas
unit MainFrm;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls,
ComCtrls, LazSerial, LazSynaSer;
type { TMainForm } TMainForm = class(TForm) BtnOpen: TButton; BtnClose: TButton; BtnQuery: TButton; BtnCtrlSerial: TButton; CbbDev: TComboBox; CbbBaud: TComboBox; CbbCOM: TComboBox; Label1: TLabel; Label2: TLabel; LazSerial1: TLazSerial; MemInfo: TMemo; Shape1: TShape; StatusBar1: TStatusBar; procedure BtnCloseClick(Sender: TObject); procedure BtnCtrlSerialClick(Sender: TObject); procedure BtnOpenClick(Sender: TObject); procedure BtnQueryClick(Sender: TObject); procedure FormClose(Sender: TObject; var CloseAction: TCloseAction); procedure LazSerial1RxData(Sender: TObject);
private public end;
var
MainForm: TMainForm;
implementation
{$R *.lfm}
uses MyDef;
{ TMainForm }
procedure TMainForm.BtnCtrlSerialClick(Sender: TObject);
begin
lazSerial1.BaudRate:=br__9600;
lazSerial1.Device:=CbbCom.Text;
try lazSerial1.Active:=Not lazSerial1.Active;
except ShowMessage('打开串口失败');
end; if not lazSerial1.Active then BtnCtrlSerial.Caption:='打开串口'
else BtnCtrlSerial.Caption:='关闭串口';
end;
procedure TMainForm.BtnCloseClick(Sender: TObject);
begin TxFrame[1]:=CMD_BEGIN; TxFrame[2]:=CMD_CLOSE; TxFrame[3]:=DEV_LED1+CbbDev.ItemIndex; TxFrame[4]:=MyDef.GetCheck(TxFrame); lazSerial1.WriteBuffer(TxFrame,Sizeof(TxFrame)); MemInfo.Lines.Add( IntToHex(TxFrame[1])+' '+IntToHex(TxFrame[2]) +' '+IntToHex(TxFrame[3])+' '+IntToHex(TxFrame[4]) +' : 请关闭设备$'+IntToHex(TxFrame[3]) );
end;
procedure TMainForm.BtnOpenClick(Sender: TObject);
begin TxFrame[1]:=CMD_BEGIN; TxFrame[2]:=CMD_OPEN; TxFrame[3]:=DEV_LED1+CbbDev.ItemIndex; TxFrame[4]:=MyDef.GetCheck(TxFrame); lazSerial1.WriteBuffer(TxFrame,Sizeof(TxFrame)); MemInfo.Lines.Add( IntToHex(TxFrame[1])+' '+IntToHex(TxFrame[2]) +' '+IntToHex(TxFrame[3])+' '+IntToHex(TxFrame[4]) +' : 请开启设备$'+IntToHex(TxFrame[3]) );
end;
procedure TMainForm.BtnQueryClick(Sender: TObject);
begin TxFrame[1]:=CMD_BEGIN; TxFrame[2]:=CMD_QUERY; TxFrame[3]:=DEV_LED1 +CbbDev.ItemIndex; TxFrame[4]:=MyDef.GetCheck(TxFrame); lazSerial1.WriteBuffer(TxFrame,Sizeof(TxFrame)); MemInfo.Lines.Add( IntToHex(TxFrame[1])+' '+IntToHex(TxFrame[2]) +' '+IntToHex(TxFrame[3])+' '+IntToHex(TxFrame[4]) +' : 请查设备$'+IntToHex(TxFrame[3])+'状态' );
end;
procedure TMainForm.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
lazSerial1.Close ;
end;
procedure TMainForm.LazSerial1RxData(Sender: TObject);
var
S,T:String;
I:Integer;
begin
S:=lazSerial1.ReadData; if Length(S)<>4 then exit;
for I:=1 TO 4 do begin T:=T+IntToHex(Ord(S[I]),2)+' ';
end; if Ord(S[2])=DEV_FM then T:=T+': 蜂鸣器'
else T:=T+': LED '+ IntToStr((Ord(S[2])-DEV_LED1+1)); if Ord(S[3])=CMD_OPEN then T:=T+'已开启'
else T:=T+'已关闭'; MemInfo.Lines.Add(T);
end;
end.
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
// MyDef.pas
unit MyDef;
interface
// 本程序使用 Trubo51( https://turbo51.com/ ) 单片机 PASCAL 编译器
//
//
// 实例 9 演示了单片机串口 按自定协议收发串口数据
// 假设有PC可以发送如下多种命令给单片机
// .打开或关闭指定的LED灯
// .打开或关闭蜂鸣器
// .查询LED灯的状态或蜂鸣器状态
// 为此,设计PC发送的命令帧为 4 个字节:
// 起始|命令|设备号|检验
// 起始:固定为 $01
// 命令
// $4F(字符O) : 开启
// $43(字符C) : 关闭
// $51(字符Q ): 查询
// 检验为前面三个字符值相加
// 设备号:$31(字符 0)--$38(字符 7) LED1 -- LED8
// $39 (字符 9) 蜂鸣器 // 单片机发回PC的应答帧为 4 个字节:起始|设备号|状态|检验
// 起始:固定为 $01
// 设备:
// 命令
// $4F(O ): 已开
// $43(C ): 已关
//
// 检验为前面三个字符值相加 // CPU 电路图请看 实例 1
//
//
Type TCmdFrame=Array[1..4] of Byte ;
var RxFrame,TxFrame:TCmdFrame; RxCnt,TxCnt:byte; const // 命令 CMD_BEGIN=$01 ; // 帧头 CMD_OPEN= $4F ; // 开启 CMD_CLOSE=$43 ; // 关闭 CMD_QUERY=$51 ; // 查询 // 设备状态 DEV_ON=CMD_OPEN ; DEV_OFF=CMD_CLOSE; //设备编号 DEV_LED1=$30 ; // LED1 DEV_LED2=$31 ; DEV_LED3=$32 ; DEV_LED4=$33 ; DEV_LED5=$34 ; DEV_LED6=$35 ; DEV_LED7=$36 ; DEV_LED8=$37 ; DEV_FM=$38 ; // 蜂鸣器 // 接收帧各字节位置表意 RX_FB_BEG=1; RX_FB_CMD=2; RX_FB_DEV=3; RX_FB_CHK=4; // 发送帧各字节位置表意 TX_FB_BEG=RX_FB_BEG; TX_FB_DEV=2; TX_FB_STA=3; TX_FB_CHK=4;
function GetCheck(AFrame:TCmdFrame):byte;
function CheckFrame(AFrame:TCmdFrame):Boolean;
implementation
function GetCheck(AFrame:TCmdFrame):byte;
begin // result:=AFrame[1] OR AFrame[2] XOR AFrame[3] ; result:=AFrame[1] + AFrame[2] + AFrame[3]
end;
function CheckFrame(AFrame:TCmdFrame):Boolean;
begin result:= (AFrame[1]=CMD_BEGIN ) And ( AFrame[RX_FB_CHK] =GetCheck(AFrame) );
end; end.
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
文章来源: blog.csdn.net,作者:大郭小工,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/weixin_43754719/article/details/113861593