OpenEdv-开源电子网

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

STM32F412VGT6串口3用不了

[复制链接]

6

主题

27

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
203
金钱
203
注册时间
2022-10-24
在线时间
39 小时
发表于 2023-3-29 09:06:20 | 显示全部楼层 |阅读模式
5金钱
本帖最后由 willie1040 于 2023-3-29 09:08 编辑

之前做的项目用的STM32F412RET,现在升级使用STM32F412VGT6。之前RET用的串口1 、2、6 都没有问题。VGT6新增了串口3,初始化什么的,都是跟之前其他串口差不多。现在是一初始化串口3,整个程序编译没有错,烧录就运行不了了。把串口3初始化函数注释掉,其他功能就能正常运行,求大神解救一下~~~
串口3的相关函数如下:
void Init_USART3(uint32_t baud)
{
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
DMA_InitTypeDef DMA_InitStructure;        


//1.串口时钟和和GPIO时钟使能。
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE); //使能GPIOD时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);//使能USART3时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);        
//2.设置引脚复用器映射
GPIO_PinAFConfig(GPIOD,GPIO_PinSource8,GPIO_AF_USART3); //GPIOB10复用为USART6
GPIO_PinAFConfig(GPIOD,GPIO_PinSource9,GPIO_AF_USART3); //GPIOB11复用为USART6
//3.GPIO端口模式设置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; //
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOD,&GPIO_InitStructure); //初始化GPIOB10,和GPIOB11
//4.串口参数初始化:设置波特率,字长,奇偶校验等参数
USART_InitStructure.USART_BaudRate = baud;//波特率一般设置为9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
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(USART3, &USART_InitStructure); //初始化串口2参数
//5.初始化NVIC
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn ;//串口3中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//抢占优先级0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器

//6.开启中断
USART_ITConfig(USART3, USART_IT_TC, ENABLE);//开启发送中断  
//USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);//开启空闲中断
//7.使能串口
USART_Cmd(USART3, ENABLE);                    //使能串口

        /* DMA2 Channel5 (串口6 TX) Config */
        DMA_Cmd(DMA1_Stream3, DISABLE);
        DMA_DeInit(DMA1_Stream3);
        while (DMA_GetCmdStatus(DMA1_Stream3) != DISABLE){}//等待DMA可设置
         
  DMA_InitStructure.DMA_Channel             = DMA_Channel_4;         //恢复缺省值
  DMA_InitStructure.DMA_PeripheralBaseAddr  = (uint32_t)(&(USART3->DR));   //源    设置串口发送数据寄存器
  DMA_InitStructure.DMA_Memory0BaseAddr     = (uint32_t)USART3_SEND_DATA;  //目的  设置发送缓冲区首地址
  DMA_InitStructure.DMA_DIR                 = DMA_DIR_MemoryToPeripheral;  //设置外设位目标,内存缓冲区-->外部寄存器
  DMA_InitStructure.DMA_BufferSize          = UART3_TX_LEN;                //需要发送的字节数,这里其实可以设置为0,因为在实际要发送的时候,会重新设置次值
  DMA_InitStructure.DMA_PeripheralInc       = DMA_PeripheralInc_Disable;   //外设地址不做增加调整,调整不调整是DMA自动实现的
  DMA_InitStructure.DMA_MemoryInc           = DMA_MemoryInc_Enable;        //内存缓冲地址增加调整
  DMA_InitStructure.DMA_PeripheralDataSize  = DMA_MemoryDataSize_Byte;                  //外设数据宽度8位,1个字节
  DMA_InitStructure.DMA_MemoryDataSize      = DMA_MemoryDataSize_Byte;     //内存数据宽度8位,1个字节
  DMA_InitStructure.DMA_Mode                = DMA_Mode_Normal;                               //DMA工作模式        单次传输模式
  DMA_InitStructure.DMA_Priority            = DMA_Priority_High;          //优先级设置
  DMA_InitStructure.DMA_FIFOMode            = DMA_FIFOMode_Disable;       /* FIFO模式 */
  DMA_InitStructure.DMA_FIFOThreshold       = DMA_FIFOThreshold_HalfFull; /* FIFO大小 */
        DMA_InitStructure.DMA_MemoryBurst         = DMA_MemoryBurst_Single;     /* 储存器突发传输*/
        DMA_InitStructure.DMA_PeripheralBurst     = DMA_PeripheralBurst_Single; /*外设突发传输*/
  DMA_Init(DMA1_Stream3, &DMA_InitStructure);                             //写入配置

  /*Enable DMA Channel5 Interrupt DMA_TX1 */
  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);        
        //DMA中断设置
  DMA_ITConfig(DMA1_Stream3, DMA_IT_TC, ENABLE);                          //启动发送DMA通道中断
  /* Enable USART6 DMA TX request */
  USART_DMACmd(USART3, USART_DMAReq_Tx, ENABLE);                          //使能串口DMA发送
        
        /* DMA2 Channel5 (串口6 RX) Config */
        DMA_Cmd(DMA1_Stream1, DISABLE);                                                            //关闭DMA接收
  DMA_DeInit(DMA1_Stream1);
        while (DMA_GetCmdStatus(DMA1_Stream1) != DISABLE);                        //等待DMA可设置
        
        DMA_InitStructure.DMA_Channel              = DMA_Channel_4;                  //通道选择
        DMA_InitStructure.DMA_PeripheralBaseAddr   = (u32)&USART3->DR;              //DMA外设地址
        DMA_InitStructure.DMA_Memory0BaseAddr      = (u32)USART3_RECEIVE_DATA;      //DMA 储存0地址
        DMA_InitStructure.DMA_DIR                  = DMA_DIR_PeripheralToMemory ;   //储存器到外设
        DMA_InitStructure.DMA_BufferSize           = UART3_RX_LEN;                  //数据传输量
        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_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_Stream1, &DMA_InitStructure);//

  /*Enable DMA Channel5 Interrupt DMA_RX1*/
  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream1_IRQn;  
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;  
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
        NVIC_Init(&NVIC_InitStructure);  
        
        
  /* Enable USART6 DMA RX request */
  USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE);                           //使能串口DMA接收
  DMA_Cmd(DMA1_Stream1, ENABLE);                                                       //使能DMA14接收通道   

        }        


///////////////////////////////////////////////////////////////////////////

//DMA 发送完成总断
void DMA1_Stream3_IRQHandler(void)
{
        if(DMA_GetFlagStatus(DMA1_Stream3,DMA_FLAG_TCIF3)!=RESET)
        {
                DMA_ClearFlag(DMA1_Stream3,DMA_FLAG_TCIF3);
        }
}
//DMA接收总断服务函数,未开启
void DMA1_Stream1_IRQHandler(void)
{
        if(DMA_GetFlagStatus(DMA1_Stream1,DMA_FLAG_TCIF1)!=RESET)
        {
                DMA_ClearFlag(DMA1_Stream1,DMA_FLAG_TCIF1);
        }
                DMA_Cmd(DMA1_Stream1, DISABLE);
                DMA_ClearFlag(DMA1_Stream1,DMA_FLAG_TCIF1 | DMA_FLAG_FEIF1 | DMA_FLAG_DMEIF1 | DMA_FLAG_TEIF1 | DMA_FLAG_HTIF1);
                DMA_SetCurrDataCounter(DMA1_Stream1, UART3_RX_LEN);
                DMA_Cmd(DMA1_Stream1, ENABLE);   
        
}

//USART3中断服务函数
void USART3_IRQHandler(void)//USART3_IRQHandler
{
        u16 data;
        if(USART_GetITStatus(USART3, USART_IT_TC) != RESET )        
                {
                  USART_ClearFlag(USART3, USART_FLAG_TC);
//                        RS485_R;
          }
        if(USART_GetITStatus(USART3,USART_IT_IDLE) != RESET)
        {
                DMA_Cmd(DMA1_Stream1, DISABLE);
                Uart3_DMA_Rx_Data();
        }
               
                data = USART3->SR;
                data = USART3->DR;
                data=data;
               
               
                DMA_ClearFlag(DMA1_Stream1,DMA_FLAG_TCIF1 | DMA_FLAG_FEIF1 | DMA_FLAG_DMEIF1 | DMA_FLAG_TEIF1 | DMA_FLAG_HTIF1);
                DMA_SetCurrDataCounter(DMA1_Stream1, UART3_RX_LEN);
                DMA_Cmd(DMA1_Stream1, ENABLE);
                USART_ClearITPendingBit(USART3, USART_IT_IDLE);        
        
}        

void Uart3_DMA_Rx_Data(void)
{
    //u16 CRC_Data;
          u16 DATA_LEN=0;

          u16 i;


                        DATA_LEN =UART3_RX_LEN - DMA_GetCurrDataCounter(DMA1_Stream1);

                        //收到指令数据
                        if((USART3_RECEIVE_DATA[0]==0xFB)&&(USART3_RECEIVE_DATA[1]==0xFB)&&(USART3_RECEIVE_DATA[2]==0xFB)&&(USART3_RECEIVE_DATA[5]==0x01))
                        {
                                for(i=0;i<DATA_LEN;i++)
                                {
                                        Cmd_Data.cmd_data_rec=USART3_RECEIVE_DATA;
                        
                                }
                                //memset(USART6_RECEIVE_DATA,0,DATA_LEN);

                                /*if((USART6_RECEIVE_DATA[4]==0x01)&&(USART6_RECEIVE_DATA[5]==0x03))//当前为轮灌页面
                                        Cmd_Data.cmd_data_rec[4]=CMD_READ_PROGRAM;*/
        
                                Cmd_Data.Uart6_get_cmd=1;
                                
                        }
                        //轮灌程序页面
                        /*if((USART6_RECEIVE_DATA[0]==0xEE)&&(USART6_RECEIVE_DATA[1]==0xB1)&&(USART6_RECEIVE_DATA[2]==0x01)&&(USART6_RECEIVE_DATA[3]==0x00))
                        {
                                if(USART6_RECEIVE_DATA[4]==0x03)//轮灌页面
                                        Cmd_Data.cmd_type=CMD_READ_PROGRAM;
                                if(USART6_RECEIVE_DATA[4]==0x00) //首页
                                        Cmd_Data.cmd_type=CMD_UPDATE_VAVLE_TIME1;
                                if(USART6_RECEIVE_DATA[4]==0x01)//第二页
                                        Cmd_Data.cmd_type=CMD_UPDATE_VAVLE_TIME2;
                                Cmd_Data.Uart6_get_cmd=1;
                        }*/
                                                   
                        
}

void Uart3_DMA_Tx_Data(u32 len,u8* raed)
{   
        u32 i;
         for(i=0;i<len;i++)USART3_SEND_DATA=raed;
//        RS485_T;
        DMA_Cmd(DMA1_Stream3, DISABLE);
        DMA1_Stream3->NDTR=len; //DMA1,传输数据
        DMA_Cmd(DMA1_Stream3, ENABLE);
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

27

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
203
金钱
203
注册时间
2022-10-24
在线时间
39 小时
 楼主| 发表于 2023-3-29 10:14:10 | 显示全部楼层
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-24 17:31

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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