/***串口基本操作****/
/*****************************************************************************************
串口程序
文件:BspUart0.h
功能:串口基本操作
平台:VS2008
编者:张永辉 2013年4月11日
张永辉 2013年4月16日整理
2013年5月17 重写BspUart0Recvs函数,让其可以连续接收
*****************************************************************************************/
#ifndef _BSPUART0_H_
#define _BSPUART0_H_
#include "\embed\source\lib\basetype.h"
//*********************************配置***************************************************
#define BSPU0_COMNAME "COM5" //使用固定端口名
#define BSPU0_BUFF_SIZE 2048 //缓冲区大小
#define BSPU0_BAUDRATE 115200 //波特率设置
//***************************************函数声明*****************************************
void BspUart0Test(void);
int BspUart0Init(void);
void BspUart0Itoa(unsigned int n);
void BspUart0Itoanr(unsigned int n);
void BspUart0String(unsigned char *str);
UINT32 BspUart0Recvs(char *buff,UINT32 len,UINT32 timeout);
UINT32 BspUart0Sends(char *buff,UINT32 len);
void BspUart0Close(void);
void BspUart0Test(void);
//****************************************************************************************
#endif
/*****************************************************************************************
串口程序
文件:BspUart0.c
功能:串口基本操作
平台:VS2008
编者:张永辉
*****************************************************************************************/
#undef UNICODE
#include <windows.h>
#include <stdio.h>
#include <process.h>
#include "BspUart0.h" //#include "\embed\vs2008\bsp\BspUart0.h"
#include "\embed\source\lib\math1.h"
//***********************************全局变量*********************************************
static HANDLE hCom; //串口句柄
static BOOL isOpend = FALSE; //打开标志位
/*****************************************************************************************
读取数据
*****************************************************************************************/
void BspUart0Test(void)
{
char a[]="1234567890";
int i = 0;
while(1)
{
BspUart0String("UART0 TEST:\n");
i = BspUart0Recvs(a,100,1000);
BspUart0String("1S recv:");BspUart0Itoanr(i);
}
BspUart0Close();
}
/*****************************************************************************************
初始化
*****************************************************************************************/
int BspUart0Init(void)
{
DCB dcb;
COMMTIMEOUTS TimeOuts;
BOOL bl = TRUE;
//不能重复初始化
if(isOpend!=FALSE)
{
return 1;
}
//创建文件
hCom = CreateFile(BSPU0_COMNAME,
GENERIC_READ|GENERIC_WRITE, //允许读和写
0, //独占方式
NULL,
OPEN_EXISTING, //打开而不是创建
//FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
0, //同步
//(FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED),//重叠方式,即非阻塞
NULL);
if(hCom == (HANDLE)-1)
{
return FALSE;
}
//输入缓冲区和输出缓冲区的大小都是 1024
bl &= SetupComm(hCom,BSPU0_BUFF_SIZE,BSPU0_BUFF_SIZE);
bl &= PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR); //清空缓冲区
//设定读超时
TimeOuts.ReadIntervalTimeout=1000; //读间隔超时
TimeOuts.ReadTotalTimeoutMultiplier=500; //读时间系数
TimeOuts.ReadTotalTimeoutConstant=500; //读时间常量
TimeOuts.WriteTotalTimeoutMultiplier=200; //写时间系数
TimeOuts.WriteTotalTimeoutConstant=200; //写时间常量
bl &= SetCommTimeouts(hCom,&TimeOuts); //设置超时
bl &= GetCommState(hCom,&dcb);
dcb.BaudRate=BSPU0_BAUDRATE; //波特率为 9600
dcb.ByteSize=8; //每个字节有 8 位
dcb.Parity=NOPARITY; //无奇偶校验位
dcb.StopBits=ONESTOPBIT; //1个停止位
bl &= SetCommState(hCom,&dcb);
if (bl==FALSE)
{
CloseHandle(hCom);
isOpend = FALSE;
return FALSE;
}
isOpend = TRUE;
return TRUE;
}
/*****************************************************************************************
发送,接收扩展函数
*****************************************************************************************/
void BspUart0Itoa(unsigned int n) //将数字转换成字符串,然后发送
{
int i;
unsigned char s[12];
for( i = 10;i >= 0;i--)
{
s[i] = ((n%10) + '0');
n = n /10;
}
//s[11]='\n';
BspUart0Sends(s,11);
}
void BspUart0Itoanr(unsigned int n) //将数字转换成字符串,加换行,然后发送
{
int i;
unsigned char s[12];
for( i = 10;i >= 0;i--)
{
s[i] = ((n%10) + '0');
n = n /10;
}
s[11]='\n';
BspUart0Sends(s,12);
}
void BspUart0String(unsigned char *str) //直接发送字符串
{
int len;
len = MathStrLen((const char*)str);
if(len ==0)
{return;}
BspUart0Sends(str,len);
}
/*****************************************************************************************
发送数据
*****************************************************************************************/
UINT32 BspUart0Sends(char *buffer,UINT32 dwBytesWritten)
{
UINT32 wrNum;
BOOL bl;
if(isOpend==FALSE)
{
return 0;
}
bl = WriteFile(hCom,buffer,dwBytesWritten,&wrNum,NULL);
if (bl==FALSE)
{
return 0;
}
return wrNum;
/* 暂时保留
DWORD dwErrorFlags;
COMSTAT ComStat;
OVERLAPPED m_OsWrite;
BOOL bWriteStat;
bWriteStat=WriteFile(hCom,buffer,dwBytesWritten, &dwBytesWritten,&m_OsWrite);
if(!bWriteStat)
{
if(GetLastError()==ERROR_IO_PENDING)
{
WaitForSingleObject(m_OsWrite.hEvent,1000);
return dwBytesWritten;
}
return 0;
}
return dwBytesWritten;
*/
}
/*****************************************************************************************
接收数据
*****************************************************************************************/
UINT32 BspUart0Reads_s(char *lpInBuffer,DWORD dwBytesRead);
UINT32 BspUart0Recvsss(char *buff,UINT32 len,UINT32 timeout)
{
UINT32 cnt = 0;
if(isOpend==FALSE)
{
return 0;
}
while(1)
{
cnt = BspUart0Reads_s(buff,len);
if ((cnt > 0) || (timeout-- == 0))
{
break;
}
Sleep(1);
}
return cnt;
}
UINT32 BspUart0Recvs(char *buff,UINT32 len,UINT32 timeout)
{
UINT32 cnt = 0;
UINT32 i = 0;
UINT32 flg = 0;
UINT32 byttime4 = (4 * 10 * 1000)/BSPU0_BAUDRATE; //接收4个数据的时间
if(isOpend==FALSE)
{
return 0;
}
while(1)
{
Sleep(1);
if ( len <= 0 )
{
break;
}
cnt = BspUart0Reads_s(&buff[i],len); //len 剩余空间 i 起始写位置
i += cnt;
len -= cnt;
//接收到数据后,要直到没有数据
if (cnt > 0 )
{
while(1)
{
if ( len <= 0 || cnt <= 0)
{
break;
}
Sleep(byttime4+1);
cnt = BspUart0Reads_s(&buff[i],len);
i += cnt;
len -= cnt;
}
break;
}
//没有收到数据则继续等待
timeout--;
if (timeout <= 0)
{
break;
}
}
return i;
}
UINT32 BspUart0Reads_s(char *lpInBuffer,DWORD dwBytesRead)
{
COMSTAT ComStat;
DWORD dwErrorFlags;
OVERLAPPED m_osRead;
BOOL bReadStatus;
memset(&m_osRead,0,sizeof(OVERLAPPED));
m_osRead.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
ClearCommError(hCom,&dwErrorFlags,&ComStat);
dwBytesRead=min(dwBytesRead,(DWORD)ComStat.cbInQue);
if(!dwBytesRead)
{
return FALSE;
}
bReadStatus=ReadFile(hCom,lpInBuffer,dwBytesRead,&dwBytesRead,&m_osRead);
if(!bReadStatus)
{
//GetLastError()函数返回 ERROR_IO_PENDING,表明串口正在进行读操作
if(GetLastError()==ERROR_IO_PENDING)
{
//使用 WaitForSingleObject 函数等待,直到读操作完成或延时 最大2秒钟
//当串口读操作进行完毕后,m_osRead 的 hEvent 事件会变为有信号
WaitForSingleObject(m_osRead.hEvent,2000);
//清空缓冲区
PurgeComm(hCom, PURGE_TXABORT| PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
return dwBytesRead;
}
return 0;
}
//清空缓冲区
PurgeComm(hCom,PURGE_TXABORT| PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
return dwBytesRead;
}
/*****************************************************************************************
关闭串口
*****************************************************************************************/
void BspUart0Close(void)
{
if(isOpend==FALSE)
{
return;
}
CloseHandle(hCom);
isOpend = FALSE;
}