![]() |
中国DOS联盟-- 联合DOS 推动DOS 发展DOS --联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum |
| 游客 | 登录 | 注册 | 会员 | 搜索 | 中国DOS联盟 |
|
中国DOS联盟论坛 现在时间是 2026-10-31 06:37 |
共 47,815 主题排行 / 349,930 发帖 / 今日 0 篇 / 48,290 会员排行 |
| DOS开发编程 & 发展交流 (开发室) » 串行通讯口的实用编程[1] |
| 可打印版本 2,706 / 7 |
| 第1楼 firstsail | 发表于 2008-09-25 17:49 |
| 高级用户 发帖 295 积分 668 来自 广东深圳 | |
|
串行通讯口的实用编程[1] #include <Stdio.h>
#include <Stdlib.h> #include <bios.h> #include <dos.h> #include <conio.h> #include <string.h> #include <symbol.h> #include <DownComm.h> int main() { BYTE byCh; char buf[256]; CMotorNet mMotorNet; //使用通讯口COM1,波特率9600,8位数据位,1位起始位,1位停止位,无奇偶校验,查询方式 mMotorNet.Init(0x2F8, 9600, 8, 1, 1, NO_PARITY, FALSE); //如果中断方式, FALSE改为TRUE即可。 //发送一个字节 byData = 'W' mMotorNet.SendData(byData); //发送一个串 ::_fstrcpy(buf, "This is WinSail V2.0!"); mMotorNet.SendBuffer(buf, _strlen(buf) + 1); //接收一个数据 byCh = mMotorNet.ReceiveData(); if (byCh == 0 && GetLastCommError() == COMM_ERROR_CODE_TIME) { //这里没有读到数据 } else { //这里读到了数据 } //接收一个串,超时为165mS(=3 * 55mS) int nCount = mMotorNet.ReceiveData(buf, 256, 3); if (nCoun == 0) { //这里完全没有数据 } else if (nCount != 256) { //这里不足256字节的数据 } else { //这里读足了256字节数据 } //接收8个字节的串,有超时处理 BOOL bSuccess = TRUE; for (int i = 0; i < 8; i++) { if (!mMotorNet.WaitCommData(3)) //3 * 55mS超时 { bSuccess = FALSE; break; } buf[i] = mMotorNet.ReceiveData(); } if (bSuccess) { //成功读到8个字节 } else { //没有读到8个字节 } //接收8个字节的串,无超时处理 for (int i = 0; i < 8; i++) { while (!mMotorNet.IsCommData()) { } buf[i] = mMotorNet.ReceiveData(); } return(0); } |
|
| 第2楼 firstsail | 发表于 2008-09-25 17:51 |
| 高级用户 发帖 295 积分 668 来自 广东深圳 | |
|
串行通讯口的实用编程[2] //这里是DownComm.h文件
#ifndef _DOWN_COMMx_H_ #define _DOWN_COMMx_H_ #define COMM_ERROR_SUCCESS 0 #define COMM_ERROR_TIME -1 #define COMM_ERROR_USER -2 #define COMM_ERROR_CHECK -3 #define COMM_ERROR_BUSY -4 #define COMM_ERROR_DEFAULT -5 #define COMM_ERROR_OVER -6 #define COMM_ERROR_ADDRESS -7 #define COMM_ERROR_FORMAT -8 #define COMM_ERROR_ANSWER -9 #define COMM_ERROR_FILE -0xA #define COMM_ERROR_READY -0xB #define COMM_ERROR_CRAFT -0xC #define COMM_ERROR_AGAIN -0xD #define COMM_ERROR_BUFFER_FULL -0xE #define CBR_50 50lu #define CBR_110 110lu #define CBR_300 300lu #define CBR_600 600lu #define CBR_1200 1200lu #define CBR_2400 2400lu #define CBR_4800 4800lu #define CBR_9600 9600lu #define CBR_14400 14400lu #define CBR_19200 19200lu #define CBR_38400 38400lu #define CBR_56000 56000lu #define CBR_57600 57600lu #define CBR_115200 115200lu #define CBR_128000 128000lu #define CBR_256000 256000lu #define NOPARITY 0 #define ODDPARITY 1 #define EVENPARITY 2 #define MARKPARITY 3 #define SPACEPARITY 4 #define ONESTOPBIT 0 #define ONE5STOPBITS 1 #define TWOSTOPBITS 2 #define DTR_CONTROL_DISABLE 0x00 #define DTR_CONTROL_ENABLE 0x01 #define DTR_CONTROL_HANDSHAKE 0x02 #define RTS_CONTROL_DISABLE 0x00 #define RTS_CONTROL_ENABLE 0x01 #define RTS_CONTROL_HANDSHAKE 0x02 #define RTS_CONTROL_TOGGLE 0x03 #define COMM_DB25_TXD 2 //数据发送端,输出 #define COMM_DB25_RXD 3 //数据接收端,输入 #define COMM_DB25_RTS 4 //请求发送(计算机要求发送数据),输出 #define COMM_DB25_CTS 5 //清除发送(MODEM准备接收数据),输入 #define COMM_DB25_DSR 6 //数据设备准备就绪,输入 #define COMM_DB25_SG 7 //信号地 #define COMM_DB25_DCD 8 //数据载波检测,输入 #define COMM_DB25_DTR 20 //数据终端准备就绪(计算机),输出 #define COMM_DB25_RI 22 //响铃指示,输入 #define COMM_DB9_TXD 3 //数据发送端,输出 #define COMM_DB9_RXD 2 //数据接收端,输入 #define COMM_DB9_RTS 7 //请求发送(计算机要求发送数据),输出 #define COMM_DB9_CTS 8 //清除发送(MODEM准备接收数据),输入 #define COMM_DB9_DSR 6 //数据设备准备就绪,输入 #define COMM_DB9_SG 5 //信号地 #define COMM_DB9_DCD 1 //数据载波检测,输入 #define COMM_DB9_DTR 4 //数据终端准备就绪(计算机),输出 #define COMM_DB9_RI 9 //响铃指示,输入 #define COMM_REGISTER_THR 0 #define COMM_REGISTER_RBR 0 #define COMM_REGISTER_BAUDL 0 #define COMM_REGISTER_BAUDH 1 #define COMM_REGISTER_IER 1 #define COMM_REGISTER_IIR 2 #define COMM_REGISTER_FCR 2 #define COMM_REGISTER_LCR 3 #define COMM_REGISTER_MCR 4 #define COMM_REGISTER_LSR 5 #define COMM_REGISTER_MSR 6 #define COMM_REGISTER_SR 7 typedef struct tagCOMMCONTROL { int nIRQ; int nBase; int nErrorCode; void interrupt (*pOldFc) (...); DWORD dwBaud; WORD wDataBit; WORD wStartBit; WORD wStopBit; WORD wParity; BYTE* pBufferR; //输入缓冲区 int nSizeR; //输入缓冲区的尺寸 int nTailR; //输入缓冲区的尾指针 int nHeadR; //输入缓冲区的头指针 BOOL bFullR; //输入缓冲区的标志 BYTE* pBufferS; //输出缓冲区 int nSizeS; //输出缓冲区的尺寸 int nTailS; //输出缓冲区的尾指针 int nHeadS; //输出缓冲区的头指针 BOOL bFullS; //输出缓冲区的标志 }COMMCONTROL, *LPCOMMCONTROL; class CMotorNet { private: BOOL m_bInterrupt; int m_nIRQ; int m_nErrorCode; private: COMMCONTROL* GetCommControl(); void CloseInterrupt(); public: void ChangeParity(WORD wParity); void InitComm(int nBase, DWORD dwBaud, WORD wDataBit = 8, WORD wStartBit = 1, WORD wStopBit = 1, WORD wParity = NOPARITY, BOOL bInterrupt = FALSE); public: BOOL IsCommData(); BOOL IsBusy(); BOOL WaitCommData(DWORD dwWait); BYTE ReceiveData(); BOOL SendData(BYTE nCh); int ReceiveBuffer(BYTE* pBuffer, int nCount, DWORD dwTimeOut = 0lu); BOOL SendBuffer(BYTE* pBuffer, int nCount); void ClearBufferR(); void ClearBufferS(); public: int GetLastCommError(){return(m_nErrorCode);}; void SetLastCommError(int nErrorCode){m_nErrorCode=nErrorCode;} void ClearLastCommError(){m_nErrorCode=COMM_ERROR_SUCCESS;} public: CMotorNet(); ~CMotorNet(); }; #endif [ Last edited by firstsail on 2008-9-25 at 05:55 PM ] |
|
| 第3楼 firstsail | 发表于 2008-09-25 17:52 |
| 高级用户 发帖 295 积分 668 来自 广东深圳 | |
|
串行通讯口的实用编程[3] |
|
| 第4楼 firstsail | 发表于 2008-09-25 18:00 |
| 高级用户 发帖 295 积分 668 来自 广东深圳 | |
|
//此文件为WinSail V2.0下载后的“功能类_CMotorNet类串行通讯详细设计.DOC”文件
2 类简介 类名为CMotorNet,头文件是“DownComm.h”。 3 类成员函数 3.1 IsCommData() 原型:BOOL IsCommData(); 作用:判断是否有数据可读 入口参数:无 出口参数:无 返回值:有数据可读返回TRUE,否则返回FALSE。 3.2 IsBusy() 原型:BOOL IsBusy(); 作用:判断是否有数据可读,与IsCommData()函数作为相同 入口参数:无 出口参数:无 返回值:有数据可读返回TRUE,否则返回FALSE。 3.3 WaitCommData() 原型:BOOL WaitCommData(DWORD dwWait); 作用:在指定的时间内等待有数据可读 入口参数:DWORD dwWait ---- 时间计数值,以55mS为单位 出口参数:无 返回值:成功返回TRUE,否则返回FALSE 3.4 SendData() 原型:BOOL SendData(BYTE byCh); 作用:发送一个字节 入口参数:BYTE byCh ---- 需发送的字节 出口参数:无 返回值:成功发送返回TRUE,否则返回FALSE 3.5 ReceiveData() 原型:BYTE ReceiveData(); 作用:接收一个字节 入口参数:无 出口参数:无 返回值:成功返回数据值;否则返回0,并置通讯错误代码为COMM_ERROR_TIME 3.6 ReceiveBuffer() 原型:int ReceiveBuffer(BYTE* pBuffer, int nCount ,DWORD dwTimeOut = 0lu); 作用:接收多个字节 入口参数: int nCount----------需读取的字节数 DWORD dwTimeOut-----超时时间,以55mS为单位 出口参数:BYTE* pBuffer-------缓冲区首地址 返回值:返回接收的字节数 3.7 Void SendBuffer() 原型:void Re(); 作用:发送多个字节 入口参数:无 出口参数:无 返回值:无 3.8 Void ClearBufferR() 原型:void ClearBufferR(); 作用:在中断模式下,清除接收缓冲区 入口参数:无 出口参数:无 返回值:无 3.9 Void ClearBufferS() 原型:void ClearBufferS(); 作用:在中断模式下,清除发送缓冲区 入口参数:无 出口参数:无 返回值:无 3.10 ChangeParity() 原型:void ChangeParity(WORD wParity); 作用:修改奇偶校验属性 入口参数:WORD wParity --- 奇偶校验属性,见InitComm()函数 出口参数:无 返回值:无 3.11 Void InitComm() 原型:void InitComm(int nBase, DWORD dwBaud, WORD wDataBit = 8, WORD wStartBit = 1, WORD wStopBit = 1, WORD wParityStyle = NOPARITY, BOOL bInterrupt = FALSE); 作用:初始化通迅口 入口参数:int nBase --- 通讯口在基地址 COM1 = 0x3F8 COM2 = 0x2F8 COM3 = 0x3E8 COM4 = 0x2E8 DWORD dwBaud-----波特率,其值如下 CBR_50 50波特率 CBR_110 110波特率 CBR_300 300波特率 CBR_600 600波特率 CBR_1200 1200波特率 CBR_2400 2400波特率 CBR_4800 4800波特率 CBR_9600 9600波特率 CBR_14400 14400波特率 CBR_19200 19200波特率 CBR_38400 38400波特率 CBR_56000 56000波特率 CBR_57600 57600波特率 CBR_115200 115200波特率 CBR_128000 128000波特率 CBR_256000 256000波特率 WORD wDataBit---------数据位,值为5,6,7,8 WORD wStartBit--------起始位,值固定为“1” WORD wStopBit---------停止位,取值如下 ONESTOPBIT 1位停止位 ONE5STOPBITS 1.5位停止位 TWOSTOPBITS 2位停止位 WORD wParityStyle-----奇偶校验 NOPARITY 无校验 ODDPARITY 奇校验 EVENPARITY 偶校验 MARKPARITY 校验位永为“1” SPACEPARITY 校验位永为“0” BOOL bInterrupt-------中断模式,TRUE为中断模式,FALSE为查询模式 出口参数:无 返回值:无 3.12 int GetLastCommError() 原型:int GetLastCommError(); 作用:获得通讯错误代码 入口参数:无 出口参数:无 返回值:通讯错误代码。如果没有通讯错误,返回COMM_ERROR_SUCCESS 3.13 void SetLastCommError () 原型:void SetLastCommError (int nErrorCode); 作用:设置通讯错误代码 入口参数:int nErrorCode--------错误代码 出口参数:无 返回值:无 3.14 Void ClearLastCommError () 原型:int GetLastCommError(); 作用:清除通讯错误代码 入口参数:无 出口参数:无 返回值:无 [ Last edited by firstsail on 2008-9-25 at 06:20 PM ] |
|
| 第5楼 firstsail | 发表于 2008-09-25 18:02 |
| 高级用户 发帖 295 积分 668 来自 广东深圳 | |
|
1.2 RS232的寄存器
RS232共有12个寄存器 序号 地址 名称 信号方向 1 Base + 0 发送保持寄存器 只写 2 Base + 0 接收数据寄存器 只读 3 Base + 0 除数锁存寄存器(LSB),波特率低八位 可读写 4 Base + 1 除数锁存寄存器(MSB),波特率高八位 可读写 5 Base + 1 IER----中断启用寄存器 只读 6 Base + 2 IIR----中断标识寄存器 只读 7 Base + 2 FCR----FIFO寄存器 只写 8 Base + 3 LCR----线路控制寄存器 可读写 9 Base + 4 MCR----MODEM控制寄存器 可读写 10 Base + 5 LSR----线路状态寄存器 只读 11 Base + 6 MSR----MODEM状态寄存器 只读 12 Base + 7 暂时存储寄存器 可读写 IER = base + 1, 中断启用寄存器 B7, B6, B5, B4, B3, B2, B1, B0 | | | | | | | |_____允许接收数据就绪中断,置1时允许接收到数据时产生中断 | | | | | | |_________允许发送保持器空中断,置1时允许发送保持寄存器空时产生中断 | | | | | |_____________允许接收线路状态中断,即置1时将在LSR变化时产生中断 | | | | |_________________允许MODEM状态中断, 即置1时将在MSR变化时产生中断 | | | |_____________________进入睡眠模式(16750) | | |_________________________进入低功耗模式(16750) | |_____________________________未使用 |_________________________________未使用 IIR = base + 2, 中断识别寄存器,只读属性 B7, B6, B5, B4, B3, B2, B1, B0 | | | | | | | |_____指示是否有中断发生 | | | | | | | 0:有中断发生 | | | | | | | 1:无中断发生 | | | | | | | | | | | | |___\_________标识具体的中断类型,中断具有优先级,LSR最高,MSR最低 | | | | | 00:MODEL状态中断(CTS/RI/DTR/DCD) | | | | | 01:发送保持寄存器空中断 | | | | | 10:接收数据就绪中断 | | | | | 11:接收线路状态中断 | | | | |_________________超时中断(16550/16750) | | | |_____________________未使用 | | |_________________________允许64字节FIFO(16550/16750) | | |___\_____________________________00:无FIFO(此时是8250/16450芯片) 01:允许FIFO,但不可用 11:允许FIFO FCR = base + 2, FIFO控制寄存器,只写属性 B7, B6, B5, B4, B3, B2, B1, B0 | | | | | | | |_____允许FIFO | | | | | | |_________清除接收FIFO | | | | | |_____________清除发送FIFO | | | | |_________________DMA模式选择 | | | |_____________________未使用 | | |_________________________允许64字节FIFO | | |___\_____________________________00:1Byte产生中断 01:4Byte产生中断 11:8Byte产生中断 11:14Byte产生中断 LCR = base + 3, 线路控制寄存器,可读/写 B7, B6, B5, B4, B3, B2, B1, B0 | | | | | | | | | | | | | | |___\_____00:5位数据位 | | | | | | 01:6位数据位 | | | | | | 10:7位数据位 | | | | | | 11:8位数据位 | | | | | |_____________0->1位停止位;1->2位停止位(6,7,8);1->1.5位停止位(5) | | | | | | | | | | | | |___\___\_________________XX0:无校验 | | 001:奇校验 | | 011:偶校验 | | 101:奇偶保持为1 | | 111:奇偶保持为0 | |_____________________________设置间断,0-禁止,1-设置 |_________________________________0:允许访问接收/发送及中断允许寄存器 1:允许访问波特率因子寄存器 MCR = base + 4, MODEM控制寄存器,可读/写 B7, B6, B5, B4, B3, B2, B1, B0 | | | | | | | |_____设置DSR | | | | | | |_________设置RTS | | | | | |_____________辅助输出1 | | | | |_________________辅助输出2 | | | |_____________________环路测试 | | |_________________________自动流量控制(仅16750) | |_____________________________未使用 |_________________________________未使用 LSR = base + 5, 线路状态寄存器,只读 B7, B6, B5, B4, B3, B2, B1, B0 | | | | | | | |_____接收数据就绪 | | | | | | |_________超越错 | | | | | |_____________奇偶错 | | | | |_________________帧格式错 | | | |_____________________间断 | | |_________________________发送保持寄存器空 | |_____________________________发送移位寄存器空 |_________________________________FIFO中接收数据错误 MSR = base + 6, MODEM状态寄存器,只读 B7, B6, B5, B4, B3, B2, B1, B0 | | | | | | | |_____CTS已改变 | | | | | | |_________DSR已改变 | | | | | |_____________RI已改变 | | | | |_________________DCD已改变 | | | |_____________________CTS有效 | | |_________________________DSR准备就绪 | |_____________________________响铃指示 |_________________________________载波检测 1.3 波特率的计算 是用1.8432MHz时钟经过16分频的时钟(115200Hz)作为被除数,波特率作为除数,余数写入除数锁存寄存器中。 BYTE wDivL = LOBYTE(115200L/(DWORD)wBaud); BYTE wDivH = HIBYTE(115200L/ (DWORD)wBaud); |
|
| 第6楼 firstsail | 发表于 2008-09-25 18:24 |
| 高级用户 发帖 295 积分 668 来自 广东深圳 | |
|
DOS系统最多支持4个通讯口,分别为COM1、COM2、COM3、COM4。基地址分别对应于0x3F8、0x2F8、0x3E8、0x2E8。
RS232电缆一般是DB25或DB9物理接口,其意义如下: DB25 DB9 信号名称 方向 含义 2 3 TXD 输出 数据发送端 3 2 RXD 输入 数据接收端 4 7 RTS 输出 请求发送(计算机要求发送数据),低电平有效 5 8 CTS 输入 清除发送(MODEM准备接收数据),低电平有效 6 6 DSR 输入 数据设备准备就绪,低电平有效 7 5 GND 信号地 8 1 DCD 输入 数据载波检测,低电平有效 20 4 DTR 输出 数据终端准备就绪(计算机),低电平有效 22 9 RI 输入 响铃指示 在RS323电缆中,随着电缆长度的增加,信号遇到的电容就越多,从而使得数据的高速传输变得不可靠。并不是说在通讯时所有的管脚都被用上,这依赖于软件设计,但最简单的采用三线互联,RXD<—>TXD、TXD<—>RXD,GND<-->GND。 ![]() |
|
| 第7楼 lonm | 发表于 2009-09-18 12:45 |
| 新手上路 发帖 6 积分 12 | |
|
UP UP UP
|
|
| 第8楼 netreg | 发表于 2009-11-16 17:46 |
| 初级用户 发帖 17 积分 134 | |
|
UP UP UP
|
|
|
[ 联系联盟系统管理团队 -
中国DOS联盟 -
标准版 ] Sponsored by ifanr Inc | © 2001–2023 |