stm32f103 uart+DMA发送接收

1 篇文章 0 订阅

stm32f103 uart+DMA发送接收 2015-12-09 工科电子... 阅 3097 转 53 转藏到我的图书馆 //stm32f1 串口通信  //  串口通信模块会为串口划分256字节的uart缓存区,缓存中断接收的数据, // 处理串口接收数据的任务会每50ms按协议处理解析缓存区里的数据。当然, // 如果没有处理完缓存区的数据,而又接收到新的数据,那新的数据将会被 // 舍弃。  //  串口的接收数据和发送数据都用到DMA处理器,其中串口接收用了串口 // 空闲中断。串口连续接收数据后检测到串口接收空闲,产生一个空闲中断, // 这时候将接收到的数据缓存到uart缓存区中,等待解析。  // 1. 配置串口IO口以及串口功能配置  //  这里使用的是uart1  #define FIFOLEN 256  static uint8_t dma_buf[FIFOLEN]; static uint8_t dma_rx[FIFOLEN]; static u8 fifo_buf[FIFOLEN]; static u16 fifo_in = 0; static u16 fifo_out = 0; static u16 fifo_used = 0;  void uart1_func_init(void) {    GPIO_InitTypeDef io;    USART_InitTypeDef uart;      //UART1 IO口配置    io.GPIO_Pin = GPIO_Pin_9;    io.GPIO_Mode= GPIO_Mode_AF_PP;    io.GPIO_Speed= GPIO_Speed_50MHz;    GPIO_Init(GPIOA, &io);    io.GPIO_Pin = GPIO_Pin_10;    io.GPIO_Mode= GPIO_Mode_IN_FLOATING;    io.GPIO_Speed= GPIO_Speed_50MHz;;    GPIO_Init(GPIOA, &io);     //USART1 功能配置 波特率115200,8位数据位,1位停止位,无校验,无硬件流控制    uart.USART_BaudRate = 115200;    uart.USART_WordLength = USART_WordLength_8b;    uart.USART_StopBits = USART_StopBits_1;    uart.USART_Parity = USART_Parity_No;    uart.USART_HardwareFlowControl = USART_HardwareFlowControl_None;    uart.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;      USART_Init(USART1, &uart);    USART_ITConfig(USART1,USART_IT_TC,DISABLE);//使能串口空闲中断    USART_ITConfig(USART1,USART_IT_RXNE,DISABLE);//失能接收中断    USART_ITConfig(USART1,USART_IT_IDLE,ENABLE);//使能发送中断      USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);//使能串口发送DMA    USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);//使能串口接收DMA    USART_Cmd(USART1, ENABLE); }    // 2. 配置DMA功能 //  stm32f103手册里可以了解到,uart1-uart4有相关的DMA通道,对应如下 //  uart1_tx-->DMA1_Channel4 uart1_rx-->DMA1_Channel5 //  uart2_tx-->DMA1_Channel7 uart2_rx-->DMA1_Channel6 //  uart3_tx-->DMA1_Channel2 uart3_rx-->DMA1_Channel3 //  uart4_tx-->DMA2_Channel5 uart4_rx-->DMA2_Channel2   static void uart1_dma_init(void) {    DMA_InitTypeDef  dma;      //DMA 配置    dma.DMA_BufferSize         = 1;                           //初始化为1个字节    dma.DMA_DIR                = DMA_DIR_PeripheralDST;       //从内存到外设    dma.DMA_M2M                = DMA_M2M_Disable;             //内存到内存,失能    dma.DMA_MemoryBaseAddr     = (uint32_t)dma_buf;           //内存地址    dma.DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte;     //数据宽度    dma.DMA_MemoryInc          = DMA_MemoryInc_Enable;        //使能自增    dma.DMA_Mode               = DMA_Mode_Normal;             //普通模式,不连续模式    dma.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;  //外设地址    dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //数据宽度    dma.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;   //外设地址不自增    dma.DMA_Priority           = DMA_Priority_High;           //优先级    DMA_DeInit(DMA1_Channel4);    DMA_Init(DMA1_Channel4, &dma);    DMA_Cmd(DMA1_Channel4, ENABLE);      dma.DMA_PeripheralBaseAddr = (u32)(&USART1->DR);    dma.DMA_MemoryBaseAddr = (uint32_t)dma_rx;    dma.DMA_DIR = DMA_DIR_PeripheralSRC;    dma.DMA_BufferSize = FIFOLEN;    dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable;    dma.DMA_MemoryInc = DMA_MemoryInc_Enable;    dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;    dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;    dma.DMA_Mode = DMA_Mode_Normal;    dma.DMA_Priority = DMA_Priority_VeryHigh;    dma.DMA_M2M = DMA_M2M_Disable;    DMA_DeInit(DMA1_Channel5);    DMA_Init(DMA1_Channel5,&dma);    DMA_Cmd(DMA1_Channel5,ENABLE); }    void uart1_init(void) {    uart1_dma_init();    uart1_func_init(); }   //3. uart 缓存区用fifo方式存取 u16 uart1_read(u8* data, u16 len) {    u16 i;    u16 ret;    ret = (len < fifo_used) ? len : fifo_used;    for(i = 0; i < ret; i++)    {        data[i] = fifo_buf[fifo_out];        if(++fifo_out == FIFOLEN)        {            fifo_out = 0;        }    }    fifo_used -= ret;    return ret; }   void uart1_write(uint8_t* data, uint16_t len) {    uint16_t i;    while(!DMA_GetFlagStatus(DMA1_FLAG_TC4));    DMA_Cmd(DMA1_Channel4, DISABLE);      for(i=0; i<len; i++)    {        dma_buf[i] = data[i];    }    DMA_ClearFlag(DMA1_FLAG_TC4);    DMA_SetCurrDataCounter(DMA1_Channel4, len);    DMA_Cmd(DMA1_Channel4, ENABLE); }  //打印调试信息 void uart1_puts(char* s) {    u16 i;    for(i=0;s[i]!=0;i++)    {        while(!USART_GetFlagStatus(USART1, USART_FLAG_TXE));        USART_SendData(USART1, s[i]);    } }  void USART1_IRQHandler(void) {    u16 temp;    u16 i;    if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)    {        temp = USART1->SR;//----清除空闲标志位        temp = USART1->DR;        DMA_Cmd(DMA1_Channel5,DISABLE);          temp = FIFOLEN - DMA_GetCurrDataCounter(DMA1_Channel5);        for(i=0; i<temp; i++)        {            if(fifo_used<FIFOLEN)            {                fifo_buf[fifo_in] = dma_rx[i];                if(++fifo_in == FIFOLEN)                {                    fifo_in = 0;                }                fifo_used++;            }        }          DMA_SetCurrDataCounter(DMA1_Channel5,FIFOLEN);        DMA_Cmd(DMA1_Channel5,ENABLE);    }    else    {        USART_ReceiveData(USART1);        USART_ClearFlag(USART1, USART_FLAG_ORE);    } }  //------------------------------------------------------------------------------------  上面是c文件,在h文件的接口如下   void uart1_init(void); u16 uart1_read(u8* data, u16 len); void uart1_write(u8* data, u16 len); void uart1_puts(char* s);  //---------------------------------------------------------------------------------------            完成了上面的配置,就可以在解析数据包的任务里调用uart1_read函数了。长度一般为缓存区长度。  这里有两个发送函数,一个是uart1_put,一个是uart1_write,前者没有dma发送,不需要指定长度,发送完整的字符串出去,适合打印调试信息到上位机。后者是dma方式发送,可以一定程度上减轻cpu负担,需要指定发送长度。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
下面是一个使用STM32F103标准库函数的串口+DMA发送不定长数据的示例代码: ```c #include "stm32f10x.h" // 定义串口DMA发送缓存区大小 #define TX_BUFFER_SIZE 256 // 定义串口DMA发送缓存区 uint8_t tx_buffer[TX_BUFFER_SIZE]; // 初始化函数 void init(void) { // 使能DMA1时钟 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // 使能串口1时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); // 配置USART1的GPIO引脚 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置USART1 USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; 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_Tx; USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE); // 配置DMA1通道4 DMA_InitTypeDef DMA_InitStructure; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR); DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)tx_buffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = 0; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel4, &DMA_InitStructure); // 使能DMA1通道4传输完成中断 DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE); // 使能DMA1通道4 DMA_Cmd(DMA1_Channel4, ENABLE); } // 串口DMA发送函数 void uart_send_dma(uint8_t *data, uint16_t len) { // 等待DMA1通道4传输完成 while (DMA_GetFlagStatus(DMA1_FLAG_TC4) == RESET); // 清除DMA1通道4传输完成标志位 DMA_ClearFlag(DMA1_FLAG_TC4); // 复位DMA1通道4 DMA_Cmd(DMA1_Channel4, DISABLE); DMA_SetCurrDataCounter(DMA1_Channel4, len); DMA_Cmd(DMA1_Channel4, ENABLE); // 将数据写入发送缓存区 for (int i = 0; i < len; i++) { tx_buffer[i] = data[i]; } } int main(void) { init(); // 发送数据 uint8_t data[] = {0x01, 0x02, 0x03, 0x04}; uart_send_dma(data, sizeof(data)); while (1); return 0; } ``` 需要注意的是,本示例使用了USART1的TX引脚,并且只实现了发送功能。如果需要实现接收功能,需要使用USART1的RX引脚,并且需要在USART_InitStructure中设置USART_Mode为USART_Mode_Rx | USART_Mode_Tx。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值