stm32f103 串口+DMA 发送不定长数据 标准库函数代码示例
时间: 2023-08-15 11:04:24 浏览: 154
STM32F103C8T6串口1空闲中断+DMA接收不定长数据源代码.zip
3星 · 编辑精心推荐
以下是一个基于STM32F103的串口+DMA发送不定长数据的示例代码,使用了标准库函数。
首先,需要初始化串口和DMA:
```c
#include "stm32f1xx.h"
#include <string.h>
#define BUFFER_SIZE 256
uint8_t buffer[BUFFER_SIZE];
uint16_t buffer_length = 0;
void init_USART1(uint32_t baudrate)
{
RCC->APB2ENR |= RCC_APB2ENR_USART1EN | RCC_APB2ENR_IOPAEN;
GPIOA->CRH |= GPIO_CRH_MODE9_0 | GPIO_CRH_MODE9_1 | GPIO_CRH_CNF9_1;
GPIOA->CRH &= ~(GPIO_CRH_CNF9_0);
USART1->BRR = SystemCoreClock / baudrate;
USART1->CR1 |= USART_CR1_TE;
USART1->CR3 |= USART_CR3_DMAT;
USART1->CR1 |= USART_CR1_UE;
}
void init_DMA1(uint8_t* buffer, uint16_t length)
{
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
DMA1_Channel4->CPAR = (uint32_t) & (USART1->DR);
DMA1_Channel4->CMAR = (uint32_t) buffer;
DMA1_Channel4->CNDTR = length;
DMA1_Channel4->CCR |= DMA_CCR_DIR | DMA_CCR_MINC | DMA_CCR_TCIE | DMA_CCR_EN;
}
```
然后,可以编写一个函数来发送数据。该函数将数据添加到缓冲区中,并启动DMA传输:
```c
void send_data(uint8_t* data, uint16_t length)
{
if (length > BUFFER_SIZE) {
length = BUFFER_SIZE;
}
if (buffer_length + length > BUFFER_SIZE) {
length = BUFFER_SIZE - buffer_length;
}
memcpy(buffer + buffer_length, data, length);
buffer_length += length;
if (DMA1_Channel4->CNDTR == 0) {
DMA1_Channel4->CCR &= ~DMA_CCR_EN;
DMA1_Channel4->CNDTR = buffer_length;
DMA1_Channel4->CCR |= DMA_CCR_EN;
buffer_length = 0;
}
}
```
在主函数中,可以使用此函数来发送数据:
```c
int main()
{
init_USART1(9600);
init_DMA1(buffer, 0);
uint8_t data[] = "Hello World!";
send_data(data, strlen(data));
while (1);
}
```
当缓冲区满时,DMA传输将启动。每次DMA传输完成时,都会触发中断,并重新启动DMA传输。
阅读全文