485通讯(2)
程序员文章站
2022-06-04 12:54:06
...
如图: 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个都过来消息我就忙不过来了
上一篇: 字典树