RS485发送并接收16位数据

1 常用RS485

通常使用RS485是在串口的基础之上,外加485芯片,如下图所示。

2 RS485传送数据限制在8位的原因

实验室里有个项目,需要在两个单片机之间进行485通信传送数据,在淘宝买了两个485模块想通过485模块发送数据,发现直接通过串口转换的数据长度最大只是255,查看代码后发现,串口的配置代码中数据长度是8位,代码如下所示。

    USART_InitStructure.USART_BaudRate = bound;//波特率设置
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8位数据长度
    USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
    USART_InitStructure.USART_Parity = USART_Parity_No;///奇偶校验位
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收发模式
    USART_Init(USART3, &USART_InitStructure); ; //初始化串口

3 发送功能实现

我参考的程序是正点原子的程序,发送功能如下所示:

//RS485发送len个字节.
//buf:发送区首地址
//len:发送的字节数(为了和本代码的接收匹配,这里建议不要超过64个字节)
void RS485_Send_Data(u8 *buf,u8 len)
{
	u8 t;
  	for(t=0;t<len;t++)		//循环发送数据
	{		   
		while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);	  
		USART_SendData(USART3,buf[t]);
	}	 
	while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);		
	RS485_RX_CNT=0;	  

}

代码可以实现发送len个长度的uint8_t类型的数据。

经过改良,我可以一次发送两个8位数据,如下所示:

uint16_t Tx=55555;
uint8_t TxData[2];
//将Txz转换成两个8位数据进行传送
TxData[0] = (Tx[0]&0xFF00)>>8;
TxData[1] = (Tx[0]&0x00FF);

在通过RS485_Send_Data(TxData,2)即可发送两个8位数据。

封装过如下代码所示:

//一次发送10个16位的数据
void get_val(uint16_t ch[10],uint8_t T_D[20])
{
    //第一个数
    T_D[0] = (ch[0]&0xFF00)>>8;
    T_D[1] = (ch[0]&0x00FF);
     //第二个数
    T_D[2] = (ch[1]&0xFF00)>>8;
    T_D[3] = (ch[1]&0x00FF);
     //第三个数
    T_D[4] = (ch[2]&0xFF00)>>8;
    T_D[5] = (ch[2]&0x00FF);
     //第四个数
    T_D[6] = (ch[3]&0xFF00)>>8;
    T_D[7] = (ch[3]&0x00FF);
     //第五个数
    T_D[8] = (ch[4]&0xFF00)>>8;
    T_D[9] = (ch[4]&0x00FF);
     //第6个数
    T_D[10] = (ch[5]&0xFF00)>>8;
    T_D[11] = (ch[5]&0x00FF);
     //第7个数
    T_D[12] = (ch[6]&0xFF00)>>8;
    T_D[13] = (ch[6]&0x00FF);
     //第8个数
    T_D[14] = (ch[7]&0xFF00)>>8;
    T_D[15] = (ch[7]&0x00FF);
     //第9个数
    T_D[16] = (ch[8]&0xFF00)>>8;
    T_D[17] = (ch[8]&0x00FF);
     //第10个数
    T_D[18] = (ch[9]&0xFF00)>>8;
    T_D[19] = (ch[9]&0x00FF);
    
}

经过改进后代码如下:

void get_valx(uint16_t ch[10],uint8_t T_D[20])
{
    static int i=0;
    for(int k=0;k<10;k++)
    {
        T_D[i] = (ch[k]&0xFF00)>>8;
        T_D[i+1] = (ch[k]&0x00FF);
        i+=2;
    }
}

4 接收功能实现

接收数据的功能是正点原子代码经过改良,可一次接收64个uint8_t类型的数据,长度可自行更改。

//接收缓存区 	
u8 RS485_RX_BUF[64];  	//接收缓冲,最大64个字节.
//接收到的数据长度
u8 RS485_RX_CNT=0;   		  
  
void USART3_IRQHandler(void)
{
	u8 res;	    
 
 	if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) //接收到数据
	{	 
	 			 
		res =USART_ReceiveData(USART3); 	//读取接收到的数据
		if(RS485_RX_CNT<64)
		{
			RS485_RX_BUF[RS485_RX_CNT]=res;		//记录接收到的值
			RS485_RX_CNT++;						//接收数据增加1 
		} 
	}  											 
} 


//RS485查询接收到的数据
//buf:接收缓存首地址
//len:读到的数据长度
void RS485_Receive_Data(u8 *buf,u8 *len)
{
	u8 rxlen=RS485_RX_CNT;
	u8 i=0;
	*len=0;				//默认为0
	delay_ms(10);		//等待10ms,连续超过10ms没有接收到一个数据,则认为接收结束
	if(rxlen==RS485_RX_CNT&&rxlen)//接收到了数据,且接收完成了
	{
		for(i=0;i<rxlen;i++)
		{
			buf[i]=RS485_RX_BUF[i];	
		}		
		*len=RS485_RX_CNT;	//记录本次数据长度
		RS485_RX_CNT=0;		//清零
	}
}

接收也可以一次接收两个8位数据长度,并进行整合。

uint8_t rx[2];
uint16_t ch;

ch=((rx[0]&0x00FF)<<8)|(rx[1]&0xFF);

经过转换即将两个数据整合到一起,一次接收10个16位的数据,具体实现如下所示。

void Receive_Val(uint16_t ch[10],uint8_t rx[20])
{
    ch[0]=((rx[0]&0x00FF)<<8)|(rx[1]&0xFF);
    ch[1]=((rx[2]&0x00FF)<<8)|(rx[3]&0xFF);
    ch[2]=((rx[4]&0x00FF)<<8)|(rx[5]&0xFF);
    ch[3]=((rx[6]&0x00FF)<<8)|(rx[7]&0xFF);
    ch[4]=((rx[8]&0x00FF)<<8)|(rx[9]&0xFF);
    ch[5]=((rx[10]&0x00FF)<<8)|(rx[11]&0xFF);
    ch[6]=((rx[12]&0x00FF)<<8)|(rx[13]&0xFF);
    ch[7]=((rx[14]&0x00FF)<<8)|(rx[15]&0xFF);
    ch[8]=((rx[16]&0x00FF)<<8)|(rx[17]&0xFF);
    ch[9]=((rx[18]&0x00FF)<<8)|(rx[19]&0xFF);
}

经过改良如下所示:

void Receive_Valx(uint16_t ch[10],uint8_t rx[20])
{
    static int i=0;
    for(int j=0;j<10;j++)
    {
        ch[j]=((rx[i]&0x00FF)<<8)|(rx[i+1]&0xFF);
        i+=2;
    }
}

经过整理,便可以将两端数据进行整合,发送和接收便都可以以16位数据进行计算了。

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值