这是一个用双字节命令发送指定长字符串的一协议帧的例子 只是程序结构太差,在发送数据期间,无法做其他事,如果USB来数据来怎么办,每隔10毫秒要做的事来了怎么办,其他中断来了怎么办 这种程序应该是目前广大工程师的弊病。 如果大家要一个好的例子,我可以发一个过来:
void Init_UART0(void) { SCON0=0x010; //RECIEVE ENABLE PCON=0x080; //SMOD=1 //;定时器0=方式1,定时器1=方式2(自动重装入8位计数器,波特率发生器) TMOD=0x21; //TIMER0 MODE=1, TIMER1 MODE=2, 8 BIT COUNTER TCON=0x00; UART0_SetBaud(UART0_BAUD);
TI0=0; //CLEAR FLAG RI0=0; //CLEAR FLAG ET0=0; //CLOSE TIMER0 INT ET1=0; //CLOSE TIMER1 INT TR0=0; //CLOSE TIMER0 TR1=1; //OPEN TIMER1 ES0=1; //OPEN COMMINT }
//设置波特率,用于动态波特率自适应的 //------------------------------------------------------------------------------- void UART0_SetBaud(unsigned char BaudIndex) { // at sysclk=12Mhz switch (BaudIndex) { case 0: TH1=0x98; //1200BIT/S,at SYSCLK/48 CKCON=(CKCON & 0xFC)|0x02; break; case 1: TH1=0x30; //2400BIT/S,at SYSCLK/12 CKCON=CKCON & 0xFC; break; case 2: TH1=0x98; //4800BIT/S,at SYSCLK/12 CKCON=CKCON & 0xFC; break; case 3: TH1=0xCC; //9600BIT/S,at SYSCLK/12 CKCON=CKCON & 0xFC; break; case 4: TH1=0xE6; //19200BIT/S,at SYSCLK/12 CKCON=CKCON & 0xFC; break; case 5: TH1=0x98; //28800BIT/S,at SYSCLK/4 CKCON=(CKCON & 0xFC) | 0x01; break; case 6: TH1=0xCC; //57600BIT/S,at SYSCLK/4 CKCON=(CKCON & 0xFC) | 0x01; break; case 7: TH1=0xE6; //115200BIT/S,at SYSCLK/4 CKCON=(CKCON & 0xFC) | 0x01; break; default: TH1=0xCC; //9600BIT/s break; } }
//中断函数 void UART0_ISR(void) interrupt VECTOR_UART0 { if (RI0) UART0_Read(); if (TI0) UART0_Write(); }
//中断读取,先入缓冲,再作具体处理,处理时间不要太长, //以便接收下一个字节,如果太长,置标志在主程序处理。 void UART0_Read(void) { RI0=0; UART0_RBUF_Index=(UART0_RBUF_Index+1) % UART0_RBUF_Size; UART0_RBUF[UART0_RBUF_Index]=SBUF0; if(UART0_RBUF_Count<UART0_RBUF_Size) UART0_RBUF_Count++; //to control
UART0_Received=1; IntEvent_On=1; } //中断发送 void UART0_Write(void) { TI0=0; UART0_Write_Char_On=0; if(!UART0_Send_On) return; if (UART0_TBUF_Count>0) { UART0_TBUF_Count-=1; SBUF0=UART0_TBUF[ ((UART0_TBUF_Index-UART0_TBUF_Count+UART0_TBUF_Size)%UART0_TBUF_Size) ]; UART0_Write_Char_On=1; //after update sbuf0 } else { UART0_Send_On=0; } }
void UART0_WaitSend(void) { while (UART0_Send_On); }
//发射一个字节,不用等待,后台发送 void UART0_Send_Char(unsigned char c) {
#ifdef MD5_Encode_On if (MD5_OK_On) { c ^= MD5_Encode_Char; } #endif
while(UART0_TBUF_Count>=UART0_TBUF_Size); UART0_Send_On=0; UART0_TBUF_Index=(UART0_TBUF_Index+1) % UART0_TBUF_Size; UART0_TBUF[UART0_TBUF_Index]=c; UART0_TBUF_Count++; UART0_Send_On=1; if(!UART0_Write_Char_On) TI0=1; }
//发送数据包 void UART0_Send_String(unsigned char *s,unsigned char len) { unsigned char i; for (i=0;i<len;i++) UART0_Send_Char (s); }
通过以上函数加上适当定义即可以很方便地完成串行通信。且不影响主程序哟!
QQ:184324486 手机:13527614127
|