|
#include "stm32f10x.h"
u8 USART1_SEND_DATA[512];
u8 USART1_RECEIVE_DATA[512];
u8 USART1_TX_Finish=1;// USART1发送完成标志量
void USART1_Init(void); //串口1的初始化函数, TX1(PA9), RX1(PA10)
void DAM_Init(void);
void NVIC_Configuration(void);
void GPIO_Configuration(void);
int main(void)
{
USART1_Init();
DAM_Init();
NVIC_Configuration();
GPIO_Configuration();
while(1)
{
}
}
void USART1_Init(void)
{
USART_InitTypeDef USART_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
USART_Cmd(USART1, ENABLE);
USART_InitStruct.USART_BaudRate = 9600;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStruct);
USART_Cmd(USART1, ENABLE);
}
void DAM_Init(void)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
//DMA初始化配置
DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t)&USART1->DR; //0x40013804;
// DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART1_SEND_DATA;;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //外设作为传输的目的
// DMA_InitStructure.DMA_BufferSize = 512;
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_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel4, &DMA_InitStructure);
/*使USART1 DMA RX 打开*/
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
DMA_Cmd(DMA1_Channel4, ENABLE);
//如果使能了DMA接收
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;// 0x40013804;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART1_RECEIVE_DATA;;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //外设作为传输的来源
DMA_InitStructure.DMA_BufferSize = 512;
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_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel5, &DMA_InitStructure);
/* 使USART1 DMA TX 打开 */
USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
DMA_Cmd(DMA1_Channel5, ENABLE);
}
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure1;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//接收中断使能,此步骤很重要!!!
// USART_ITConfig(USART1, USART_IT_IDLE , ENABLE);//开启空闲,帧错,噪声,校验错中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
//DMA发送中断配置
NVIC_InitStructure1.NVIC_IRQChannel = DMA1_Channel4_IRQn;
NVIC_InitStructure1.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure1.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure1.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure1);
//开启DMA中断
DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE);
// DMA_ITConfig(DMA1_Channel4, DMA_IT_TE, ENABLE);
//DMA接收中断配置
NVIC_InitStructure1.NVIC_IRQChannel = DMA1_Channel5_IRQn;
NVIC_InitStructure1.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure1.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure1.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure1);
//开启DMA中断
DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);
// DMA_ITConfig(DMA1_Channel5, DMA_IT_TE, ENABLE);
}
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
//使能串口1和GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
//配置管脚
//TX(PA9)配置为复用推挽输出
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
// GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
//RX(PA10)配置为浮空输入
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
// GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
}
//DMA1_Channel4中断服务函数
//USART1使用DMA发数据中断服务程序
void DMA1_Channel4_IRQHandler(void)
{
DMA_ClearITPendingBit(DMA1_IT_TC4); //清除DMA通道x中断待处理标志位、传输完成中断
DMA_ClearITPendingBit(DMA1_IT_TE4); //清除DMA通道x中断待处理标志位、传输错误中断
DMA_Cmd(DMA1_Channel4, DISABLE);//关闭DMA
USART1_TX_Finish=1;//置DMA传输完成
}
//DMA1_Channel5中断服务函数
void DMA1_Channel5_IRQHandler(void) // 问题是 接受中断没有接收到数据完成触发
{
DMA_ClearITPendingBit(DMA1_IT_TC5); //清除DMA通道x中断待处理标志位、传输完成中断
DMA_ClearITPendingBit(DMA1_IT_TE5);
DMA_Cmd(DMA1_Channel5, DISABLE);//关闭DMA,防止处理其间有数据
DMA1_Channel5->CNDTR = 580;//重装填
DMA_Cmd(DMA1_Channel5, ENABLE);//处理完,重开DMA
}
void USART1_IRQHandler(void)
{
u16 DATA_LEN;
u16 i;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)//如果为空闲总线中断 //程序到这里无法往下执行
{
DMA_Cmd(DMA1_Channel5, DISABLE);//关闭DMA,防止处理其间有数据
DATA_LEN=512-DMA_GetCurrDataCounter(DMA1_Channel5); //512-剩余待传数量=数据数量
if(DATA_LEN > 0)
{
while(USART1_TX_Finish==0);//等待数据传输完成才下一次
for(i=0;i
{
USART1_SEND_DATA[i]= (uint8_t)USART_ReceiveData(USART1);
// USART1_SEND_DATA[i]=USART1_RECEIVE_DATA[i];
}
//USART用DMA传输替代查询方式发送,克服被高优先级中断而产生丢帧现象。
DMA_Cmd(DMA1_Channel4, DISABLE); //改变datasize前先要禁止通道工作
DMA1_Channel4->CNDTR=DATA_LEN; //DMA1,传输数据量 DMA_SetCurrDataCounter(DMA1_Channel4,DATA_LEN);
USART1_TX_Finish=0;//DMA传输开始标志量
DMA_Cmd(DMA1_Channel4, ENABLE);
}
//DMA_Cmd(DMA1_Channel5, DISABLE);//关闭DMA,防止处理其间有数据
DMA_ClearFlag(DMA1_FLAG_GL5 | DMA1_FLAG_TC5 | DMA1_FLAG_TE5 | DMA1_FLAG_HT5);//清标志
DMA1_Channel5->CNDTR = 512;//重装填
DMA_Cmd(DMA1_Channel5, ENABLE);//处理完,重开DMA
i = USART1->SR;
i = USART1->DR; //清USART_IT_IDLE标志
}
if(USART_GetITStatus(USART1, USART_IT_PE | USART_IT_FE | USART_IT_NE) != RESET)//出错
{
USART_ClearITPendingBit(USART1, USART_IT_PE | USART_IT_FE | USART_IT_NE); //奇偶错误中断
}
USART_ClearITPendingBit(USART1, USART_IT_TC); //清除USARTx的中断待处理位,传输完成中断
USART_ClearITPendingBit(USART1, USART_IT_IDLE); //清除USARTx的中断待处理位,空闲总线中断
}
|
|