OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 1923|回复: 5

STM32 RS485 串口62500波特率 中断接收丢数据

[复制链接]

2

主题

7

帖子

0

精华

新手上路

积分
24
金钱
24
注册时间
2018-10-30
在线时间
5 小时
发表于 2019-5-11 22:18:42 | 显示全部楼层 |阅读模式
1金钱
请教大神,有奖回复

最佳答案

查看完整内容[请看2#楼]

有始有终,问题已解决 ,中断接收那里 要将收到的数据先存储,后再打印查看, 接收一个输出一个有个切换的时序问题,造成接收数据丢失 发送那里是字节发送间隔1ms ,要将发送字节间隔 降低
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

7

帖子

0

精华

新手上路

积分
24
金钱
24
注册时间
2018-10-30
在线时间
5 小时
 楼主| 发表于 2019-5-11 22:18:43 | 显示全部楼层
有始有终,问题已解决
,中断接收那里 要将收到的数据先存储,后再打印查看, 接收一个输出一个有个切换的时序问题,造成接收数据丢失 发送那里是字节发送间隔1ms ,要将发送字节间隔 降低
回复

使用道具 举报

0

主题

79

帖子

0

精华

高级会员

Rank: 4

积分
727
金钱
727
注册时间
2016-5-27
在线时间
91 小时
发表于 2019-5-12 12:02:33 | 显示全部楼层
这就是个串口收发的问题,把代码发出来,我帮你看看。
回复

使用道具 举报

2

主题

7

帖子

0

精华

新手上路

积分
24
金钱
24
注册时间
2018-10-30
在线时间
5 小时
 楼主| 发表于 2019-5-12 13:53:44 | 显示全部楼层
本帖最后由 彩虹糖丶 于 2019-5-12 13:57 编辑

/*USART号、时钟、波特率*/
#define RS485_USART                   USART3
#define RS485_USART_BAUDRATE          62500
/*TX引脚*/
#define RS485_USART_TX_GPIO_PORT      GPIOB
#define RS485_USART_TX_PIN            GPIO_Pin_10
/*RX引脚*/
#define RS485_USART_RX_GPIO_PORT      GPIOB
#define RS485_USART_RX_PIN            GPIO_Pin_11

/*485收发控制引脚*/
#define RS485_RE_GPIO_PORT             GPIOC
#define RS485_RE_PIN                         GPIO_Pin_8
/*中断相关*/
#define RS485_INT_IRQ                 USART3_IRQn
#define RS485_IRQHandler              USART3_IRQHandler

/*控制收发引脚*/
//进入接收模式,必须要有延时等待485处理完数据
#define RS485_RX_EN()                          GPIO_ResetBits(RS485_RE_GPIO_PORT,RS485_RE_PIN);
//进入发送模式,必须要有延时等待485处理完数据
#define RS485_TX_EN()                          GPIO_SetBits(RS485_RE_GPIO_PORT,RS485_RE_PIN);



void bsp_rcc_init( void )
{

    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE );
    RCC_APB1PeriphClockCmd( RCC_APB1Periph_UART5, ENABLE );
    RCC_APB1PeriphClockCmd( RCC_APB1Periph_CAN1, ENABLE );
    RCC_APB1PeriphClockCmd( RCC_APB1Periph_UART4, ENABLE );
    RCC_APB1PeriphClockCmd( RCC_APB1Periph_USART2, ENABLE );
    RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM4, ENABLE );
         
    RCC_APB1PeriphClockCmd( RCC_APB1Periph_USART3, ENABLE);

}

void bsp_nvic_init( void )
{
    NVIC_InitTypeDef  NVIC_InitStructure;

    NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );

    NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 6;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init( &NVIC_InitStructure );

    /* Enable the USARTy Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = RS485_INT_IRQ;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =5;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}   

void RS485_Config(void)
{

    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;

    // 将USART Tx的GPIO配置为推挽复用模式
    GPIO_InitStructure.GPIO_Pin = RS485_USART_TX_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(RS485_USART_TX_GPIO_PORT, &GPIO_InitStructure);

    // 将USART Rx的GPIO配置为浮空输入模式
    GPIO_InitStructure.GPIO_Pin = RS485_USART_RX_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(RS485_USART_RX_GPIO_PORT, &GPIO_InitStructure);

    /* 485收发控制管脚 */
    GPIO_InitStructure.GPIO_Pin = RS485_RE_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(RS485_RE_GPIO_PORT, &GPIO_InitStructure);

    /* USART 模式配置*/
    USART_InitStructure.USART_BaudRate = RS485_USART_BAUDRATE;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    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(RS485_USART, &USART_InitStructure);
                USART_ITConfig(RS485_USART, USART_IT_RXNE, ENABLE);
    /*使能USART*/
    USART_Cmd(RS485_USART, ENABLE);

}


void RS485_IRQHandler(void)
{
     u8 u8RsTemp;

    if(USART_GetITStatus(RS485_USART, USART_IT_RXNE) != RESET)        /*接收到数据触发*/
    {
           u8RsTemp = USART_ReceiveData(USART3);         //读取接收到的数据
           printf("%02x, ", u8RsTemp);
    }
}
void RS485_SendCmd(  u8 * scmd )
{
    u8 i;
    for(i= 0; i< scmd[0]; i++)
    {
        RS485_SendByte(scmd[i+1]);
        vTaskDelay(1);
    }

}
/**********************************************************************************************************
* 功能   : RS485发送一个字节的数据
* 参数   : 要发送的字节数
* 返回值 : 无
* 注释   :        使用单字节数据发送前要使能发送引脚,发送后要使能接收引脚。
**********************************************************************************************************/
void RS485_SendByte(  u8 ch )
{

    /* 发送一个字节数据到USART3 */
    USART_SendData(RS485_USART,ch);
    /* 等待发送完毕 */
    while (USART_GetFlagStatus(RS485_USART, USART_FLAG_TC) == RESET);
}

        vTaskDelay(1);
        RS485_TX_EN();         //RS485 发送使能
        vTaskDelay(1);/*加短暂延时,保证485配置发送ok*/

        RS485_SendCmd(CatEngCmdEnter);         //发送数据
        printf("\n");
        for(i = 0; i < 5; i++)
        {
              printf("%02x, ", CatEngCmdEnter[i+1]);
        }
        printf("\n");
        vTaskDelay(1); /*加短暂延时,保证485发送数据完毕*/
        RS485_RX_EN();        //RS485 接收使能
        vTaskDelay(1);
        vTaskDelay(2000);

回复

使用道具 举报

2

主题

7

帖子

0

精华

新手上路

积分
24
金钱
24
注册时间
2018-10-30
在线时间
5 小时
 楼主| 发表于 2019-5-12 13:58:54 | 显示全部楼层
本帖最后由 彩虹糖丶 于 2019-5-12 14:00 编辑

两个同样的板子,一个做收,一个做发,发的时候字节延时1ms,能够正常收发但是板子和要通讯的设备通讯的时候,设备回复速度很快,中断接收的数据就不完整了,请教下这种情况该怎么处理
回复

使用道具 举报

0

主题

79

帖子

0

精华

高级会员

Rank: 4

积分
727
金钱
727
注册时间
2016-5-27
在线时间
91 小时
发表于 2019-5-12 16:36:36 | 显示全部楼层
彩虹糖丶 发表于 2019-5-12 13:58
两个同样的板子,一个做收,一个做发,发的时候字节延时1ms,能够正常收发但是板子和要通讯的设备通讯的时 ...

把串口中断函数中加个清标志的  USART_ClearITPendingBit(USART3,USART_IT_RXNE);
另外把在中断中发数据去了,改在外面另一个函数发送(最好别在中断中搞延时的事,发数据是要延时的等着数据发完才退出while)
再就是用你那个发送函数很好,为什么要用printf呢?回车换行 换成 0x0d0x0a就好了
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-19 19:23

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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