新手上路
- 积分
- 24
- 金钱
- 24
- 注册时间
- 2017-9-20
- 在线时间
- 4 小时
|
3金钱
具体的程序如下:#include "stm32f0xx.h"#include "bsp_usart1.h"
#define USART_TDR_Address (USART1_BASE + 0x28)
#define USART_RDR_Address (USART1_BASE + 0x24)
#define TXBUFF_SIZE 255
#define RXBUFF_SIZE 255
uint8_t Tx_Buff[TXBUFF_SIZE];
uint8_t Rx_Buff[RXBUFF_SIZE];
uint8_t Flag_Uart_Send = 0;
uint8_t Rx_Size = 0;
uint8_t rx_buff[255];
/// 配置USART2接收中断
static void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the DMA Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_3_IRQn; // 发送DMA通道的中断配置
NVIC_InitStructure.NVIC_IRQChannelPriority = 0x03; // 优先级设置
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable the USART Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; // 串口中断配置
NVIC_InitStructure.NVIC_IRQChannelPriority =0x02;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**
* @brief USART3 TX DMA 配置,内存到外设(USART1->DR)
* @param 无
* @retval 无
*/
void USART1_DMA_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
/*开启DMA时钟*/
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
///*--- LUMMOD_UART_Tx_DMA_Channel DMA Config ---*/
/*关DMA通道*/
DMA_Cmd(DMA1_Channel2, DISABLE);
/*恢复缺省值*/
DMA_DeInit(DMA1_Channel2);
/*设置DMA源:串口数据寄存器地址*/
DMA_InitStructure.DMA_PeripheralBaseAddr = USART_TDR_Address;
/*内存地址(要传输的变量的指针)*/
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Tx_Buff;
/*方向:从内存到外设*/
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
/*传输大小DMA_BufferSize=TXBUFF_SIZE*/
DMA_InitStructure.DMA_BufferSize = TXBUFF_SIZE;
/*外设地址不增*/
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
/*内存地址自增*/
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
/*外设数据单位*/
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
/*内存数据单位 8bit*/
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
/*DMA模式:单次传输模式*/
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal ;
/*优先级:高*/
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
/*禁止内存到内存的传输 */
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
/*配置DMA1的2通道*/
DMA_Init(DMA1_Channel2, &DMA_InitStructure);
/*清除DMA所有标志*/
DMA_ClearFlag(DMA1_FLAG_GL2);
/*关闭DMA*/
DMA_Cmd (DMA1_Channel2,DISABLE);
/*配置DMA发送完成后产生中断*/
DMA_ITConfig(DMA1_Channel2, DMA_IT_TC, ENABLE);
/*--- LUMMOD_UART_Rx_DMA_Channel DMA Config ---*/
/*关DMA通道*/
DMA_Cmd(DMA1_Channel3, DISABLE);
/*恢复缺省值*/
DMA_DeInit(DMA1_Channel3);
/*设置DMA源:串口数据寄存器地址*/
DMA_InitStructure.DMA_PeripheralBaseAddr = USART_RDR_Address;
/*内存地址(要传输的变量的指针)*/
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Rx_Buff;
/*方向:从外设到内存*/
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
/*传输大小DMA_BufferSize=RXBUFF_SIZE*/
DMA_InitStructure.DMA_BufferSize = RXBUFF_SIZE;
/*外设地址不增*/
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
/*内存地址自增*/
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
/*外设数据单位*/
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
/*内存数据单位 8bit*/
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
/*DMA模式:单次传输模式*/
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal ;
/*优先级:高*/
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
/*禁止内存到内存的传输 */
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
/*配置DMA1的2通道*/
DMA_Init(DMA1_Channel3, &DMA_InitStructure);
/*清除DMA所有标志*/
DMA_ClearFlag(DMA1_FLAG_GL3);
/*关闭DMA*/
DMA_Cmd (DMA1_Channel3,ENABLE);
}
/**
* @brief USART3 GPIO 配置,工作模式配置。115200 8-N-1
* @param 无
* @retval 无
*/
void USART1_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure; //定义串口初始化结构体
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); //使能GPIOA的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//使能USART的时钟
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);//配置PA9成第二功能引脚 TX
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);//配置PA10成第二功能引脚 RX
/*USART1_TX ->PA9 USART1_RX ->PA10*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10; //选中串口默认输出管脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //定义输出最大速率
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//定义管脚9的模式
GPIO_Init(GPIOA, &GPIO_InitStructure); //调用函数,把结构体参数输入进行初始化
/*串口通讯参数设置*/
USART_InitStructure.USART_BaudRate = 9600; //波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位8位
USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位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);
USART1_DMA_Config(); // 串口 DMA 配置
NVIC_Configuration();
USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); // 开启 串口空闲IDEL 中断
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); // 开启串口DMA发送
USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE); // 开启串口DMA接收
// queueCreate(&g_SendQueue,g_SendBuffer,UART_BUF_SIZE);
// queueCreate(&g_RecvQueue,g_RecvBuffer,UART_BUF_SIZE);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_Cmd(USART1, ENABLE);
}
void USART1_DAM_Tx_Over(void)
{
DMA_ClearFlag(DMA1_FLAG_GL2); // 清除标志
DMA_Cmd(DMA1_Channel2, DISABLE); // 关闭DMA通道
Flag_Uart_Send = 0;
}
void Uart1Send(uint8_t *buf,uint8_t Size)
{
uint8_t i;
for(i=0;i<Size;i++)
{
Tx_Buff[i] = buf[i];
}
DMA1_Channel2->CNDTR = (uint16_t)Size; // 设置要发送的字节数目
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
DMA_Cmd(DMA1_Channel2, ENABLE); //开始DMA发送
Flag_Uart_Send = 1;
}
void USART1_DMA_Rx_Data(void)
{
uint16_t i = 0;
Rx_Size = USART1->ISR;
Rx_Size = USART1->RDR;
DMA_Cmd(DMA1_Channel3, DISABLE); // 关闭DMA ,防止干扰
DMA_ClearFlag(DMA1_FLAG_GL3 ); // 清DMA标志位
Rx_Size = RXBUFF_SIZE - DMA_GetCurrDataCounter(DMA1_Channel3); //获得接收到的字节数
for(i = 0;i < Rx_Size;i++)
{
rx_buff[i]=Rx_Buff[i];
// enqueue(&g_RecvQueue,Rx_Buff[i]);
}
DMA1_Channel3->CNDTR = RXBUFF_SIZE; // 重新赋值计数值,必须大于等于最大可能接收到的数据帧数目
DMA_Cmd(DMA1_Channel3, ENABLE); //处理完在开启缓冲
/* DMA 开启,等待数据。注意,如果中断发送数据帧的速率很快,MCU来不及处理此次接收到的数据,中断又发来数据的话,这里不能开启,否则数据会被覆盖。有2种方式解决。
1. 在重新开启接收DMA通道之前,将LumMod_Rx_Buf缓冲区里面的数据复制到另外一个数组中,然后再开启DMA,然后马上处理复制出来的数据。
2. 建立双缓冲,在LumMod_Uart_DMA_Rx_Data函数中,重新配置DMA_MemoryBaseAddr 的缓冲区地址,那么下次接收到的数据就会保存到新的缓冲区中,不至于被覆盖。*/
}
中断函数如下
void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) // 空闲中断
{
USART1_DMA_Rx_Data();
USART_ReceiveData( USART1 ); // Clear IDLE interrupt flag bit
}
}
void DMA1_Channel2_3_IRQHandler(void)
{
/*判断是否发送完毕*/
if(DMA_GetITStatus(DMA1_FLAG_TC2))
{
USART1_DAM_Tx_Over();
}
}
现在问题是只能发送一次,就停了,接收不能接收,麻烦大家帮帮忙
|
|