直接上代码 /******************************************************************************** * 函 数 名: USART_Config() * 功能描述: 配置USART的GPIO口 * 输入参数: bau 串口波特率 * 输出参数: void * 注 释: 配置USART串口参数 ********************************************************************************/ void USARTx_Config(USART_TypeDef* USARTx,unsigned int bar) { USART_InitTypeDef USART_InitStructure; //USART1 初始化设置 USART_InitStructure.USART_BaudRate = bar; //波特率设置 USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长为8位数据格式 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_Rx | USART_Mode_Tx; //收发模式 USART_Init(USARTx, &USART_InitStructure); //初始化串口1 } /******************************************************************************** * 函 数 名: USARTx_IT_Config() * 功能描述: 配置USART的GPIO口 * 输入参数: irq 中断通道号 * Pre 抢占优先级 * Sub 子优先级 * 输出参数: void * 注 释: 配置串口中断 ********************************************************************************/ void USARTx_IT_Config(unsigned char irq,unsigned char Pre,unsigned char Sub) { NVIC_InitTypeDef NVIC_InitStructure; //Usart1 NVIC 配置 NVIC_InitStructure.NVIC_IRQChannel = irq; //串口1中断通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=Pre;//抢占优先级 NVIC_InitStructure.NVIC_IRQChannelSubPriority =Sub; //子优先级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器、 } /******************************************************************************** * 函 数 名: USARTx_DMA_Config() * 功能描述: 配置USART的DMA通道 * 输入参数: DMAy_Channelx 通道号 * paddr 外设地址 (串口的DR地址,详情配置见Init代码) * Maddr 存储器地址 * dir 模式 DMA_DIR_PeripheralDST(存储器到外设) DMA_DIR_PeripheralSRC(外设到存储器) * size 传输数据量 * 输出参数: void * 注 释: 配置串口中断 ********************************************************************************/ void USARTx_DMA_Config(DMA_Channel_TypeDef* DMAy_Channelx,unsigned int paddr,unsigned int Maddr,unsigned int dir,unsigned int size) { DMA_InitTypeDef DMA_InitStructure; DMA_DeInit(DMAy_Channelx); /* 配置 DMA 发送通道*/ DMA_InitStructure.DMA_PeripheralBaseAddr = paddr; //DMA外设地址 DMA_InitStructure.DMA_MemoryBaseAddr = Maddr; //DMA 存储器地址 DMA_InitStructure.DMA_DIR = dir; //存储器到外设模式 DMA_InitStructure.DMA_BufferSize = size; //数据传输量 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设非增量模式 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //存储器增量模式 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据长度:8位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //存储器数据长度:8位 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //使用普通模式 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //中等优先级 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输 DMA_Init(DMAy_Channelx, &DMA_InitStructure); //初始化DMA } /******************************************************************************** * 函 数 名: USART_Init() * 功能描述: 配置USART * 输入参数: void * 输出参数: void * 注 释: 配置USART串口参数 ********************************************************************************/ void USARTx_Init(void) { /*USART1 config*/ USARTx_Config(USART1,115200); USART_Cmd(USART1, ENABLE); //使能串口1 USART_ClearFlag(USART1, USART_FLAG_TC); /*清除发送中断标志*/ USART_ClearFlag(USART1, USART_IT_IDLE); /*清除空闲中断标志*/ USART_ITConfig(USART1, USART_FLAG_TC, ENABLE); /*开启空闲中断*/ USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); /*开启空闲中断*/ USARTx_IT_Config(USART1_IRQn,0,0); USARTx_DMA_Config(DMA1_Channel4,(unsigned int)&USART1->DR,(unsigned int)USARTStr.SendBuff,DMA_DIR_PeripheralDST,0); USARTx_DMA_Config(DMA1_Channel5,(unsigned int)&USART1->DR,(unsigned int)USARTStr.ReadBuff,DMA_DIR_PeripheralSRC,USART_BUFSIZE); USART_DMACmd(USART1, USART_DMAReq_Tx|USART_DMAReq_Rx, ENABLE); /* 使能DMA串口发送和接受请求 */ DMA_Cmd(DMA1_Channel5,ENABLE); /*打开接收数据通道*/ UserMemset((unsigned char *)&USARTStr,0,sizeof(USARTStr)); /*USART2 config*/ USARTx_Config(USART2,115200); USART_Cmd(USART2, ENABLE); //使能串口1 USART_ClearFlag(USART2, USART_FLAG_TC); /*清除发送中断标志*/ USART_ITConfig(USART2, USART_IT_IDLE, ENABLE); /*开启空闲中断*/ USARTx_IT_Config(USART2_IRQn,0,1); USARTx_DMA_Config(DMA1_Channel7,(unsigned int)&USART2->DR,(unsigned int)USART2Str.SendBuff,DMA_DIR_PeripheralDST,0); USARTx_DMA_Config(DMA1_Channel6,(unsigned int)&USART2->DR,(unsigned int)USART2Str.ReadBuff,DMA_DIR_PeripheralSRC,USART_BUFSIZE); USART_DMACmd(USART2, USART_DMAReq_Tx|USART_DMAReq_Rx, ENABLE); /* 使能DMA串口发送和接受请求 */ DMA_Cmd(DMA1_Channel6,ENABLE); /*打开接收数据通道*/ UserMemset((unsigned char *)&USART2Str,0,sizeof(USART2Str)); } /******************************************************************************** * 函 数 名: USART1SendData * 功能描述: 串口1DMA发送数组 * 输入参数: buf 发送的数组 * len 数组长度 * 输出参数: void * 注 释: 无 ********************************************************************************/ void USART1SendData(unsigned char *pData,unsigned short size) { UserCopy(USARTStr.SendBuff,pData,size); DMA_Cmd(DMA1_Channel4,DISABLE); DMA1_Channel4->CNDTR = size; DMA_Cmd(DMA1_Channel4,ENABLE); } /******************************************************************************** * 函 数 名: USART1_IRQHandler * 功能描述: 串口接收中断 * 输入参数: void * 输出参数: void * 注 释: 无 ********************************************************************************/ void USART1_IRQHandler(void) { unsigned char temp; if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) //空闲中断 { temp = USART1->SR; temp = USART1->DR; temp = temp; USARTStr.Len = USART_BUFSIZE - DMA1_Channel5->CNDTR; USARTStr.Flag = 0x80; DMA_Cmd(DMA1_Channel5, DISABLE); DMA1_Channel5->CNDTR=USART_BUFSIZE; DMA_Cmd(DMA1_Channel5, ENABLE); USART_ClearITPendingBit(USART1, USART_IT_IDLE); } if(USART_GetITStatus(USART1, USART_FLAG_TC) != RESET) //传输完成中断 { USARTStr.Flag = 0; UserMemset((unsigned char *)&USARTStr,0,USARTStr.Len); } } 下面是变量的声明 #define USART_BUFSIZE 1024 /*最大接收串口数据的值*/ /**************************************************************************** * Local Types ****************************************************************************/ typedef struct TagUSARTStruct{ /*声明结构体来接收串口的数据*/ unsigned short Len; unsigned char Flag; unsigned char SendBuff[USART_BUFSIZE]; /* 发送数据 */ unsigned char ReadBuff[USART_BUFSIZE]; /* 接收数据 */ }T_USARTStruct; extern T_USARTStruct USARTStr; /*外部调用声明*/ extern T_USARTStruct USART2Str; 串口的gpio配置是好搞的我就补贴上代码了 千万记住打开相关的时钟配置 /* open DMA1 clock */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); 以上的配置代码是测试完全通过的,在DMA中所说的外设到内存其实是配置了串口的DR数据地址映射到全局变量中,所说的外设是STM32在M3内核上添加的功能,例如:串口,IIC,SPI,ADC,DAC等这些外设,配置DMA时候把这些地址给到DMA外设地址配置上去,DMA内存是把代码中的全局变量的地址。STM32DMA有三种模式:内存到内存和外设到内存、内存到外设。使用接收PC端或者其他设备发送过来的数据在配置DMA时候必须提前打开,否则接收不到数据。例如串口1接收数据在配置DMA1通道5时候,在配置时要事先使能打开。通道4是用于发送数据出去可以填写好发送内容再打开,填数据前必须先关闭通道,中断可以根据需求去配置,但是配置了中断记得及时的清除标志位。否则发生整个程序在不断的执行中断代码,主程序代码无法执行,包括DMA的中断配置可根据手册查询配置,同样配置了,也要及时的清除中断标志。使用C自带微型库会增加代码大小,使用不多其实建议自己写,下面贴出代码。 /******************************************************************************** * 函 数 名: UserCopy * 功能描述: 拷贝数据 * 输入参数: pdata 拷贝到的数组 * data 要拷贝的数组 * len 拷贝的长度 * 输出参数: void * 注 释: 无 ********************************************************************************/ void UserCopy(unsigned char *pdata,unsigned char *data,int len) { int i; for(i=0;i<len;i++) { pdata = data; } } /******************************************************************************** * 函 数 名: UserMemset * 功能描述: 清除数据 * 输入参数: pdata 要清楚的数组 * t 填充的数据 * len 数组长度 * 输出参数: void * 注 释: 无 ********************************************************************************/ void UserMemset(unsigned char *pdata,char t,int len) { int i; for(i=0;i<len;i++) { pdata = t; } } /************************************************************** * 函 数 名:HexToAscii * 功能描述:十六进制转字符串 * 输入参数:pHex 十六进制 * pAscii 字符串 * nLen 长度 * 输出参数: void * 注 释: 无 ***************************************************************/ void HexToAscii(unsigned char *pHex, unsigned char *pAscii, int nLen) { unsigned char Nibble[2]; unsigned int i,j; for (i = 0; i < nLen; i++) { Nibble[0] = (pHex & 0xF0) >> 4; Nibble[1] = pHex & 0x0F; for (j = 0; j < 2; j++) { if(Nibble[j] < 10) { Nibble[j] += 0x30; } else { if(Nibble[j] < 16) Nibble[j] = Nibble[j] - 10 + 'A'; } *pAscii++ = Nibble[j]; } } *pAscii++ = '\0'; } |
STM32
超强工具——STM32CubeMX 你会用吗?
集结出发! STM32全国研讨会系列之一:ST智能门铃中国首秀
关于STM32启动文件的几个小问题
【银杏科技ARM+FPGA双核心应用】STM32H7系列35——USB_VCP_FS
【银杏科技ARM+FPGA双核心应用】STM32H7系列28——USB_HID
粉丝分享 | 图说CRC原理应用及STM32硬件CRC外设
STM32L151进入低功耗,并由RTC唤醒的故事
[转]stm32控制NFC模块(PN532)源码(P2P,模拟卡,读写卡等
STM32G070RB+LVGL移植
不客气