找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1468|回复: 0
打印 上一主题 下一主题
收起左侧

stm32 开发板的通信

[复制链接]
跳转到指定楼层
楼主
ID:984108 发表于 2021-11-25 13:38 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
void RS485_Init(u32 bound) ;

void RS485_Receive_Data(u8 *ReceiveBuf,u8 *len);

void RS485_Send_Data(u8 *SendBuf ,u8 len);



    void RS485_Init(u32 bound)

{

    GPIO_InitTypeDef GPIO_InitType;

    USART_InitTypeDef USART_InitType;

    NVIC_InitTypeDef NVIC_InitType;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD,ENABLE);       //使能GPIOA和GPIOD的时钟

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);                       //使能USART2的时钟





    GPIO_InitType.GPIO_Pin=GPIO_Pin_7;                                   //接收或者发送模式控制引脚PD7(初始化之后才能用)

    GPIO_InitType.GPIO_Mode = GPIO_Mode_Out_PP;                       //推挽输出

    GPIO_InitType.GPIO_Speed=GPIO_Speed_50MHz;                     //这个引脚是485芯片中的发送接收控制引脚

    GPIO_Init(GPIOD,&GPIO_InitType);                                   //当PDout(7)输出的是高电平‘1’时是发送,为‘0’时是接收



    GPIO_InitType.GPIO_Pin=GPIO_Pin_2;                                  //USART2的TX引脚是PA2

    GPIO_InitType.GPIO_Mode=GPIO_Mode_AF_PP;

    GPIO_InitType.GPIO_Speed=GPIO_Speed_50MHz;

    GPIO_Init(GPIOA,&GPIO_InitType);



    GPIO_InitType.GPIO_Pin=GPIO_Pin_3;                                  //USART2的RX引脚是PA3

    GPIO_InitType.GPIO_Mode=GPIO_Mode_IN_FLOATING;

    GPIO_InitType.GPIO_Speed=GPIO_Speed_50MHz;

    GPIO_Init(GPIOA,&GPIO_InitType);



    #ifdef EN_RS485_RX

        USART_InitType.USART_BaudRate=bound;                                        //串口2的初始化

        USART_InitType.USART_HardwareFlowControl=USART_HardwareFlowControl_None;

        USART_InitType.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;

        USART_InitType.USART_Parity=USART_Parity_No;                       //其中重要的是USART_Mode要既能接收又能发送

        USART_InitType.USART_StopBits=USART_StopBits_1;                   //USART2的波特率都设置为9600

        USART_InitType.USART_WordLength=USART_WordLength_8b;

        USART_Init(USART2,&USART_InitType);



        NVIC_InitType.NVIC_IRQChannel=USART2_IRQn;                          //USART2中断初始化

        NVIC_InitType.NVIC_IRQChannelCmd=ENABLE;                            //其实这个中断主要是对发送的数据及时处理,使接收时便捷高效

        NVIC_InitType.NVIC_IRQChannelPreemptionPriority=3;

        NVIC_InitType.NVIC_IRQChannelSubPriority=3;

        NVIC_Init(&NVIC_InitType);





        USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);            //要用到USART2中断除了初始化之外当然要对中断进行配置以及使能

        USART_Cmd(USART2,ENABLE);                                 //明确发生什么时会进入串口中断

    #endif

    RX485_TX_EN=0;              //默认接收模式   

}



这里的串口中断函数,发送的数据被接收数据寄存器接收到,就会触发中断,进行处理

#ifdef EN_RS485_RX



u8 RS485_RX_BUF[64];

u8 RS485_RX_CNT=0;

void USART2_IRQHandler(void)       //发送完数据就使能接收中断,使串口可以接收数据到缓冲区(数组RS485_RX_BUF)中

{

    u8 Res;

    if(USART_GetITStatus(USART2,USART_IT_RXNE)!=RESET)     

    {



        Res=USART_ReceiveData(USART2);

        if(RS485_RX_CNT<64)                         //一次接收的数据最多为64,超过之后将不会对发送过来的数据进行缓存

        {  

            RS485_RX_BUF[RS485_RX_CNT]=Res;

            RS485_RX_CNT++;

        }  

    }

}



#endif











void RS485_Send_Data(u8 *SendBuf ,u8 len)                       //发送处理函数

{

    u8 i;

    RX485_TX_EN=1;

    for(i=0;i<len;i++)                                                          //把长度为len的数组SendBuf发送出去

    {

        while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET);        //等待发送移位数据寄存器的数据非空时(即发送结束)跳出来

        USART_SendData(USART2,SendBuf[i]);                                          //发送数据

    }

    while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET);

    RX485_TX_EN=0;                                                                  //默认接收模式   

    RS485_RX_CNT=0;

}







void RS485_Receive_Data(u8 *ReceiveBuf,u8 *len)                     //接收处理函数

{

    u8 rxlen,i=0;

    rxlen=RS485_RX_CNT;

    delay_ms(10);

    if((rxlen==RS485_RX_CNT)&&rxlen)                             //把中断函数处理之后的缓存数据取出来

    {

        for(i=0;i<rxlen;i++)

        {

            ReceiveBuf[i]=RS485_RX_BUF[i];                       //传递接收到的数据以及长度回去

        }

        *len=RS485_RX_CNT;

        RS485_RX_CNT=0;                                            //对接收的个数进行清零,方便下次接收

    }



}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表