⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 send.cpp

📁 语音通信电路完整的程序设计。里面是所有的源文件都经本人测试可以用
💻 CPP
字号:
#include <windows.h>#include <stdio.h>//文件操作,访问I/O全靠它了#include <conio.h>//控制台I/O, getch()之类的#include <mmsystem.h>//多媒体的,我的程序中用到了多媒体定时器,一般windows定//时器,精度差。而多媒体定时器精度高,可精确到1mS.所以跟硬件打交道的时候就很//有用了。//下面的程序需要在project-->setting-->link中设置一下连接的库,否则compile能通//过,link通不过也白搭。库文件列表如下//kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib //shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib //kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib //shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib //winmm.lib//下面可以看我的程序了,这个程序是通过多媒体定时器每1mS,从串行口以115.2kbps的//波特率向外播放一个wave文件,弄这个干吗?我的板子可以放歌了。呵呵。#define TIME_INTERVAL 1//定时间隔,mS单位static UINT MyTimerID;//访问定时器的时候所用的定时器idstatic HANDLE hComm,hWaveFile;//串口和wave文件句柄static DCB Current_Comm_dcb = {0};//串口参数结构体,波特率,流量控制,校验//什么的static DCB Previous_Comm_dcb = {0};//同上static DWORD FileSize,rFileSize,PlayPosition;//一些变量,文件大小,播放指针static BYTE *FileBuffer;//文件缓冲区的指针,用malloc申请来的内存给他static OVERLAPPED osWrite = {0};//对问建交叠操作所必需的一个结构体。//交叠操作是指,用一个函数触发一下操作,然后函数立刻返回了,这时候你可以干别的//操作完成后会给信号的。98不支持的,2000和nt才支持。BOOL WriteABuffer(BYTE * lpBuf, DWORD dwToWrite)//将lpBuf所只想的缓冲区中//dwToWrite个字节通过串口发出。{   static DWORD dwWritten;   static BOOL fRes;   // Issue write.   if (!WriteFile(hComm, lpBuf, dwToWrite, &dwWritten, &osWrite)) {      if (GetLastError() != ERROR_IO_PENDING) {         // WriteFile failed, but it isn't delayed. Report error and abort.         fRes = FALSE;      }      else {         // Write is pending.         if (!GetOverlappedResult(hComm, &osWrite, &dwWritten, TRUE))            fRes = FALSE;         else            // Write operation completed successfully.            fRes = TRUE;      }   }   else      // WriteFile completed immediately.      fRes = TRUE;// CloseHandle(osWrite.hEvent);   return fRes;}void WINAPI TimerEventProc(UINT wTimerID, UINT msg,DWORD dwUser, DWORD dw1, DWORD dw2)//这个函数是定时器的回掉函数,定时事件发生后,它自动被调用。//我在这个函数里发送8个字节。{ static long delay=2000,j; WriteABuffer(&((BYTE)FileBuffer[PlayPosition]),1); PlayPosition++;// for(j=0;j<delay;j++); WriteABuffer(&((BYTE)FileBuffer[PlayPosition]),1); PlayPosition++;// for(j=0;j<delay;j++); WriteABuffer(&((BYTE)FileBuffer[PlayPosition]),1); PlayPosition++;// for(j=0;j<delay;j++); WriteABuffer(&((BYTE)FileBuffer[PlayPosition]),1); PlayPosition++;// for(j=0;j<delay;j++); WriteABuffer(&((BYTE)FileBuffer[PlayPosition]),1); PlayPosition++;// for(j=0;j<delay;j++); WriteABuffer(&((BYTE)FileBuffer[PlayPosition]),1); PlayPosition++;// for(j=0;j<delay;j++); WriteABuffer(&((BYTE)FileBuffer[PlayPosition]),1); PlayPosition++;// for(j=0;j<delay;j++); WriteABuffer(&((BYTE)FileBuffer[PlayPosition]),1); PlayPosition++;// for(j=0;j<delay;j++);}BOOL InitializeTimer(UINT *TimerID,UINT TimeInterval)//初始化定时器{ TIMECAPS tc; if(timeGetDevCaps(&tc, sizeof(TIMECAPS))==TIMERR_NOERROR) {  /*if(TIME_INTERVAL>=minforeach (foreach (function ()  {  }$array as $key => $value) {  }$array as $value) {  }(max(tc.wPeriodMin,1),tc.wPeriodMax))*/if(TimeInterval>=min(max(tc.wPeriodMin,1),tc.wPeriodMax))  {   timeBeginPeriod(TIME_INTERVAL);   printf("1\n");   getch();  }  else  {   return(FALSE);  } } else {  return(FALSE); } if(!((*TimerID)=timeSetEvent(TIME_INTERVAL,TIME_INTERVAL,(LPTIMECALLBACK) 	 TimerEventProc,(DWORD)1,TIME_PERIODIC))) {	 printf("2\n");	 getch();  return(FALSE); } else {	 printf("3\n");	 return(TRUE); }}void FreeTimer(UINT *TimerID, UINT TimeInterval)//释放定时器,如果忘了释放,嘿嘿。。{ timeKillEvent((*TimerID)); timeEndPeriod(TimeInterval);}void fbc(void)//普通二进制转折叠二进制编码,这是pcm编码标准必须的//对大家没什么用{DWORD j;int i;BYTE rom[256];for(i=0;i<128;i++)rom[i]=127-i;for(;i<256;i++)rom[i]=rom[255-i]+128;for(j=0;j<FileSize;j++){//FileBuffer[j]=FileBuffer[j]/2;FileBuffer[j] = rom[FileBuffer[j]];}}int main(int argc,char *argv[])//主函数开始了,睁大眼睛。{printf("Writen by jxj.2001.5. All rights reserved\n\n");//版权。if(argc<2){ printf("Require wave_File name!\n"); getch(); exit(1);}//wave文件名从命令行给PlayPosition=0;//播放指针回零printf("Open serial communication port ... ");//下面是怎么打开串口hComm = CreateFile( "com1",                    GENERIC_READ | GENERIC_WRITE,                    0,                    0,                    OPEN_EXISTING,                    FILE_FLAG_OVERLAPPED,//这个参数表明是交叠方式打开                    0);if (hComm == INVALID_HANDLE_VALUE){ printf("error!\n"); getch(); return(1);}else{ printf("successful!\n");}FillMemory(&Previous_Comm_dcb, sizeof(Previous_Comm_dcb), 0);FillMemory(&Current_Comm_dcb, sizeof(Current_Comm_dcb), 0);Previous_Comm_dcb.DCBlength = sizeof(Previous_Comm_dcb);Current_Comm_dcb.DCBlength = sizeof(Current_Comm_dcb);printf("Get previous CommState ... ");//得到当前串口设置if (!GetCommState(hComm, &Previous_Comm_dcb)){ printf("error!\n"); getch(); return(1);}else{ printf("successful!\n");}printf("Set current CommState ... ");//写一个你需要的串口设置的结构Current_Comm_dcb = Previous_Comm_dcb;Current_Comm_dcb.BaudRate = 115200;Current_Comm_dcb.fBinary = TRUE;Current_Comm_dcb.fParity = TRUE;Current_Comm_dcb.StopBits = ONESTOPBIT;Current_Comm_dcb.fDtrControl = DTR_CONTROL_DISABLE;Current_Comm_dcb.fRtsControl = RTS_CONTROL_DISABLE;Current_Comm_dcb.ByteSize = 8;Current_Comm_dcb.Parity = ODDPARITY;Current_Comm_dcb.fOutX = FALSE;Current_Comm_dcb.fInX = FALSE;//设置进入串口if (!SetCommState(hComm, &Current_Comm_dcb)){ printf("error!\n"); getch(); return(1);}else{ printf("successful!\n");}printf("Open WaveFile ... ");//打开普通的wave文件hWaveFile = CreateFile( argv[1],                    GENERIC_READ | GENERIC_WRITE,                    0,                    0,                    OPEN_EXISTING,                    FILE_ATTRIBUTE_NORMAL,                    0);if (hWaveFile == INVALID_HANDLE_VALUE){ printf("error!\n"); getch(); return(1);}else{ printf("successful!\n");}printf("Get file size ...");//获得文件大小,以便确定申请多大内存if (!(FileSize=GetFileSize(hWaveFile,NULL))){ printf("error!\n"); getch(); return(1);}else{ printf("%ld successful!\n",FileSize);}printf("Apply memory ... ");//申请内存if (!(FileBuffer = (BYTE *)malloc(FileSize))){ printf("error!\n"); getch(); return(1);}else{ printf("successful!\n");}printf("Fill the FileBuffer with WaveFile ... ");//文件放入内存if(!ReadFile(hWaveFile,FileBuffer,FileSize,&rFileSize,NULL)){ printf("error!\n"); getch(); return(1);}else{ if(FileSize!=rFileSize) {  printf("error!\n");  getch();  return(1); } printf("successful!\n");}fbc();printf("Initialize write ... ");//准备以交叠的方式写串口osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);//结构初始化一下if (osWrite.hEvent == NULL){ printf("error!\n"); getch(); return(1);}else{ printf("successful!\n");}printf("Initialize Timer ... ");//定时器初始化if (!InitializeTimer(&MyTimerID,TIME_INTERVAL)){ printf("error!\n"); getch(); return(1);}else{ printf("successful!\n");}while(PlayPosition<FileSize);//等待播放完毕 FreeTimer(&MyTimerID,TIME_INTERVAL); printf("Recover the previous CommState ... "); if (!SetCommState(hComm, &Previous_Comm_dcb)) {  printf("error!\n");  getch();  return(1); } else {  printf("successful!\n"); } CloseHandle(osWrite.hEvent); CloseHandle(hComm); CloseHandle(hWaveFile); return(0);}//我的板子上用的FLEX10K10LC84-4 FPGA芯片来通过MAX232电平转换接受,FPGA当中通信//用的UART是从QUICKLOGIC公司下载的免费IP核。//当然还有一个码速调整问题,因为115.2kbps最高实现8kHz,8bit的音频,定时精度达不到//8k,只能到1k,所以1mS发送8个字节,这8个是连在一起的.在fpga内部将它们在1mS之内//散开。实现均匀的8k.//8k 8bit自然是很不爽,后来用并口实现了48k 8bit,可以忍受了。

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -