///***************************************************************************** //下面是test.c里面的函数 ///***************************************************************************** //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //串口猎人用的程序 ////////// //值得说明的是,CRC协议同样适用于串口猎人适用,也就是”协议”是通用的 //////// // USART1->DR=num; //////// //串口猎人只能发送hex值,即只能发送16进制的数据,才能显示出波形 ///////// // while((USART1->SR&0X40)==0); //////// // delay_ms(500); //////// // num-=1; //////// // if(num==0x00) //////// // num=0xff; /////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //值得说明的是,CRC协议同样适用于串口猎人适用,也就是”协议”是通用的 //////// //串口助手用的程序 //////// // printf("%d ",0XA5); //////// // printf("%d ",t); //////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Visualscope串口示波器的程序 //////// //////// for(i=0;i<4;i++)//先装载数据 //////// { //////// OutData[i]= num; //////// num-=70; //////// } //////// num=0xff; //////// OutPut_Data();//调用主函数 //////// delay_ms(10);//定义发送频率 //////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///***************************************************************************** //下面是USART.H里面的函数 ///***************************************************************************** //串口示波器的变量 extern float OutData[4];//这是全局变量 unsigned short CRC_CHECK(unsigned short *Buf, unsigned short CRC_CNT); void voTxIsr(void); void OutPut_Data(); ///*****************************************************************************//下面的是USART.C里面的文件 //这里用到了串口接收数据中断函数,所以需要把原先的数据串口中断函数屏蔽了 ///***************************************************************************** //the following is MCU code for CRC16 ,please refer. //------------------------------------------------------------------------------------------- #define ULONG unsigned long #define RxCountMax 18 //float OutData[4]; 这个是全局变量,在main函数和USART.H中都有定义 unsigned short TxBuf[10]; unsigned short RxBuf[RxCountMax]; unsigned short RxCnt; unsigned short TxCnt; unsigned short Rx50msCnt; unsigned long pAddr1,pAddr2,pAddr3,pAddr4; //CRC16校验算法 unsigned short CRC_CHECK(unsigned short *Buf, unsigned short CRC_CNT) { unsigned short CRC_Temp; unsigned char i,j; CRC_Temp = 0xffff; for (i=0;i<CRC_CNT; i++){ CRC_Temp ^= Buf[i]; for (j=0;j<8;j++) { if (CRC_Temp & 0x01) CRC_Temp = (CRC_Temp >>1 ) ^ 0xa001; else CRC_Temp = CRC_Temp >> 1; } } return(CRC_Temp); } //Receive interrupt routine 串口接收中断函数 void USART1_IRQHandler(void) { unsigned short i,CRC_RX,CRC_Tmp; RxBuf[RxCnt] = USART1->DR; //acquire data 接收数据 RxCnt++; if(RxCnt == RxCountMax) { CRC_Tmp = CRC_CHECK(RxBuf,16); //CRC Calculation 计算接收到的数据的CRC校验值 CRC_RX = ((unsigned short)RxBuf[RxCountMax-1]<<8) + RxBuf[RxCountMax-2]; //接收的数据中的最后两位就是CRC校验值 if(CRC_Tmp == CRC_RX){ //比较两个校验值是否相同 LED0=~LED0; //这里是我做的一个现象,通信成功就亮/灭一下灯 pAddr1 = ((ULONG)(RxBuf[0x3])<<24)|((ULONG)(RxBuf[0x2])<<16)|((ULONG)(RxBuf[0x1])<<8)|RxBuf[0x0]; //然后把数据保存起来 pAddr2 = ((ULONG)(RxBuf[0x7])<<24)|((ULONG)(RxBuf[0x6])<<16)|((ULONG)(RxBuf[0x5])<<8)|RxBuf[0x4]; pAddr3 = ((ULONG)(RxBuf[0xB])<<24)|((ULONG)(RxBuf[0xA])<<16)|((ULONG)(RxBuf[0x9])<<8)|RxBuf[0x8]; pAddr4 = ((ULONG)(RxBuf[0xF])<<24)|((ULONG)(RxBuf[0xE])<<16)|((ULONG)(RxBuf[0xD])<<8)|RxBuf[0xC]; } RxCnt = 0; } Rx50msCnt = 0; //to add--Clear Receive Data Register Fll flag; // USART1->DR=res; // while((USART1->SR&0X40)==0);// } //Transfer interrupt routine 串口发送数据函数 void voTxIsr(void) { if(TxCnt <= 9) { USART1->DR = TxBuf[TxCnt]; //Clear Tx interrupt flag TxCnt++; if(TxCnt >= 10) { //send interrupt disable TxCnt=0; } } } //------------------------------------------------------------------------------------------- //Monitor routine Execute every T Period time 应用函数,在主函数中直接调用这个就可以了 void OutPut_Data() { int temp[4] = {0}; unsigned int temp1[4] = {0}; unsigned short databuf[10] = {0}; unsigned char i; unsigned short CRC16 = 0; for(i=0;i<4;i++) { temp[i] = (u16)OutData[i]; //把要发送的数据传过来 temp1[i] = (u16)temp[i]; //并复制一份数据,进行下面的处理 } for(i=0;i<4;i++) { databuf[i*2] = (u8)(temp1[i]%256); //高低位处理 databuf[i*2+1] = (u8)(temp1[i]/256); } CRC16 = CRC_CHECK(databuf,8); //计算要发送数据的CRC16校验值 databuf[8] = CRC16%256; //并保存在databuf的8 9里面 databuf[9] = CRC16/256; for(i=0;i<10;i++)//把数据和校验位一起发送出去 { // voTxIsr(); if(TxCnt <= 9) { USART1->DR = databuf[TxCnt];//发送数据给寄存器 while((USART1->SR&0X40)==0);//直到发送完成才结束发送 TxCnt++; if(TxCnt >= 10) { TxCnt=0; //准备下次发送数据 } } } }