51单片机与串口通信代码
作者:佚名 来源:本站原创 点击数: 9407 更新时间:2007年06月17日 【字体:大 中 小】
1. 发送:向总线上发命令
2. 接收:从总线接收命令,并分析是地址还是数据。 3. 定时发送:从内存中取数并向主机发送.
经过调试,以上功能基本实现,目前可以通过上位机对单片机进行实时控制。 程序如下:
//这是一个单片机C51串口接收(中断)和发送例程,可以用来测试51单片机的中断接收 //和查询发送,另外我觉得发送没有必要用中断,因为程序的开销是一样的 #i nclude
#define INBUF_LEN 4 //数据长度 unsigned char inbuf1[INBUF_LEN];
unsigned char checksum,count3 , flag,temp,ch; bit read_flag=0; sbit cp=P1^1; sbit DIR=P1^2; int i;
unsigned int xdata *RAMDATA; /*定义RAM地址指针*/
unsigned char a[6] ={0x11,0x22,0x33,0x44,0x55,0x66} ;
void init_serialcomm(void) {
SCON=0x50; //在11.0592MHz下,设置串行口波特率为9600,方式1,并允许接收 PCON=0x00; ES=1;
TMOD=0x21; //定时器工作于方式2,自动装载方式 TH0=(65536-1000)%6; TL0=(65536-1000)/256; TL1=0xfd; TH1=0xfd; ET0=1; TR0=1; TR1=1; // TI=0; EA=1; // TI=1; RAMDATA=0x1F45;
}
void serial () interrupt 4 using 3 { if(RI) { RI=0; ch=SBUF;
TI=1; //置SBUF空 switch(ch) {
case 0x01 :printf(\ TI=0;break; case 0x02 :printf(\ TI=0;break; case 0x03 :printf(\ TI=0;break; case 0x04 :printf(\ TI=0;break; default :printf(\ TI=0;break; } } }
//向串口发送一个字符
void timer0() interrupt 1 using 3{ // char i; flag++; TH0=0x00; TL0=0x00;
if(flag==10) {// cp=!cp;
// for(i=0;i<6;i++) P2=0x25; TI=1; temp=*RAMDATA; printf(\ TI=0;
// RAMDATA--; flag=0; } } //主程序 main() {
init_serialcomm(); //初始化串口 //向6264中送数据 {
*RAMDATA=0x33; } while(1) {
*RAMDATA=0x33;; } }
调试过程中遇到的问题:
1. 发送过程:在发送时必须保证TI=1:即发送缓冲器为空,否则将导致数据发不出去,如果想强制发送可以用:TI=1.具体发送数据:利用printf(“akjdfaklfj”);函数直接发送即可。
2. 接收过程:在接收时多选用中断方式,这样可以节约CPU的时间,提高效率,
1 Windows API通信函数方法
与通信有关的Windows API函数共有26个,但主要有关的有:
CreateFile() 用 “comn”(n为串口号)作为文件名就可以打开串口。 ReadFile() 读串口。 WriteFile() 写串口。 CloseHandle() 关闭串口句柄。
初始化时应注意CreateFile()函数中串口共享方式应设为0,串口为不可共享设备,其它与一般文件读写类似。以下给出API实
现的源代码。 1.1 发送的例程 //声明全局变量 HANDLE m_hIDComDev;
OVERLAPPED m_OverlappedRead, m_Over lappedWrite; //初始化串口
void CSerialAPIView::OnInitialUpdate() {
CView::OnInitialUpdate(); Char szComParams[50]; DCB dcb;
Memset(&m_OverlappedRead, 0, sizeof (OVERLAPPED)); Memset(&m_OverlappedWrite, 0, sizeof (OVERLAPPED)); m_hIDComDev = NULL;
m_hIDComDev = CreateFile(“COM2”, GENERIC_READ│GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL│FILE_FLAG_OVERLAPPED, NULL); if (m_hIDComDev == NULL) {
AfxMessageBox(“Can not open serial port!”); goto endd; }
memset(&m_OverlappedRead, 0, sizeof (OVERLAPPED)); memset(&m_OverlappedWrite, 0, sizeof (OVERLAPPED)); COMMTIMEOUTS CommTimeOuts;
CommTimeOuts.ReadIntervalTimeout=0×FFFFFFFF; CommTimeOuts.ReadTotalTimeoutMultiplier = 0; CommTimeOuts.ReadTotalTimeoutConstant = 0; CommTimeOuts.WriteTotalTimeoutMultiplier = 0; CommTimeOuts.WriteTotalTimeoutConstant = 5000; SetCommTimeouts(m_hIDComDev, &CommTimeOuts); Wsprintf(szComparams, “COM2:9600, n, 8, 1”);
m_OverlappedRead. hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); m_OverlappedWrite. hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); dcb. DCBlength = sizeof(DCB); GetCommState(m_hIDComDev, &dcb); dcb. BaudRate = 9600; dcb. ByteSize= 8; unsigned char ucSet;