本人想写一个stm32与组态王通讯的程序。在网上找了一些资料。里边有一块一直调试不通,请教一下大家。还有就是单片机作为从机地址怎么设置,还有数据地址怎么设置?
uchar AsciiToHex(uchar *StartAdd,uchar n)
{
uchar i,d;
for(i=0;i<n;i++)
{
d<<=4;
if(StartAdd>0x40) d=d+(StartAdd-0x37);
else d=d+(StartAdd-0x30);
}
return (d);
}
1)、stm32串口配置
void USART_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
USART_ClockInitTypeDef USART_ClockInitStructure;
USART_InitStructure.USART_BaudRate=115200;//波特率115200 USART_InitStructure.USART_WordLength=USART_WordLength_8b; //8位传输 USART_InitStructure.USART_StopBits=USART_StopBits_1;//1个停止位
USART_InitStructure.USART_Parity=USART_Parity_No;//无校验位
USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx; //RX|TX模式
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//禁止硬件流控,禁止RTS,CTS信号 USART_Init(USART1,&USART_InitStructure);
/*USART1时钟配置*/
USART_ClockInitStructure.USART_Clock=USART_Clock_Disable;//禁止串口时钟
USART_ClockInitStructure.USART_CPOL=USART_CPOL_Low;
USART_ClockInitStructure.USART_CPHA=USART_CPHA_2Edge;
USART_ClockInitStructure.USART_LastBit=USART_LastBit_Disable;
USART_ClockInit(USART1,&USART_ClockInitStructure);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//使USART1接收中断
USART_ClearFlag(USART1,USART_FLAG_TC);//一个一个字节发送时使用USART_FLAG_TXE,连续发送时用USART_FLAG_TC
USART_Cmd(USART1,ENABLE);
}
2)、stm32串口中断程序
void USART1_IRQHandler(void)
{
uchar buf;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
buf=(uchar)USART_ReceiveData(USART1);//读数据
if(RecFlag)
{
if(buf==0x0d)//判断接收完成
{
RecOK=1;
RecFlag=0;
}
else
{
RecBuf[RecCount]=buf;
RecCount++;
}
}
if(buf==0x40) //判断接收字头
RecFlag=1;
}
USART_ClearFlag(USART1,USART_FLAG_RXNE);
USART_ClearITPendingBit(USART1,USART_FLAG_RXNE);
}
3、接收数据的CRC校验程序
/***********ASCII码转换成16进制数***********/
uchar AsciiToHex(uchar *StartAdd,uchar n)
{
uchar i,d;
for(i=0;i<n;i++)
{
d<<=4;
if(StartAdd>0x40) d=d+(StartAdd-0x37);
else d=d+(StartAdd-0x30);
}
return (d);
}
/**********校验接收到的数据帧的CRC校验码********/
char ChackCRC(void)
{
uchar i,xordat,crc;
crc=AsciiToHex(&RecBuf[RecCount-2],2);
for(i=0,xordat=0;i<RecCount-2;i++)
xordat^=RecBuf;
RecCount=0;
if(crc==xordat) return 1;
else return 0;
}
4、下位机读写函数
/********下位机读函数********/
void ReadData(void)
{ uchar i,crc;
TBUF[0]=0x40;
TBUF[1]=RecBuf[0];
TBUF[2]=RecBuf[1];
TBUF[3]=RecBuf[8];
TBUF[4]=RecBuf[9];
for(i=ByteCount*2;i>0;i--)
{
if(ByteCount>1)
TBUF[ByteCount*2-i+5]=ASCII[(word[DatAdd-10]>>(i-1)*4)%16];
else
TBUF[ByteCount*2-i+5]=ASCII[(byte[DatAdd]>>(i-1)*4)%16];
}
for(i=1,crc=0;i<=ByteCount*2+4;i++)
{
crc^=TBUF;
}
TBUF[ByteCount*2+5]=ASCII[crc/16];
TBUF[ByteCount*2+6]=ASCII[crc%16];
TBUF[ByteCount*2+7]=0x0d;
for(i=0;i<ByteCount*2+8;i++)
DataSend(TBUF);
}
/*******下位机写函数********/
void WriteData(void)
{
uint i,dat,crc;
dat=AsciiToHex(&RecBuf[10],ByteCount*2);
if(ByteCount>1)
{
word[DatAdd-10]=dat;
}
else
{
byte[DatAdd]=dat;
}
TBUF[0]=0x40;
TBUF[1]=RecBuf[0];
TBUF[2]=RecBuf[1];
TBUF[3]=TBUF[4]=0x23;
crc=TBUF[1]^TBUF[2]^TBUF[3]^TBUF[4];
TBUF[5]=ASCII[crc/16];
TBUF[6]=ASCII[crc%16];
TBUF[7]=0x0d;
for(i=0;i<8;i++)
DataSend(TBUF);
}
5、Stm32与组态王通讯主程序部分
int main(void)
{
char CRCOK;
char RWFlag;
uint ii=0;
uchar DevAddr;
uchar BUF2438[8];
RCC_Configuration();
usart1_config();
TIM3_configuration();
nvic_config();
while(1)
{
if(RecOK) //串口接收完成
{
RecOK=0;
DevAddr=AsciiToHex(&RecBuf[0],2); //检查设备地址是否是本机地址
if(DevAddr==LOCAL)
{
RWFlag=(char)(AsciiToHex(&RecBuf[2],2)&0x01); //判断读写标志 0:读 1:写
DatAdd=AsciiToHex(&RecBuf[4],4);//获取数据地址
ByteCount=AsciiToHex(&RecBuf[8],2);//数据字节数
if(!RWFlag)//RWFlag=0,主机读数据
{
CRCOK=ChackCRC();
if(CRCOK)
{ //CRC校验OK
ReadData();
}//发送数据 else
{
Error(); //否则返回数据到主机
}
}
else //RWFlag=1 主机写数据
{
CRCOK=ChackCRC();
if(CRCOK) //CRC校验OK
WriteData(); //写数据 else
Error(); //错误 }
}
else RecCount=0; //清除串口接收数据计数
}
}
}
万分感谢。 |