485通讯(2)

如图: 1-2-3-4这四路RS485是通过一个开关在一起的,5是独立的普通RS485在前面的文章中已经OK

今天说一下中间这个开关:74LV4052相当于一个双刀四掷开关,具体接通哪一通道,由输入地址码AB来决定

这个器件用到4个管脚,TX RX就是STM32的USART2,而另外2个就是普通IO即可,我通过设置0和1就可以出现00/01/10/11这样4中情况,这样4中情况分别对应右边4路RS485的某一路导通。具体是怎么一一对应的?现在不关心,需要看datasheel,我们自己盲人摸象,哪一路通了就是和它对应的。


void RS485_1234_Init(void)
{
		GPIO_InitTypeDef   GPIO_InitStructure;
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;        
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;            
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
		GPIO_Init(GPIOG, &GPIO_InitStructure);/*1号*/

		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;        
		GPIO_Init(GPIOG, &GPIO_InitStructure);/*2号*/

		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;        
		GPIO_Init(GPIOG, &GPIO_InitStructure);/*3号*/	

		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;        
		GPIO_Init(GPIOG, &GPIO_InitStructure);/*4号*/

		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;        
		GPIO_Init(GPIOG, &GPIO_InitStructure);/*S0*/	

		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;        
		GPIO_Init(GPIOG, &GPIO_InitStructure);/*S1*/	
	
}

void Choise_RS485_1234(u8 num)
{
	switch(num)
	{
		case 1:SW_S0_L();SW_S1_L();			break;
		case 2:SW_S0_H();SW_S1_L();			break;
		case 3:SW_S0_L();SW_S1_H();			break;
		case 4:SW_S0_H();SW_S1_H();			break;
		default :break;
	}
}

void TS_74LV4052_Init(void)
{
    USART_Config(2, 9600, USART_WordLength_8b, USART_Parity_No,  2,  0, ENABLE, DISABLE);/*USART2*/
	  RS485_1234_Init();
}


void TS_74LV4052_SendMgs(int num,u8 *Msg, u8 Len)
{
		Choise_RS485_1234(num);
    USART_GetFlagStatus(USART2,USART_FLAG_TC);
    if(Len)
    {
        TS_74LV4052_On();
        USART_SendData(USART2, 0xFE);
        while(USART_GetFlagStatus(USART2, USART_FLAG_TC)==RESET)  ;
        USART_SendData(USART2, 0xFE);
        while(USART_GetFlagStatus(USART2, USART_FLAG_TC)==RESET)        ;
        USART_SendData(USART2, 0xFE);
        while(USART_GetFlagStatus(USART2, USART_FLAG_TC)==RESET)        ;
        USART_SendData(USART2, 0xFE);
        while(USART_GetFlagStatus(USART2, USART_FLAG_TC)==RESET)        ;
        while(Len--)
        {
            USART_SendData(USART2, *(Msg++));
            while(USART_GetFlagStatus(USART2, USART_FLAG_TC)==RESET);
        }
        TS_74LV4052_Off();
    }
}
#define SW_S0_H()         		GPIO_SetBits(GPIOG ,GPIO_Pin_14)
#define SW_S0_L()	       		  GPIO_ResetBits(GPIOG ,GPIO_Pin_14) 
#define SW_S1_H()         		GPIO_SetBits(GPIOG ,GPIO_Pin_13)
#define SW_S1_L()	       		  GPIO_ResetBits(GPIOG ,GPIO_Pin_13) 
#define RS485_1DET_ON         GPIO_SetBits(GPIOG,GPIO_Pin_8) 
#define RS485_1DET_OFF        GPIO_ResetBits(GPIOG,GPIO_Pin_8) 
#define RS485_2DET_ON         GPIO_SetBits(GPIOG,GPIO_Pin_9) 
#define RS485_2DET_OFF        GPIO_ResetBits(GPIOG,GPIO_Pin_9) 
#define RS485_3DET_ON         GPIO_SetBits(GPIOG,GPIO_Pin_10) 
#define RS485_3DET_OFF        GPIO_ResetBits(GPIOG,GPIO_Pin_10) 
#define RS485_4DET_ON         GPIO_SetBits(GPIOG,GPIO_Pin_11) 
#define RS485_4DET_OFF        GPIO_ResetBits(GPIOG,GPIO_Pin_11) 

#define TS_74LV4052_On()      RS485_1DET_ON;RS485_2DET_ON;RS485_3DET_ON;RS485_4DET_ON
#define TS_74LV4052_Off()     RS485_1DET_OFF;RS485_2DET_OFF;RS485_3DET_OFF;RS485_4DET_OFF

先初始化:void TS_74LV4052_Init(void)

然后就可以去发消息了void TS_74LV4052_SendMgs(int num,u8 *Msg, u8 Len)

测试就是对的。

后面问题来了?如何收消息呢?平时都是低电平,也就是都是监听这,但是这个开关导致我一个时间点只能有一路是通的,所以我平时还需要轮训切换00-01-10-11这样等待某一个485过来消息。这样比较麻烦,如果4个都过来消息我就忙不过来了

猜你喜欢

转载自blog.csdn.net/weixin_42381351/article/details/81664722
今日推荐