OpenEdv-开源电子网

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

407移植FreeRTOS串口通信使用消息队列问题

[复制链接]

14

主题

57

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2018-11-15
在线时间
40 小时
发表于 2019-12-5 11:06:41 | 显示全部楼层 |阅读模式
5金钱
本帖最后由 Moose 于 2019-12-5 11:41 编辑

串口一没问题,在接收完成后使用消息队列发送没问题,建立一个任务接收可以,可是用的串口2,采用正点原子定时器标记接收完成的方式,加上发送消息队列,却接收有问题了,定时器抢占优先级也改为8了,串口2的抢占优先级为7,新建的接受任务应该没问题,但是接收不了。//串口2中断函数

void USART2_IRQHandler(void)
{
        u8 res;
    BaseType_t xHigherPriorityTaskWoken;
        if(USART_GetITStatus(USART2,USART_IT_RXNE)!=RESET)                //接收到数据
        {
                res=USART_ReceiveData(USART2);
                if((USART2_RX_STA&(1<<15))==0)                        //没有接收到数据,进行接收
                {
                        if(USART2_RX_STA<USART2_MAX_RECV_LEN)        //还可以接受数据
                        {        
                                TIM_SetCounter(TIM7,0);             //计数器清空
                                if(USART2_RX_STA==0)                                //第一次接收到数据
                                {
                                        TIM_Cmd(TIM7,ENABLE);                        //开启定时器
                                }
                                USART2_RX_BUF[USART2_RX_STA++]=res;

                        }else
                        {
                                USART2_RX_STA |= 1<<15;                                //标记位置1,此次数据接收完成
                        }
                }
        if((USART2_RX_STA&(1<<15)))
        {
            xQueueSendFromISR(WIFI_QUEUE,USART2_RX_BUF,&xHigherPriorityTaskWoken);//向队列中发送数据
               
            USART2_RX_STA=0;        
            memset(USART2_RX_BUF,0,USART2_MAX_RECV_LEN);    //清除数据接收缓USART2_RX_BUF,用于下一次数据接收
        
            portYIELD_FROM_ISR(xHigherPriorityTaskWoken);   //如果需要的话进行一次任务切换
        }
        }
}

//定时器的函数
void Tim7_init(u16 arr,u16 psc)
{        
        NVIC_InitTypeDef NVIC_InitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE);//TIM7时钟使能   
        
        //定时器TIM7初始化
        TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值        
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
        TIM_TimeBaseInit(TIM7, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位

    TIM_ClearITPendingBit(TIM7,TIM_IT_Update);
        TIM_ITConfig(TIM7,TIM_IT_Update,ENABLE ); //使能指定的TIM7中断,允许更新中断
        
        TIM_Cmd(TIM7,DISABLE);//关闭定时器7
        
        NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=8 ;//抢占优先级8
        NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;                //子优先级0
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
        NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器
        
}
//中断服务程序
void TIM7_IRQHandler(void)
{
        if(TIM_GetITStatus(TIM7,TIM_IT_Update)!=RESET)
        {
                USART2_RX_STA |= 1<<15;                                                //时间到,置位接收结束
                TIM_ClearITPendingBit(TIM7, TIM_IT_Update  );  //清除TIM7更新中断标志   
                TIM_Cmd(TIM7,DISABLE);
        }
}




//接收的任务函数
void wifi_task1(void *pvParameters)
{
    BaseType_t err;
    u8 pv[USART_REC_LEN];
        while(1)
    {
        LED0=~LED0;
        if(WIFI_QUEUE!=0)
        {
            err = xQueueReceive(WIFI_QUEUE,pv,portMAX_DELAY);
            if(err==pdTRUE)
            {
                printf("Recv2:%s\r\n",pvBuffer);
                memset(pv,0,USART_REC_LEN);
            }
        }
    }
}

RTOS练手项目.zip

13.82 MB, 下载次数: 84

最佳答案

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

你用定时器TIM7用于识别一帧报文接收完毕,建议你将代码改写成如下形式: void USART2_IRQHandler(void) { u8 res; if(USART_GetITStatus(USART2,USART_IT_RXNE)!=RESET) //接收到数据 { res=USART_ReceiveData(USART2); USART2_RX_BUF=res; TIM_Cmd(TIM7,DISBLE); //关闭定时器 TIM_SetCounter(TIM7,0); ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

19

主题

334

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1108
金钱
1108
注册时间
2018-11-6
在线时间
240 小时
发表于 2019-12-5 11:06:42 | 显示全部楼层
你用定时器TIM7用于识别一帧报文接收完毕,建议你将代码改写成如下形式:

void USART2_IRQHandler(void)
{
        u8 res;
   
        if(USART_GetITStatus(USART2,USART_IT_RXNE)!=RESET)                //接收到数据
        {
                res=USART_ReceiveData(USART2);
                USART2_RX_BUF[USART2_RX_STA++]=res;
                TIM_Cmd(TIM7,DISBLE);                        //关闭定时器       
                TIM_SetCounter(TIM7,0);             //计数器清空
                TIM_Cmd(TIM7,ENABLE);                        //开启定时器         
                portYIELD_FROM_ISR(xHigherPriorityTaskWoken);   //如果需要的话进行一次任务切换

        }
}



//TIM7中断服务程序
void TIM7_IRQHandler(void)
{
        if(TIM_GetITStatus(TIM7,TIM_IT_Update)!=RESET)
        {
                TIM_ClearITPendingBit(TIM7, TIM_IT_Update  );  //清除TIM7更新中断标志   
                TIM_Cmd(TIM7,DISABLE);
                xQueueSendFromISR(WIFI_QUEUE,USART2_RX_BUF,&xHigherPriorityTaskWoken);//向队列中发送数据           
                USART2_RX_STA=0;        
                memset(USART2_RX_BUF,0,USART2_MAX_RECV_LEN);    //清除数据接收缓USART2_RX_BUF,用于下一次数据接收

        }
}



//接收的任务函数
void wifi_task1(void *pvParameters)
{
    BaseType_t err;
    u8 pv[USART_REC_LEN];
        while(1)
    {
        LED0=~LED0;
        if(WIFI_QUEUE!=0)
        {
            err = xQueueReceive(WIFI_QUEUE,pv,portMAX_DELAY);
            if(err==pdTRUE)
            {
                printf("Recv2:%s\r\n",pvBuffer);
                memset(pv,0,USART_REC_LEN);
            }
        }
    }
}


   
回复

使用道具 举报

14

主题

57

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2018-11-15
在线时间
40 小时
 楼主| 发表于 2019-12-5 11:43:26 | 显示全部楼层
串口2的消息队列发送的数组错了,改了后直接往串口2发送数据系统卡死了。我是那里的逻辑错了吗?
回复

使用道具 举报

57

主题

1680

帖子

3

精华

资深版主

Rank: 8Rank: 8

积分
4306
金钱
4306
注册时间
2018-6-30
在线时间
808 小时
发表于 2019-12-5 14:00:16 | 显示全部楼层
这个你只能仿真找下问题,看看能不能进中断,不能进中断检查下配置
业精于勤荒于嬉;行成于思毁于随!
回复

使用道具 举报

14

主题

57

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2018-11-15
在线时间
40 小时
 楼主| 发表于 2019-12-5 14:17:28 | 显示全部楼层
1208 发表于 2019-12-5 14:00
这个你只能仿真找下问题,看看能不能进中断,不能进中断检查下配置

在中断接收函数接收过程中加了发送,测试的时候可以进去把接收的打印出来,好像是接收完成后进去发送消息队列出问题了。
void USART2_IRQHandler(void)
{
        u8 res;
    BaseType_t xHigherPriorityTaskWoken;
        if(USART_GetITStatus(USART2,USART_IT_RXNE)!=RESET)                //接收到数据
        {
                res=USART_ReceiveData(USART2);
        USART_SendData(USART2,res);
                if((USART2_RX_STA&(1<<15))==0)                        //没有接收到数据,进行接收
                {
                        if(USART2_RX_STA<USART2_MAX_RECV_LEN)        //还可以接受数据
                        {       
                                TIM_SetCounter(TIM7,0);             //计数器清空
                                if(USART2_RX_STA==0)                                //第一次接收到数据
                                {
                                        TIM_Cmd(TIM7,ENABLE);                        //开启定时器
                                }
                                USART2_RX_BUF[USART2_RX_STA++]=res;
               
                        }else
                        {
                                USART2_RX_STA |= 1<<15;                                //标记位置1,此次数据接收完成
                        }
                }
        if((USART2_RX_STA&(1<<15))&&(WIFI_QUEUE!=NULL))
        {
            USART_SendData(USART2,'x');
            xQueueSendFromISR(WIFI_QUEUE,USART2_RX_BUF,&xHigherPriorityTaskWoken);//向队列中发送数据
               
            USART2_RX_STA=0;       
            memset(USART2_RX_BUF,0,USART2_MAX_RECV_LEN);    //清除数据接收缓USART2_RX_BUF,用于下一次数据接收
       
            portYIELD_FROM_ISR(xHigherPriorityTaskWoken);   //如果需要的话进行一次任务切换
        }
        }
}
回复

使用道具 举报

57

主题

1680

帖子

3

精华

资深版主

Rank: 8Rank: 8

积分
4306
金钱
4306
注册时间
2018-6-30
在线时间
808 小时
发表于 2019-12-5 19:42:36 | 显示全部楼层
那你就重点检查接收完成后进去发送消息队列出问题,看看能打印数据不
业精于勤荒于嬉;行成于思毁于随!
回复

使用道具 举报

19

主题

334

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1108
金钱
1108
注册时间
2018-11-6
在线时间
240 小时
发表于 2019-12-9 10:25:23 | 显示全部楼层
我现在都用DMA方式接收串口数据,这样的好处是:可以减少CPU被打断的次数,提高系统效率。
回复

使用道具 举报

19

主题

334

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1108
金钱
1108
注册时间
2018-11-6
在线时间
240 小时
发表于 2019-12-9 10:31:10 | 显示全部楼层
stm32f407 串口USART2接收和发送全部使用DMA方式,同时使用串口空闲中断可以解决:DMA接收不定长报文

void USART2_DMA_Tx_Configuration(void)
{
        DMA_InitTypeDef  DMA_InitStructure;
        
        
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1 , ENABLE);                                        //DMA1时钟使能
        DMA_DeInit(DMA1_Stream6);
        while (DMA_GetCmdStatus(DMA1_Stream6) != DISABLE);                                                //等待DMA可配置
        DMA_InitStructure.DMA_Channel = DMA_Channel_4;                                                         //DMA通道配置
        DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART2->DR;                //DMA外设地址
        DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)USART2_DMA_TX_Buffer;        //发送缓存指针
        DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;                                        //DMA传输方向:内存--->外设
        DMA_InitStructure.DMA_BufferSize = USART2_DMA_TX_BUFFER_MAX_LENGTH;                //数据传输字节数量
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;                //外设非增量模式
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                                        //存储器增量模式
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;        //外设数据长度:8位
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;                        //存储器数据长度:8位        
        DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                                                        //使用普通模式
        DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;                                        //中等优先级 DMA_Priority_High
        DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
        DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
        DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;                                //存储器突发单次传输
        DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;                //外设突发单次传输
        DMA_Init(DMA1_Stream6, &DMA_InitStructure);                                                                //初始化DMA Stream
        DMA_Cmd(DMA1_Stream6, DISABLE);                                                                                 //开启DMA传输
}





void USART2_DMA_Rx_Configuration(void)
{
        DMA_InitTypeDef  DMA_InitStructure;

        
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1 , ENABLE);                                        //DMA1时钟使能
        DMA_DeInit(DMA1_Stream5);
        while (DMA_GetCmdStatus(DMA1_Stream5) != DISABLE);                                                //等待DMA可配置  
        DMA_InitStructure.DMA_Channel = DMA_Channel_4;                                                  //通道选择
        DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART2->DR;                //DMA外设地址
        DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)USART2_DMA_RX_Buffer;        //接收缓存指针
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory ;                                //DMA传输方向:外设到存储器模式:外设--->内存
        DMA_InitStructure.DMA_BufferSize = USART2_DMA_RX_BUFFER_MAX_LENGTH;                //缓冲大小
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;                //外设非增量模式
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                                        //存储器增量模式
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;        //外设数据长度:8位
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;                        //存储器数据长度:8位
        DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                                                        //使用普通模式
        DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;                                        //中等优先级 DMA_Priority_VeryHigh
        DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
        DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
        DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;                                //存储器突发单次传输
        DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;                //外设突发单次传输
        DMA_Init(DMA1_Stream5 , &DMA_InitStructure);                                                        //初始化DMA_Stream        
        DMA_Cmd(DMA1_Stream5, ENABLE);                                                                                  //开启DMA传输
}



void USART2_DMA_Begin_Send(uint8_t *send_buffer , uint16_t nSendCount)
{               
        if (nSendCount < USART2_DMA_TX_BUFFER_MAX_LENGTH)
        {
                memcpy(USART2_DMA_TX_Buffer , send_buffer , nSendCount);
                DMA_Cmd(DMA1_Stream6 , DISABLE);                    //关闭DMA传输
                while (DMA_GetCmdStatus(DMA1_Stream6) != DISABLE);        //确保DMA可以被设置
                DMA_SetCurrDataCounter(DMA1_Stream6 , nSendCount);  //数据传输量
                DMA_Cmd(DMA1_Stream6 , ENABLE);                               //开启DMA传输
        }
}


void USART2_Configuration(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;
               

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 , ENABLE);         //for USART2, USART3, UART4 or UART5.        
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
               
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);            

        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
        
        USART_InitStructure.USART_BaudRate = 115200;
        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(USART2, &USART_InitStructure);
        USART_Cmd(USART2, ENABLE);

        USART_ClearFlag(USART2, USART_FLAG_TC); //清除发送完成标志        
        while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);        //等待空闲帧发送完成后再清零发送完成标志(警告:如果不使能USART_Mode_Tx,会导致单片机在这里死机)
        USART_ClearFlag(USART2, USART_FLAG_TC);        //清除发送完成标志

    USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);                                //禁止USART1接收不为空中断
        USART_ITConfig(USART2, USART_IT_TXE, DISABLE);                                //禁止USART1发送空中断
        USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);                                //开启USART1空闲中断
        USART_ITConfig(USART2, USART_IT_TC, ENABLE);                                //开启USART1传输完成中断
        
        USART_DMACmd(USART2 ,   USART_DMAReq_Tx,ENABLE);                          //使能串口的DMA发送
        USART_DMACmd(USART2 ,   USART_DMAReq_Rx,ENABLE);                          //使能串口的DMA接收

}


void USART2_Begin_Send(void)
{

        GPIO_USART2_RS485_SEND_enable();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();        
        USART2_DMA_Begin_Send(MB_USART2.send_buffer , MB_USART2.sendCount);
}



void USART2_IRQHandler(void)
{
        int16_t ch;

        
        if (USART_GetITStatus(USART2,USART_IT_IDLE) != RESET)
        {               
                USART_ClearITPendingBit(USART2 , USART_IT_IDLE);        //必须先清除总线空闲中断标识,然后读一下数据寄存器,DMA接收才会正确(先读SR,然后读DR才能清除空闲中断标识)注意:这句必须要,否则不能够清除中断标志位。
                ch =  USART_ReceiveData(USART2);                        //必须先清除总线空闲中断标识,然后读一下数据寄存器,DMA接收才会正确(先读SR,然后读DR才能清除空闲中断标识)注意:这句必须要,否则不能够清除中断标志位。
               

               
                DMA_Cmd(DMA1_Stream5 , DISABLE);                         //关闭DMA,防止处理其间有数据
                DMA_ClearFlag(DMA1_Stream5 , DMA_FLAG_TCIF5 | DMA_FLAG_FEIF5 | DMA_FLAG_DMEIF5 | DMA_FLAG_TEIF5 | DMA_FLAG_HTIF5);//清零标志位
                ch = USART2_DMA_RX_BUFFER_MAX_LENGTH - DMA_GetCurrDataCounter(DMA1_Stream5);
                if (ch > 0)
                {

                        {
                                MB_USART2.Outtime_mark = TRUE;   //置标识,表示DMA接收通信数据完毕
                                MB_USART2.receCount = ch;        //DMA接收通信数据长度
                                memcpy(MB_USART2.mscomm_buffer , USART2_DMA_RX_Buffer , MB_USART2.receCount);//从DMA接收缓冲区拷贝到解析报文缓冲区
                        }
                }
                DMA_SetCurrDataCounter(DMA1_Stream5 , USART2_DMA_RX_BUFFER_MAX_LENGTH);
                DMA_Cmd(DMA1_Stream5, ENABLE);
        }
        
        else if (USART_GetITStatus(USART2,USART_IT_TC)!= RESET)
        {
                USART_ClearITPendingBit(USART2, USART_IT_TC);
                                
                //DMA_Cmd(DMA1_Stream6 , DISABLE);//这条语句必须屏蔽,否则485通信时会出现异常情况,2018.10.18
                DMA_ClearFlag(DMA1_Stream6 , DMA_FLAG_TCIF6 | DMA_FLAG_FEIF6 | DMA_FLAG_DMEIF6 | DMA_FLAG_TEIF6 | DMA_FLAG_HTIF6);
                DMA_SetCurrDataCounter(DMA1_Stream6 , 0);                        //清除数据长度
               
                GPIO_USART2_RS485_RECIVE_enable();
        }
        
}
回复

使用道具 举报

19

主题

334

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1108
金钱
1108
注册时间
2018-11-6
在线时间
240 小时
发表于 2019-12-9 10:33:22 | 显示全部楼层
#define USART2_DMA_RX_BUFFER_MAX_LENGTH                (255)
#define USART2_DMA_TX_BUFFER_MAX_LENGTH                (255)

uint8_t USART2_DMA_RX_Buffer[USART2_DMA_RX_BUFFER_MAX_LENGTH];
uint8_t USART2_DMA_TX_Buffer[USART2_DMA_TX_BUFFER_MAX_LENGTH];
回复

使用道具 举报

19

主题

334

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1108
金钱
1108
注册时间
2018-11-6
在线时间
240 小时
发表于 2019-12-9 10:43:24 | 显示全部楼层
假如USART2需要接收1000个字节,用串口接收中断,需要产生1000次中断,用DMA中断,只产生一次中断。
假如USART2需要发送3000个字节,用串口发送中断,需要产生3000次中断,用DMA中断,只产生一次中断。
回复

使用道具 举报

14

主题

57

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2018-11-15
在线时间
40 小时
 楼主| 发表于 2019-12-9 16:47:47 | 显示全部楼层
霸王猫 发表于 2019-12-9 10:43
假如USART2需要接收1000个字节,用串口接收中断,需要产生1000次中断,用DMA中断,只产生一次中断。
假如U ...

牛批,,我晚上看看你的代码,谢谢指导
回复

使用道具 举报

3

主题

1155

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7462
金钱
7462
注册时间
2015-1-15
在线时间
1367 小时
发表于 2019-12-9 16:52:56 来自手机 | 显示全部楼层
一言不合就推DMA
回复

使用道具 举报

14

主题

57

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2018-11-15
在线时间
40 小时
 楼主| 发表于 2019-12-9 21:25:56 | 显示全部楼层
霸王猫 发表于 2019-12-5 11:06
你用定时器TIM7用于识别一帧报文接收完毕,建议你将代码改写成如下形式:

void USART2_IRQHandler(void) ...

这个不能解决,应该给8楼设为答案的
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-22 22:19

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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