久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4974|回復(fù): 4
收起左側(cè)

STM32 串口DMA收發(fā)

[復(fù)制鏈接]
ID:351938 發(fā)表于 2018-6-14 16:39 | 顯示全部樓層 |閱讀模式
本帖最后由 mmik 于 2018-6-14 16:51 編輯

最近在做一個STM32單片機(jī)的項目,用到串口通信功能。但是目前網(wǎng)上的帖子比較零碎現(xiàn)在整理一份完整的代碼發(fā)到論壇中。希望能幫到用到的朋友。

關(guān)鍵步驟:

1、初始化串口。
2、初始化DMA通道。
3、配置串口中斷,當(dāng)發(fā)生IDLE中斷時處理一次DMA數(shù)據(jù)。
4、配置DMA中斷,當(dāng)發(fā)生DMA接收完成時處理一次DMA數(shù)據(jù)。

上代碼:
初始化串口:
  // 通用端口初始化參數(shù)
  GPIO_InitTypeDef GPIO_InitStructure;
  // 串口初始化參數(shù)
  USART_InitTypeDef USART_InitStructure;
  // 中斷向量初始化參數(shù)
  NVIC_InitTypeDef NVIC_InitStructure;

  // 啟用GPIO總線時鐘
  // STM32F1系列GPIO時鐘都在APB2總線
  RCC_APB2PeriphClockCmd(uartDef->portAPBxParam, ENABLE);

  // 啟用串口總線時鐘
  // uart1 在APB2總線,uart2~5 在APB1總線
  if (APB1 == uartDef->uartAPBx)
  {
    RCC_APB1PeriphClockCmd(uartDef->uartAPBxParam, ENABLE);
  }

  else if (APB2 == uartDef->uartAPBx)
  {
    RCC_APB2PeriphClockCmd(uartDef->uartAPBxParam, ENABLE);
  }

  // 設(shè)置串口TX發(fā)送口
  GPIO_InitStructure.GPIO_Pin   = uartDef->txPin;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;                                //推挽輸出
  GPIO_Init(uartDef->txGPIO, &GPIO_InitStructure);                                //初始化GPIOA.9

  // 設(shè)置串口RX接收口
  GPIO_InitStructure.GPIO_Pin   = uartDef->rxPin;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN_FLOATING;                          //浮空輸入
  GPIO_Init(uartDef->rxGPIO, &GPIO_InitStructure);  

  //USART 初始化設(shè)置
  USART_InitStructure.USART_BaudRate            = uartDef->uartDcb.baudrate;      //串口波特率,一般設(shè)置為9600;
  USART_InitStructure.USART_WordLength          = USART_WordLength_8b;            //字長為8位數(shù)據(jù)格式
  USART_InitStructure.USART_StopBits            = USART_StopBits_1;               //一個停止位
  USART_InitStructure.USART_Parity              = USART_Parity_No;                //無奇偶校驗位
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //無硬件數(shù)據(jù)流控制
  USART_InitStructure.USART_Mode                = USART_Mode_Rx | USART_Mode_Tx;  //收發(fā)模式

  USART_Init(uartDef->port, &USART_InitStructure);                                //初始化串口

  USART_ITConfig(uartDef->port, USART_IT_RXNE, ENABLE);                           //開啟接收中斷
  USART_ITConfig(uartDef->port, USART_IT_IDLE, ENABLE);                           //開啟空閑中斷

  //USART NVIC 配置
  NVIC_InitStructure.NVIC_IRQChannel                   = uartDef->NVIC_IRQ;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;                       //搶占優(yōu)先級3
  NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 3;                       //子優(yōu)先級3
  NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;                  //IRQ通道使能
  NVIC_Init(&NVIC_InitStructure);                                                 //根據(jù)指定的參數(shù)初始化VIC寄存器

  USART_Cmd(uartDef->port, ENABLE);                                               //使能串口

  // 配置DMA收發(fā)
DMA_Configuration(port);



//// 配置DMA
  DMA_InitTypeDef DMA_InitStructure;

  //使能DMA傳輸
  //
  if((0x0400 & (u32)DMA_CHx))
  {
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
  }
  else
  {
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  }
  DMA_Cmd(DMA_CHx, DISABLE);

  DMA_DeInit(DMA_CHx);                                                            //將DMA的通道寄存器重設(shè)為缺省值

  DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;                                //DMA外設(shè)ADC基地址
  DMA_InitStructure.DMA_MemoryBaseAddr     = cmar;                                //DMA內(nèi)存基地址
  DMA_InitStructure.DMA_DIR                = dmaDir;                              //數(shù)據(jù)傳輸方向,從內(nèi)存讀取發(fā)送到外設(shè)
  DMA_InitStructure.DMA_BufferSize         = bufferSize;                          //DMA通道的DMA緩存的大小
  DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;           //外設(shè)地址寄存器不變
  DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable;                //內(nèi)存地址寄存器遞增
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;         //數(shù)據(jù)寬度為8位
  DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte;             //數(shù)據(jù)寬度為8位
  DMA_InitStructure.DMA_Mode               = DMA_Mode_Normal;                     //工作在正常緩存模式
  DMA_InitStructure.DMA_Priority           = DMA_Priority_Medium;                 //DMA通道 x擁有高優(yōu)先級
  DMA_InitStructure.DMA_M2M                = DMA_M2M_Disable;                     //DMA通道x沒有設(shè)置為內(nèi)存到內(nèi)存?zhèn)鬏?br />
  DMA_Init(DMA_CHx,&DMA_InitStructure);                                          //根據(jù)DMA_InitStruct中指定的參數(shù)初始化DMA的通道USART1_Tx_DMA_Channel所標(biāo)識的寄存器  
  DMA_ITConfig(DMA_CHx, DMA_IT_TC, ENABLE);
  DMA_Cmd(DMA_CHx, ENABLE);



  // 根據(jù)端口選擇DMA監(jiān)聽
  switch(port)
  {
    case UART_PORT1:
      NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;
    break;
    case UART_PORT2:
      NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel6_IRQn;
    break;
    case UART_PORT3:
      NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel3_IRQn;
    break;
    case UART_PORT4:
      NVIC_InitStructure.NVIC_IRQChannel = DMA2_Channel3_IRQn;
    break;
    default:
      break;
  }

  // 串口5 不支持DMA
  switch(port)
  {
    case UART1:
    case UART2:
    case UART3:
    case UART4:
      // 開啟DMA 發(fā)送
      USART_DMACmd(uartDef->port,USART_DMAReq_Tx,ENABLE);
      USART_DMA_Config(uartDef->txChannel,
                       0,DMA_DIR_PeripheralDST,
                       (u32)&uartDef->port->DR,(u32)(uartDef->txBuffer));
      // 開啟DMA 接收
      USART_DMACmd(uartDef->port,USART_DMAReq_Rx,ENABLE);
      USART_DMA_Config(uartDef->rxChannel,
                       uartDef->rxMaxLen,DMA_DIR_PeripheralSRC,
                       (u32)&uartDef->port->DR,(u32)(uartDef->rxBuffer));

      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         
      NVIC_Init(&NVIC_InitStructure);
      break;
    default:
      break;
  }


DMA 中斷處理(DMA1_IT_TC6 是指通道6的中斷標(biāo)志)
  if( DMA_GetITStatus(DMA1_IT_TC6)==SET)
  {
    DMA_ClearITPendingBit(DMA1_IT_GL6);

    DMA_Cmd(uartDef->rxChannel,DISABLE);
    uartDef->rxLen = uartDef->rxMaxLen - DMA_GetCurrDataCounter(uartDef->rxChannel);
    if (NULL != uartDef->callback)
    {
      uartDef->callback(UART_PORT2,EVENT_UART_READY_TO_READ,uartDef->customizePara);
    }

    DMA_SetCurrDataCounter(uartDef->rxChannel,uartDef->rxMaxLen);
    DMA_Cmd(uartDef->rxChannel,ENABLE);
  }


USART 中斷處理
if(USART_GetITStatus(uartDef->port, USART_IT_IDLE) != RESET)
  {
    res = uartDef->port->SR;
    res = uartDef->port->DR;

    DMA_Cmd(uartDef->rxChannel,DISABLE);
    uartDef->rxLen = uartDef->rxMaxLen - DMA_GetCurrDataCounter(uartDef->rxChannel);

    if (NULL != uartDef->callback)
    {
      uartDef->callback(port,EVENT_UART_READY_TO_READ,uartDef->customizePara);
    }

    DMA_SetCurrDataCounter(uartDef->rxChannel,uartDef->rxMaxLen);
    DMA_Cmd(uartDef->rxChannel,ENABLE);
  }



評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復(fù)

使用道具 舉報

ID:140371 發(fā)表于 2018-6-15 04:57 | 顯示全部樓層
下來學(xué)習(xí),謝謝分想
回復(fù)

使用道具 舉報

ID:163795 發(fā)表于 2018-12-13 10:25 | 顯示全部樓層
厲害厲害,贊一個
回復(fù)

使用道具 舉報

ID:383374 發(fā)表于 2019-1-23 01:40 來自手機(jī) | 顯示全部樓層
下載文件怎么沒有
回復(fù)

使用道具 舉報

ID:397922 發(fā)表于 2019-10-17 10:43 | 顯示全部樓層
謝謝分享
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 国产成人99久久亚洲综合精品 | 精品国产乱码久久久久久影片 | 人人人人干 | 亚洲精品欧美精品 | 99精品国自产在线观看 | 久久九九网站 | 九九综合 | a级片网站 | 亚洲欧美中文字幕在线观看 | 日韩国产黄色片 | 中文字幕成人在线 | 99re视频精品 | www国产亚洲精品久久网站 | 成人妇女免费播放久久久 | 嫩草视频在线免费观看 | 久久亚洲二区 | 欧美高清一区 | 人人色视频 | 欧美激情久久久久久 | 日本久久综合网 | 97免费视频在线观看 | 婷婷色在线播放 | 国产精品无码久久久久 | 午夜精品网站 | 黑人巨大精品欧美一区二区一视频 | 亚洲视频一| 久久久精品一区 | 超碰成人av | 欧美不卡视频 | 特级黄一级播放 | 男人天堂999 | 免费国产一区二区 | h视频免费在线观看 | 欧美在线一区二区三区 | a毛片| 久久精品久久久久久 | 国产美女自拍视频 | 亚洲欧美日韩在线 | 欧美日韩电影免费观看 | 免费的av| 亚洲人成一区二区三区性色 |