用Pcomm Pro开发串行通信程序
【打印文章】
用C + +Builder 在Win9x 下 开 发 串 行 通 信 程 序 是 程 序 员 们 经 常 遇 到 却 又 令 人 头 痛 的 事 情, 不 但 要 理 解 许 多 复 杂 的API 函 数, 还 要 掌 握 多 线 程 编 程。 令 人 欣 慰 的 是 有 一 些 公 司 专 门 为C + +Builder 开 发 了 编 写 串 行 通 信 程 序 的 开 发 工 具, 例 如MOXA 公 司 的Pcomm( 该 软 件 可 在http:\\www.moxa.com.tw 下 载), 因 而 帮 我 们 解 决 了 串 行 编 程 这 一 难 题。
----下 面 结 合 一 个 具 体 的 例 子 来 说 明 串 行 通 信 程 序 的 开 发。 本 程 序 的 编 程 环 境 是Win98 和C + +Builder3.0。 这 个 编 程 示 例 的 功 能 比 较 强, 它 具 有 发 送 数 据 和 自 动 接 收 数 据 的 双 重 功 能。 在 它 的 基 础 上 稍 加 修 改, 即 可 以 让 用 户 选 定 进 行 传 输 的 通 信 端 口, 并 设 定 这 个 端 口 的 相 关 参 数, 包 括 波 特 率、 数 据 位、 停 止 位、 奇 偶 校 验 和 流 量 控 制 等。
一、 Pcomm 的 设 置
----启 动C + +Builder3.0, 点 击File/New Application, 建 立 一 个 项 目 文 件, 修 改 表 单 的Name 属 性 为Comm, 然 后 存 盘, 命 名 项 目(Project) 为CommTest, 命 名 单 元(Unit) 为Comm。
----Pcomm Library 是 一 个 动 态 连 接 库(DLL) 文 件, 当 使 用C + +Builder 编 译 器 编 译PComm.dll 库 时, 我 们 必 须 告 诉C + +Builder 的 编 译 器 怎 样 找 到 这 些 函 数(sio_xxx())。
----因 此 我 们 用PComm Pro 在Borland C + +Builder 中 开 发 一 个 串 行 程 序 时, 必 须 做 到 以 下 两 点:
假 如 你 的Pcomm Pro 是 安 装 在c:\Program files( 缺 省 安 装 目 录) 目 录 下, 把c:\Program files \ Pcomm Pro \ Lib 下 的Pcommb.lib 文 件 加 入 到C + +Builder 的View 菜 单 中Project Manager 的 项 目 中, 使 之 成 为 项 目 的 一 个 单 元(unit)。
把 #include "c:\Program files\PcommPro\Lib\PComm.h" 包 含 在 你 的Comm.cpp 中。
二、 表 单 及 属 性 的 设 置
----如 图1 中 表 单 所 示:
----依 照 图1 中 主 界 面 来 添 加 控 件, 并 依 照 表1 中 的 设 置 来 设 置 各 控 件 的Name 和Caption 属 性。
----该 通 信 程 序 的 工 作 原 理 为 中 断 方 式, 即 当 输 入 缓 存 内 有 数 据 时, 就 会 触 发Pcomm 的 中 断 函 数sio_cnt_irq (Port, *CntIrq, count), 再 由 它 启 动 中 断 服 务 程 序CntIrq(), 然 后 由 数 据 接 收 函 数sio_read (port, ibuf, len) 来 接 收 数 据 并 做 其 他 相 应 的 处 理; 至 于 函 数 Open ()、Sent ()、Close () 则 分 别 为 打 开 按 钮、 发 送 按 钮、 关 闭 按 钮 的click 事 件 函 数;SendData、 ReceiveData 分 别 为 发 送 数 据 编 辑 框 和 接 收 数 据 编 辑 框 相 对 应 的 字 符 串 变 量。
三、 主 程 序 的 编 制
----双 击 表 单 上 的Button 控 件, 就 会 产 生 相 应 的 事 件, 如 双 击" 打 开" 按 钮, 就 会 产 生Open() 事 件 函 数。 在 这 些 函 数 中 添 加 代 码, 以 及Pcomm Pro 的 串 行 控 制 函 数, 就 能 实 现 对 串 口 事 件 的 处 理。 其 中 一 个 需 要 注 意 的 问 题 是SendData 和ReceiveData 都 为 AnsiString 字 符 串, 而Pcomm Pro 的 函 数 所 需 发 送 和 接 收 的 字 符 串 都 为 char 型, 因 此 要 正 确 使 用Pcomm 函 数, 还 要 注 意 字 符 串 转 换。AnsiString 字 符 串 可 通 过c_str() 函 数 转 换 为char 型, 而char 行 字 符 串 转 换 为 AnsiString 则 比 较 简 单。 可 用AnsiString(char) 把char 型 强 制 转 换 为AnsiString 型。 程 序 主 要 代 码 如 下 所 示:
void __fastcall TComm::Open (TObject *Sender)
// 串 口 打 开 函 数
{
int i;
sio_open (port); // 打 开 串 口
sio_ioctl (port, B2400, P_NONE | BIT_7 | STOP_1 );
// 设 置 串 口 参 数
// 包 括 波 特 率、数 据 位、停 止 位、奇 偶 校 验
void __stdcall ( *p)(int);
p=cntirq;
i=sio_cnt_irq(port, *p,1);// 设 置 中 断 函 数
}
// - - - - - - - - - - - - - - - - -
void __fastcall TComm::Sent (TObject *Sender)
// 数 据 发 送 函 数
{
char *SendData=new char[20];
SendData=SentEdit ->Text.c_str();
// 把SendEdit 中 的AnsiString 型 字
符 串 转 换 为char 型
sio_write(port,SendData,20); // 发 送 数 据
}
// - - - - - - - - - - - - - - - - -
void __fastcall TComm::Close (TObject *Sender)
// 串 口 关 闭 函 数
{
sio_close (port); // 关 闭 串 口
}
// - - - - - - - - - - - - - - - - -
void __stdcall cntirq(int port)
// 中 断 服 务 函 数( 手 工 生 成 函 数)
{
char ibuf[20];
AnsiString ReceiveData[20];
sio_read (port,ibuf, 20); // 接 收 数 据
ReceiveData = Ansistring(ibuf);
//char 字 符 串 转 换AnsiString 型 字 符 串
ReceiveEdit ->Text=ReceiveData;
// 显 示 接 受 到 的 字 符 串
}
----在 程 序 中, 我 们 使 用 了 一 些sio_xxx() 型 的 函 数, 它 们 都 是Pcomm pro 自 带 的 串 行 通 信 函 数( 函 数 的 具 体 用 法 可 以 参 考Pcomm pro 的 帮 助), 通 过 这 些 函 数, 我 们 可 以 对 串 行 端 口 进 行 设 置。
----sio_open(port) 和sio_close(port) 为 打 开 串 口 和 关 闭 串 口 函 数, 参 数port 可 设 置 具 体 操 作 的 串 口;sio_ ioctl(int port, int baud, int mode) 为 串 口 控 制 函 数, 可 设 置 串 口 的 波 特 率、 数 据 位、 停 止 位、 奇 偶 校 验; 至 于sio_write(port) 和sio_read(port), 则 为 读 串 口 和 写 串 口 函 数;sio_cnt_irq(int port,VOID (CALLBACK *func)(int port), int count) 为 中 断 函 数, 当 串 口 有 数 据 时, 就 触 发 该 函 数, 然 后 该 函 数 就 会 启 动 其 中 断 服 务 程 序VOID (CALLBACK *func)(int port)( 为 一 函 数 指 针), 这 里 是 调 用cntirq() 函 数 接 收 数 据, 该 函 数 需 要 程 序 员 手 工 生 成。
----由 此 我 们 可 以 看 出, 只 要 我 们 对 程 序 稍 加 修 改, 在 表 单 上 再 添 加 一 些 控 件, 使 得sio_xxx() 这 些 函 数 的 参 数 可 以 由 用 户 界 面 输 入, 就 可 以 做 到 由 用 户 选 定 进 行 数 据 传 输 的 通 信 端 口, 并 设 定 这 个 端 口 的 相 关 参 数, 包 括 波 特 率、 数 据 位、 停 止 位、 奇 偶 校 验 和 流 量 控 制 等
----下 面 结 合 一 个 具 体 的 例 子 来 说 明 串 行 通 信 程 序 的 开 发。 本 程 序 的 编 程 环 境 是Win98 和C + +Builder3.0。 这 个 编 程 示 例 的 功 能 比 较 强, 它 具 有 发 送 数 据 和 自 动 接 收 数 据 的 双 重 功 能。 在 它 的 基 础 上 稍 加 修 改, 即 可 以 让 用 户 选 定 进 行 传 输 的 通 信 端 口, 并 设 定 这 个 端 口 的 相 关 参 数, 包 括 波 特 率、 数 据 位、 停 止 位、 奇 偶 校 验 和 流 量 控 制 等。
一、 Pcomm 的 设 置
----启 动C + +Builder3.0, 点 击File/New Application, 建 立 一 个 项 目 文 件, 修 改 表 单 的Name 属 性 为Comm, 然 后 存 盘, 命 名 项 目(Project) 为CommTest, 命 名 单 元(Unit) 为Comm。
----Pcomm Library 是 一 个 动 态 连 接 库(DLL) 文 件, 当 使 用C + +Builder 编 译 器 编 译PComm.dll 库 时, 我 们 必 须 告 诉C + +Builder 的 编 译 器 怎 样 找 到 这 些 函 数(sio_xxx())。
----因 此 我 们 用PComm Pro 在Borland C + +Builder 中 开 发 一 个 串 行 程 序 时, 必 须 做 到 以 下 两 点:
假 如 你 的Pcomm Pro 是 安 装 在c:\Program files( 缺 省 安 装 目 录) 目 录 下, 把c:\Program files \ Pcomm Pro \ Lib 下 的Pcommb.lib 文 件 加 入 到C + +Builder 的View 菜 单 中Project Manager 的 项 目 中, 使 之 成 为 项 目 的 一 个 单 元(unit)。
把 #include "c:\Program files\PcommPro\Lib\PComm.h" 包 含 在 你 的Comm.cpp 中。
二、 表 单 及 属 性 的 设 置
----如 图1 中 表 单 所 示:
----依 照 图1 中 主 界 面 来 添 加 控 件, 并 依 照 表1 中 的 设 置 来 设 置 各 控 件 的Name 和Caption 属 性。
----该 通 信 程 序 的 工 作 原 理 为 中 断 方 式, 即 当 输 入 缓 存 内 有 数 据 时, 就 会 触 发Pcomm 的 中 断 函 数sio_cnt_irq (Port, *CntIrq, count), 再 由 它 启 动 中 断 服 务 程 序CntIrq(), 然 后 由 数 据 接 收 函 数sio_read (port, ibuf, len) 来 接 收 数 据 并 做 其 他 相 应 的 处 理; 至 于 函 数 Open ()、Sent ()、Close () 则 分 别 为 打 开 按 钮、 发 送 按 钮、 关 闭 按 钮 的click 事 件 函 数;SendData、 ReceiveData 分 别 为 发 送 数 据 编 辑 框 和 接 收 数 据 编 辑 框 相 对 应 的 字 符 串 变 量。
三、 主 程 序 的 编 制
----双 击 表 单 上 的Button 控 件, 就 会 产 生 相 应 的 事 件, 如 双 击" 打 开" 按 钮, 就 会 产 生Open() 事 件 函 数。 在 这 些 函 数 中 添 加 代 码, 以 及Pcomm Pro 的 串 行 控 制 函 数, 就 能 实 现 对 串 口 事 件 的 处 理。 其 中 一 个 需 要 注 意 的 问 题 是SendData 和ReceiveData 都 为 AnsiString 字 符 串, 而Pcomm Pro 的 函 数 所 需 发 送 和 接 收 的 字 符 串 都 为 char 型, 因 此 要 正 确 使 用Pcomm 函 数, 还 要 注 意 字 符 串 转 换。AnsiString 字 符 串 可 通 过c_str() 函 数 转 换 为char 型, 而char 行 字 符 串 转 换 为 AnsiString 则 比 较 简 单。 可 用AnsiString(char) 把char 型 强 制 转 换 为AnsiString 型。 程 序 主 要 代 码 如 下 所 示:
void __fastcall TComm::Open (TObject *Sender)
// 串 口 打 开 函 数
{
int i;
sio_open (port); // 打 开 串 口
sio_ioctl (port, B2400, P_NONE | BIT_7 | STOP_1 );
// 设 置 串 口 参 数
// 包 括 波 特 率、数 据 位、停 止 位、奇 偶 校 验
void __stdcall ( *p)(int);
p=cntirq;
i=sio_cnt_irq(port, *p,1);// 设 置 中 断 函 数
}
// - - - - - - - - - - - - - - - - -
void __fastcall TComm::Sent (TObject *Sender)
// 数 据 发 送 函 数
{
char *SendData=new char[20];
SendData=SentEdit ->Text.c_str();
// 把SendEdit 中 的AnsiString 型 字
符 串 转 换 为char 型
sio_write(port,SendData,20); // 发 送 数 据
}
// - - - - - - - - - - - - - - - - -
void __fastcall TComm::Close (TObject *Sender)
// 串 口 关 闭 函 数
{
sio_close (port); // 关 闭 串 口
}
// - - - - - - - - - - - - - - - - -
void __stdcall cntirq(int port)
// 中 断 服 务 函 数( 手 工 生 成 函 数)
{
char ibuf[20];
AnsiString ReceiveData[20];
sio_read (port,ibuf, 20); // 接 收 数 据
ReceiveData = Ansistring(ibuf);
//char 字 符 串 转 换AnsiString 型 字 符 串
ReceiveEdit ->Text=ReceiveData;
// 显 示 接 受 到 的 字 符 串
}
----在 程 序 中, 我 们 使 用 了 一 些sio_xxx() 型 的 函 数, 它 们 都 是Pcomm pro 自 带 的 串 行 通 信 函 数( 函 数 的 具 体 用 法 可 以 参 考Pcomm pro 的 帮 助), 通 过 这 些 函 数, 我 们 可 以 对 串 行 端 口 进 行 设 置。
----sio_open(port) 和sio_close(port) 为 打 开 串 口 和 关 闭 串 口 函 数, 参 数port 可 设 置 具 体 操 作 的 串 口;sio_ ioctl(int port, int baud, int mode) 为 串 口 控 制 函 数, 可 设 置 串 口 的 波 特 率、 数 据 位、 停 止 位、 奇 偶 校 验; 至 于sio_write(port) 和sio_read(port), 则 为 读 串 口 和 写 串 口 函 数;sio_cnt_irq(int port,VOID (CALLBACK *func)(int port), int count) 为 中 断 函 数, 当 串 口 有 数 据 时, 就 触 发 该 函 数, 然 后 该 函 数 就 会 启 动 其 中 断 服 务 程 序VOID (CALLBACK *func)(int port)( 为 一 函 数 指 针), 这 里 是 调 用cntirq() 函 数 接 收 数 据, 该 函 数 需 要 程 序 员 手 工 生 成。
----由 此 我 们 可 以 看 出, 只 要 我 们 对 程 序 稍 加 修 改, 在 表 单 上 再 添 加 一 些 控 件, 使 得sio_xxx() 这 些 函 数 的 参 数 可 以 由 用 户 界 面 输 入, 就 可 以 做 到 由 用 户 选 定 进 行 数 据 传 输 的 通 信 端 口, 并 设 定 这 个 端 口 的 相 关 参 数, 包 括 波 特 率、 数 据 位、 停 止 位、 奇 偶 校 验 和 流 量 控 制 等
本栏文章均来自于互联网,版权归原作者和各发布网站所有,本站收集这些文章仅供学习参考之用。任何人都不能将这些文章用于商业或者其他目的。( Pfan.cn )
【编程爱好者论坛】