您的位置 首页 解答

stm32的串口闲暇中止接纳数据

举个例子:1、后台数据->USART1->USART2->其它设备,其它设备数据->USART2->USART1->后台,这两个数据过程也可能同时进行。2、由于硬件

举个比方:

1、后台数据->USART1-> USART2->其它设备,其它设备数据->USART2-> USART1->后台,这两个数据进程也或许一起进行。

2、因为硬件的约束,USART1和USART2的传输波特率不一样,比方USART1运用GPRS通讯,USART2运用短距离无线通讯;或许USART1运用以太网通讯,USART2运用485总线通讯。

现在我把我完结的进程简略描绘一下:

1、 初始化设置:USART1_RX DMA1_ Channel5,USART2_RX DMA1_ Channel6,USART1_TX DMA1_ Channel4,USART2_TX DMA1_ Channel7(详细设置请看程序包)
2、 当数据发送给USART1接纳结束时分会引起USART1的串口总线中止,核算DMA1_ Channel5内存数组剩下容量,得到接纳的字符长度。将接纳的字符给DMA1_ Channel4内存数组,发动DMA1_ Channel4通道传输数据,(传输完结需求封闭。)下一次数据接纳能够在发动DMA1_ Channel4时分就开端,不需求等候DMA1_ Channel4数据传输完结。可是上一次DMA1_ Channel4完结之前,不能够将数据给DMA1_ Channel4内存数组,会冲掉曾经数据。

3、 USART2类同USART1。

源程序:

IO口界说:
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* 第1步:翻开GPIO和USART部件的时钟 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
/* 第2步:将USART Tx的GPIO装备为推挽复用形式 */
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);
/* 第3步:将USART Rx的GPIO装备为浮空输入形式
因为CPU复位后,GPIO缺省都是浮空输入形式,因而下面这个过程不是有必要的
可是,我仍是主张加上便于阅览,而且避免其它当地修改了这个口线的设置参数
*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* 第1步:翻开GPIO和USART2部件的时钟 */
//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
/* 第2步:将USART2 Tx的GPIO装备为推挽复用形式 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* 第3步:将USART2 Rx的GPIO装备为浮空输入形式
因为CPU复位后,GPIO缺省都是浮空输入形式,因而下面这个过程不是有必要的
可是,我仍是主张加上便于阅览,而且避免其它当地修改了这个口线的设置参数
*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* 第3步现已做了,因而这步能够不做
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
*/
GPIO_Init(GPIOA, &GPIO_InitStructure);

}

串口初始化:
void USART_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
/* 第4步:装备USART参数
– BaudRate = 115200 baud
– Word Length = 8 Bits
– One Stop Bit
– No parity
– Hardware flow control disabled (RTS and CTS signals)
– Receive and transmit enabled
*/
USART_InitStructure.USART_BaudRate = 19200;
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);

//装备USART1闲暇中止

USART_ITConfig(USART1, USART_IT_IDLE , ENABLE);

/* 第5步:使能 USART, 装备结束 */
USART_Cmd(USART1, ENABLE);
/* CPU的小缺点:串口装备好,假如直接Send,则第1个字节发送不出去
如下句子处理第1个字节无法正确发送出去的问题 */
USART_ClearFlag(USART1, USART_FLAG_TC);/* 清发送完结标志,Transmission Complete flag */
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(USART2, &USART_InitStructure);

//装备USART2闲暇中止

USART_ITConfig(USART2, USART_IT_IDLE , ENABLE);
USART_Cmd(USART2, ENABLE);
/* CPU的小缺点:串口装备好,假如直接Send,则第1个字节发送不出去
如下句子处理第1个字节无法正确发送出去的问题 */
USART_ClearFlag(USART2, USART_FLAG_TC);/* 清发送外城标志,Transmission Complete flag */

}

DMA装备:
void DMA_Configuration(void)
{
DMA_InitTypeDef DMA_InitStructure;
/* DMA clock enable */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//敞开DMA1外设时钟
/* DMA1 Channel4 (triggered by USART1 Tx event) Config */
DMA_DeInit(DMA1_Channel4);
DMA_InitStructure.DMA_PeripheralBaseAddr = 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_Circular;//循环形式
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel4, &DMA_InitStructure);
DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE);
DMA_ITConfig(DMA1_Channel4, DMA_IT_TE, ENABLE);
/* Enable USART1 DMA TX request */
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
DMA_Cmd(DMA1_Channel4, DISABLE);
/* DMA1 Channel5 (triggered by USART2 Tx event) Config */
DMA_DeInit(DMA1_Channel7);
DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40004404;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART2_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_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel7, &DMA_InitStructure);
DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE);
DMA_ITConfig(DMA1_Channel7, DMA_IT_TE, ENABLE);
/* Enable USART1 DMA TX request */
USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);
DMA_Cmd(DMA1_Channel7, DISABLE);
/* DMA1 Channel5 (triggered by USART1 Rx event) Config */
DMA_DeInit(DMA1_Channel5);
DMA_InitStructure.DMA_PeripheralBaseAddr = 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);
DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);
DMA_ITConfig(DMA1_Channel5, DMA_IT_TE, ENABLE);
/* Enable USART1 DMA RX request */
USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
DMA_Cmd(DMA1_Channel5, ENABLE);
/* DMA1 Channel6 (triggered by USART1 Rx event) Config */
DMA_DeInit(DMA1_Channel6);
DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40004404;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART2_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_Medium;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel6, &DMA_InitStructure);
DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE);
DMA_ITConfig(DMA1_Channel6, DMA_IT_TE, ENABLE);
/* Enable USART2 DMA RX request */
USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE);
DMA_Cmd(DMA1_Channel6, ENABLE);

}

中止优先级装备:
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure one bit for preemption priority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/* Enable the USART1 Interrupt */
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);
/* Enable the USART2 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//Enable DMA Channel4 Interrupt
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//Enable DMA Channel7 Interrupt
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/*Enable DMA Channel5 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/*Enable DMA Channel6 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel6_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

}

数组界说,意义如落款:
u8 USART1_SEND_DATA[512];
u8 USART2_SEND_DATA[512];
u8 USART1_RECEIVE_DATA[512];
u8 USART2_RECEIVE_DATA[512];
u8 USART1_TX_Finish=1;// USART1发送完结标志量

u8 USART2_TX_Finish=1;// USART2发送完结标志量

USART1中止服务函数
void USART1_IRQHandler(void)
{
u16 DATA_LEN;
u16 i;
if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)//假如为闲暇总线中止
{
DMA_Cmd(DMA1_Channel5, DISABLE);//封闭DMA,避免处理其间有数据
//USART_RX_STA = USART1->SR;//先读SR,然后读DR才干铲除
//USART_RX_STA = USART1->DR;
DATA_LEN=512-DMA_GetCurrDataCounter(DMA1_Channel5);
if(DATA_LEN > 0)
{
while(USART1_TX_Finish==0)//等候数据传输完结才下一次
{
;

}

//将数据送DMA存储地址
for(i=0;iTA_LEN;i )
{
USART1_SEND_DATA=USART1_RECEIVE_DATA;
}
//USART用DMA传输代替查询方法发送,战胜被高优先级中止而发生丢帧现象。
DMA_Cmd(DMA1_Channel4, DISABLE);//改动datasize前先要制止通道作业
DMA1_Channel4->CNDTR=DATA_LEN;//DMA1,传输数据量
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
//读SR后读DR铲除Idle
i = USART1->SR;
i = USART1->DR;
}
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);
USART_ClearITPendingBit(USART1, USART_IT_IDLE);

}

USART2中止服务函数
void USART2_IRQHandler(void)
{
u16 DATA_LEN;
u16 i;
if(USART_GetITStatus(USART2, USART_IT_IDLE) != RESET)//假如为闲暇总线中止
{
DMA_Cmd(DMA1_Channel6, DISABLE);//封闭DMA,避免处理其间有数据
//USART_RX_STA = USART1->SR;//先读SR,然后读DR才干铲除
//USART_RX_STA = USART1->DR;
DATA_LEN=512-DMA_GetCurrDataCounter(DMA1_Channel6);
if(DATA_LEN > 0)
{
while(USART2_TX_Finish==0)//等候数据完结才下一次
{
;
}
//将数据送DMA存储地址
for(i=0;iTA_LEN;i )
{
USART2_SEND_DATA=USART2_RECEIVE_DATA;
}
//USART用DMA传输代替查询方法发送,战胜被高优先级中止而发生丢帧现象。
DMA_Cmd(DMA1_Channel7, DISABLE);//改动datasize前先要制止通道作业
DMA1_Channel7->CNDTR=DATA_LEN; //DMA1,传输数据量
USART2_TX_Finish=0;//DMA传输开端标志量
DMA_Cmd(DMA1_Channel7, ENABLE);
}
//DMA_Cmd(DMA1_Channel5, DISABLE);//封闭DMA,避免处理其间有数据
DMA_ClearFlag(DMA1_FLAG_GL6 | DMA1_FLAG_TC6 | DMA1_FLAG_TE6 | DMA1_FLAG_HT6);//清标志
DMA1_Channel6->CNDTR = 512;//重装填
DMA_Cmd(DMA1_Channel6, ENABLE);//处理完,重开DMA
//读SR后读DR铲除Idle
i = USART2->SR;
i = USART2->DR;
}
if(USART_GetITStatus(USART2, USART_IT_PE | USART_IT_FE | USART_IT_NE) != RESET)//犯错
{
USART_ClearITPendingBit(USART2, USART_IT_PE | USART_IT_FE | USART_IT_NE);
}
USART_ClearITPendingBit(USART2, USART_IT_TC);
USART_ClearITPendingBit(USART2, USART_IT_IDLE);

}

DMA1_Channel5中止服务函数
void DMA1_Channel5_IRQHandler(void)
{
DMA_ClearITPendingBit(DMA1_IT_TC5);
DMA_ClearITPendingBit(DMA1_IT_TE5);
DMA_Cmd(DMA1_Channel5, DISABLE);//封闭DMA,避免处理其间有数据
DMA1_Channel5->CNDTR = 580;//重装填
DMA_Cmd(DMA1_Channel5, ENABLE);//处理完,重开DMA

}

DMA1_Channel6中止服务函数
void DMA1_Channel6_IRQHandler(void)
{
DMA_ClearITPendingBit(DMA1_IT_TC6);
DMA_ClearITPendingBit(DMA1_IT_TE6);
DMA_Cmd(DMA1_Channel6, DISABLE);//封闭DMA,避免处理其间有数据
DMA1_Channel6->CNDTR = 580;//重装填
DMA_Cmd(DMA1_Channel6, ENABLE);//处理完,重开DMA

}

DMA1_Channel4中止服务函数
//USART1运用DMA发数据中止服务程序
void DMA1_Channel4_IRQHandler(void)
{
DMA_ClearITPendingBit(DMA1_IT_TC4);
DMA_ClearITPendingBit(DMA1_IT_TE4);
DMA_Cmd(DMA1_Channel4, DISABLE);//封闭DMA
USART1_TX_Finish=1;//置DMA传输完结

}

DMA1_Channel7中止服务函数
//USART2运用DMA发数据中止服务程序
void DMA1_Channel7_IRQHandler(void)
{
DMA_ClearITPendingBit(DMA1_IT_TC7);
DMA_ClearITPendingBit(DMA1_IT_TE7);
DMA_Cmd(DMA1_Channel7, DISABLE);//封闭DMA
USART2_TX_Finish=1;//置DMA传输完结

}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/changshang/jieda/277397.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部