NUCLEO-L4R5ZI供电分析与LPUART和DMA通道的实现


NUCLEO-L4R5ZI的供电分析

1
STM32L4+执行速度高达120Mhz,FLASH达到了2M字节,SRAM达到640字节,还有更丰富的图像和连接性能,并且拥有低功耗能力。

从下面芯片图来看,电源主要是从STLINK的USB供电即5V。经过的是一个可控的供电芯片ST890,然后供电给JP6跳线。
在这里插入图片描述
这块小编是软件出身,对于PCB的了解也不是很深。从下图可以看出,E5v从外面直接输入的5V,而VIN是是从VIN经过LDO芯片LD1117S50转过来。然后所有的5v在经过LD39050变成3.3V供整块板子供电。默认采用的是STLCK供电,这个可以实现LPUART低功耗串口的使用,其他两种小编也没试过。
在这里插入图片描述

NUCLEO-L4R5ZI的LPUART和DMA通道实现

  1. 串口初始化`
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#define BUFFERSIZE 255             
uint8_t rx_buff[BUFFERSIZE];
uint8_t recv_end_flag=0,rx_len=0;

GPIO_InitTypeDef GPIO_InitStruct;
UART_HandleTypeDef LPUART1_Handler;
DMA_HandleTypeDef hdma_lpuart1_rx;

void LPUART1_Init(int baud)
{<!-- -->
    __HAL_RCC_GPIOG_CLK_ENABLE();
    __HAL_RCC_LPUART1_CLK_ENABLE();
    __HAL_RCC_DMAMUX1_CLK_ENABLE();
  __HAL_RCC_DMA2_CLK_ENABLE();
    HAL_PWREx_EnableVddIO2();
   
  GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF8_LPUART1;
  HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

  LPUART1_Handler.Instance = LPUART1;
  LPUART1_Handler.Init.BaudRate =baud;
  LPUART1_Handler.Init.WordLength = UART_WORDLENGTH_8B;
  LPUART1_Handler.Init.StopBits = UART_STOPBITS_1;
  LPUART1_Handler.Init.Parity = UART_PARITY_NONE;
  LPUART1_Handler.Init.Mode = UART_MODE_TX_RX;
  LPUART1_Handler.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  LPUART1_Handler.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  LPUART1_Handler.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  LPUART1_Handler.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  LPUART1_Handler.FifoMode = UART_FIFOMODE_DISABLE;
  HAL_UART_Init(&LPUART1_Handler);
    __HAL_UART_ENABLE_IT(&LPUART1_Handler,UART_IT_IDLE);
    HAL_NVIC_SetPriority(LPUART1_IRQn,1,0);
  HAL_NVIC_EnableIRQ(LPUART1_IRQn);
  HAL_UARTEx_SetTxFifoThreshold(&LPUART1_Handler,UART_TXFIFO_THRESHOLD_1_8);
    HAL_UARTEx_SetRxFifoThreshold(&LPUART1_Handler,UART_RXFIFO_THRESHOLD_1_8);
   
    hdma_lpuart1_rx.Instance = DMA2_Channel7;
  hdma_lpuart1_rx.Init.Request = DMA_REQUEST_LPUART1_RX;
  hdma_lpuart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
  hdma_lpuart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
  hdma_lpuart1_rx.Init.MemInc = DMA_MINC_ENABLE;
  hdma_lpuart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  hdma_lpuart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
  hdma_lpuart1_rx.Init.Mode =DMA_NORMAL;
  hdma_lpuart1_rx.Init.Priority = DMA_PRIORITY_LOW;
  HAL_DMA_Init(&hdma_lpuart1_rx);

  __HAL_LINKDMA(&LPUART1_Handler,hdmarx,hdma_lpuart1_rx);
   
}

int fputc(int ch,FILE *f)
{<!-- -->
    while(!(LPUART1->ISR&(1<<7)));
    LPUART1->TDR=ch;
  return ch;

}
  1. 中断服务和标志函数代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
void LPUART1_DMA_Get()
{<!-- -->
    int i;
    if(recv_end_flag==1)
    {<!-- -->
        printf("接收到的数据【%s】 数据长度=%d",rx_buff,rx_len);
        if(rx_buff[0]==0x66)
            if(rx_buff[1]==0x01)
                HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_7);
            else if(rx_buff[1]==0x02)
                HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_14);
        for(i=0;i<rx_len;i++)
            rx_buff[i]=0;
        rx_len=0;
        recv_end_flag=0;
    }
    HAL_UART_Receive_DMA(&LPUART1_Handler,(uint8_t*)rx_buff,BUFFERSIZE);
}

void LPUART1_IRQHandler()
{<!-- -->
    uint32_t temp;
    if(LPUART1==LPUART1_Handler.Instance)
    {<!-- -->
        if(__HAL_UART_GET_FLAG(&LPUART1_Handler,UART_FLAG_IDLE))
        {<!-- -->
            __HAL_UART_CLEAR_IDLEFLAG(&LPUART1_Handler);
            HAL_UART_DMAStop(&LPUART1_Handler);
          temp=hdma_lpuart1_rx.Instance->CNDTR;
            rx_len=BUFFERSIZE-temp;
            recv_end_flag=1;
        }
    }
}
  1. LED初始化
    为了检测代码的效果,接收到数据后让led灯进行翻转显示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void LED_Init()
{<!-- -->
    GPIO_InitTypeDef GPIO_InitStruct;
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
   
  GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_14;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);  
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14, GPIO_PIN_RESET);
   
    GPIO_InitStruct.Pin = GPIO_PIN_7;
    HAL_GPIO_WritePin(GPIOC,GPIO_PIN_7, GPIO_PIN_SET);

}

4.主函数代码

1
2
3
4
5
6
7
8
9
10
11
12
13
int main()
{<!-- -->
  HAL_Init();
  SystemClock_Config();
  Delay_Init();
  LED_Init();
  LPUART1_Init(115200);
    printf("xiaonai\n");
  while (1)
  {<!-- -->
        LPUART1_DMA_Get();
  }
}
1
整体代码思路就是while(1)循环一直开启DMA接收,当串口触发空闲中断后,触发标志位,记录DMA通道未发送数据长度并停止DMA接收,DMA通道里面靠前的数据也就接收到了串口接收到的数据了,并且把长度也记录下来,串口助手一定要加入0x0d,0x0a.