NUCLEO-L4R5ZI的供电分析
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通道实现
- 串口初始化`
#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;
}
- 中断服务和标志函数代码
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;
}
}
}
- LED初始化
为了检测代码的效果,接收到数据后让led灯进行翻转显示
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.主函数代码
int main()
{
HAL_Init();
SystemClock_Config();
Delay_Init();
LED_Init();
LPUART1_Init(115200);
printf("xiaonai\n");
while (1)
{
LPUART1_DMA_Get();
}
}
整体代码思路就是while(1)循环一直开启DMA接收,当串口触发空闲中断后,触发标志位,记录DMA通道未发送数据长度并停止DMA接收,DMA通道里面靠前的数据也就接收到了串口接收到的数据了,并且把长度也记录下来,串口助手一定要加入0x0d,0x0a.