当前位置: 代码迷 >> 综合 >> stdma2
  详细解决方案

stdma2

热度:49   发布时间:2024-02-05 01:31:11.0

1.  

// DMA 存储器到外设(串口)数据传输实验#include "stm32f10x.h"
#include <stdio.h>#define  RECEIVEBUFF_SIZE  20 
uint8_t ReceiveBuff[RECEIVEBUFF_SIZE];
void USART_Config(void);
void USART1_NVIC_Config(void); 
void USART1_DMA_Config(void); int main(void)
{uint16_t i;USART_Config();USART1_DMA_Config();USART1_NVIC_Config();for(i=0;i<RECEIVEBUFF_SIZE;i++){ReceiveBuff[i]	 = 'x';}}
void USART_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);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);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_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_Rx | USART_Mode_Tx;USART_Init(USART1, &USART_InitStructure);USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);USART_Cmd(USART1, ENABLE);	    
}/*****************  发送一个字节 **********************/
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch)
{USART_SendData(pUSARTx,ch);while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);	
}/****************** 发送8位的数组 ************************/
void Usart_SendArray( USART_TypeDef * pUSARTx, uint8_t *array, uint16_t num)
{uint8_t i;for(i=0; i<num; i++){Usart_SendByte(pUSARTx,array[i]);	}while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET);
}/*****************  发送字符串 **********************/
void Usart_SendString( USART_TypeDef * pUSARTx, char *str)
{unsigned int k=0;do {Usart_SendByte( pUSARTx, *(str + k) );k++;} while(*(str + k)!='\0');while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET);
}/*****************  发送一个16位数 **********************/
void Usart_SendHalfWord( USART_TypeDef * pUSARTx, uint16_t ch)
{uint8_t temp_h, temp_l;/* 取出高八位 */temp_h = (ch&0XFF00)>>8;/* 取出低八位 */temp_l = ch&0XFF;/* 发送高八位 */USART_SendData(pUSARTx,temp_h);	while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);/* 发送低八位 */USART_SendData(pUSARTx,temp_l);	while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);	
}///重定向c库函数printf到串口,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{USART_SendData(USART1, (uint8_t) ch);while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);		return (ch);
}///重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);return (int)USART_ReceiveData(USART1);
}void USART1_DMA_Config(void)
{DMA_InitTypeDef DMA_InitStructure;RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);DMA_InitStructure.DMA_PeripheralBaseAddr = (USART1_BASE+0x04);DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ReceiveBuff;// 方向:从外设到内存DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;DMA_InitStructure.DMA_BufferSize = RECEIVEBUFF_SIZE;// 外设地址不增	    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模式,一次或者循环模式DMA_InitStructure.DMA_Mode = DMA_Mode_Normal ;//DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;DMA_InitStructure.DMA_Priority = DMA_Priority_High;DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;DMA_Init(DMA1_Channel5, &DMA_InitStructure);DMA_Cmd (DMA1_Channel5,ENABLE);
}//重新恢复DMA指针
void DMA_Enable(DMA_Channel_TypeDef*DMA_CHx)
{DMA_Cmd(DMA_CHx, DISABLE );  //关闭USART1 TX DMA1所指示的通道DMA_SetCurrDataCounter(DMA_CHx, RECEIVEBUFF_SIZE);//DMA通道的DMA缓存的大小DMA_Cmd(DMA_CHx, ENABLE);  //打开USART1 TX DMA1所指示的通道
}void USART1_NVIC_Config(void)
{NVIC_InitTypeDef NVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);
}//串口中断函数
void USART1_IRQHandler(void)               
{uint8_t Usart1_Rec_Cnt;if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾){USART_ReceiveData(USART1);//读取数据注意:这句必须要,否则不能够清除中断标志位。//算出接本帧数据长度Usart1_Rec_Cnt = RECEIVEBUFF_SIZE - DMA_GetCurrDataCounter(DMA1_Channel5); //***********帧数据处理函数************//printf ("Thelenght:%d\r\n",Usart1_Rec_Cnt);printf ("The data:\r\n");Usart_SendArray(USART1, ReceiveBuff, RECEIVEBUFF_SIZE);printf ("\r\nOver! \r\n");USART_ClearITPendingBit(USART1,USART_IT_IDLE);  //清除中断标志DMA_Enable(DMA1_Channel5);                  //恢复DMA指针,等待下一次的接收}} 

 

  相关解决方案