专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
STM32
谁有串口通信的资料,分享一下可好
2019-10-16 04:27
发布
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
站内问答
/
STM32/STM8
5414
6
1505
在这里,我不想去下载百度了,因为为了几个程序,还得等好长时间去下载,现在只想问问大家有没有相关的程序,谢谢啦,分享下。
友情提示:
此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
6条回答
yyx112358
2019-10-16 09:28
…………原子哥有分文件夹的程序,你可以看看
我手上只有我自己改过的程序,你不怕麻烦也可以看看
[mw_shl_code=c,true]#include "sys.h"
#include "usart.h"
//////////////////////////////////////////////////////////////////////////////////
//如果使用ucos,则包括下面的头文件即可.
#if SYSTEM_SUPPORT_UCOS
#include "includes.h" //ucos 使用
#endif
//////////////////////////////////////////////////////////////////////////////////
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32F4探索者开发板
//串口1初始化
//正点原子@ALIENTEK
//技术论坛:
www.openedv.com
//修改日期:2014/6/10
//版本:V1.5
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2009-2019
//All rights reserved
//********************************************************************************
//V1.3修改说明
//支持适应不同频率下的串口波特率设置.
//加入了对printf的支持
//增加了串口接收命令功能.
//修正了printf第一个字符丢失的bug
//V1.4修改说明
//1,修改串口初始化IO的bug
//2,修改了USART_RX_STA,使得串口最大接收字节数为2的14次方
//3,增加了USART_REC_LEN,用于定义串口最大允许接收的字节数(不大于2的14次方)
//4,修改了EN_USART1_RX的使能方式
//V1.5修改说明
//1,增加了对UCOSII的支持
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
//加入以下代码,支持printf函数,而不需要选择use MicroLIB
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
int _sys_exit(int x)
{
x = x;
return 0;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
unsigned int i=0xFFFF;
while(((USART1->SR&0X40)==0)&&(i--));//循环发送,直到发送完毕
USART1->DR = (u8) ch;
return ch;
}
#endif
#ifndef IAP_BOOTLOADER
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误
void USART1_DMA_RxEnable(void);
__align(32) u8 USART1_RX_BUF[USART1_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节【应小于0x3FFF即16383】.
u16 USART1_RX_STA=0; //接收状态标记
/*原子的旧定义,使用空闲中断后旧定义无效
//接收状态
//bit15, 接收完成标志
//bit14, 接收到0x0d
//bit13~0, 接收到的有效字节数目
*/
//bit15, 接收完成标志
//bit14, 缓冲区满标志
//bit13~0, 接收到的有效字节数目
//初始化IO 串口1
//bound:波特率
void USART1_init(u32 bound)
{
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1时钟
//串口1对应引脚复用映射
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //GPIOA9复用为USART1
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //GPIOA10复用为USART1
//USART1端口配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //GPIOA9与GPIOA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA9,PA10
//USART1 初始化设置
USART_InitStructure.USART_BaudRate = bound;//波特率设置
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(USART1, &USART_InitStructure); //初始化串口1
USART_ClearFlag(USART1, USART_FLAG_TC);
#if !EN_USART1_DMA
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启相关中断
#endif
USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//存在BUG,当写为USART_IT_RXNE|USART_IT_IDLE无法打开IDLE中断
//应当是因为USART有CR1-3三个寄存器,由于或运算结果不同于原参数,故库函数默认写入CR3,详见源代码
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority =1; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器、
#if EN_USART1_DMA
USART1_DMA_Init();
USART1_DMA_RxEnable();
#endif
USART_Cmd(USART1, ENABLE); //使能串口1
}
#if EN_USART1_DMA
//RX的DMA常开,中断中处理;TX的在需要时调用USART1_DMA_TxSingle()
//DMA2_Stream7_CHANNEL4->USART1_TX,DMA2_Stream2_CHANNEL4->USART1_RX
void USART1_DMA_Init(void)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//DMA2时钟使能
DMA_DeInit(DMA2_Stream7);
while (DMA_GetCmdStatus(DMA2_Stream7) != DISABLE){}//等待DMA可配置
DMA_DeInit(DMA2_Stream2);
while (DMA_GetCmdStatus(DMA2_Stream2) != DISABLE){}//等待DMA可配置
/* 配置 DMA Stream */
DMA_InitStructure.DMA_Channel = DMA_Channel_4; //通道选择
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;//DMA外设地址
DMA_InitStructure.DMA_Memory0BaseAddr = NULL;//DMA 存储器0地址
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;//存储器到外设模式
DMA_InitStructure.DMA_BufferSize = 0;//数据传输量
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_FIFOMode = DMA_FIFOMode_Enable;//开FIFO
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//存储器突发单次传输
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//外设突发单次传输
DMA_Init(DMA2_Stream7, &DMA_InitStructure);//初始化DMA Stream
/* 配置 DMA Stream */
DMA_InitStructure.DMA_Channel = DMA_Channel_4; //通道选择
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;//DMA外设地址
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)USART1_RX_BUF;//DMA 存储器0地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;//存储器到外设模式
DMA_InitStructure.DMA_BufferSize = USART1_REC_LEN;//数据传输量
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_FIFOMode = DMA_FIFOMode_Disable;//开FIFO
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//存储器突发单次传输
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//外设突发单次传输
DMA_Init(DMA2_Stream2, &DMA_InitStructure);//初始化DMA Stream
USART_DMACmd(USART1,USART_DMAReq_Tx|USART_DMAReq_Rx,ENABLE);
}
void USART1_DMA_TxSingle(uint8_t *buffer,uint16_t len_byte)
{
if( (DMA2_Stream7->CR&(uint32_t)DMA_SxCR_EN)!=0 )//已经使能
while(! DMA_GetFlagStatus(DMA2_Stream7,DMA_FLAG_TCIF7)); //等待DMA通道传输完成
DMA_Cmd(DMA2_Stream7,DISABLE); //使DMA通道停止工作
DMA_ClearFlag(DMA2_Stream7,DMA_FLAG_TCIF7); //清除通道传输完成状态标记
DMA2_Stream7->NDTR=len_byte; //设置要传输的数据长度
DMA2_Stream7->M0AR=(uint32_t)buffer; //设置RAM缓冲区地址
DMA_Cmd(DMA2_Stream7,ENABLE); //启动DMA传输
}
void USART1_DMA_RxEnable(void)
{
// 空闲中断不需要等待接收完成
// if( (DMA2_Stream2->CR&(uint32_t)DMA_SxCR_EN)!=0 )//已经使能
// while(! DMA_GetFlagStatus(DMA2_Stream2,DMA_FLAG_TCIF2)); //等待DMA通道传输完成
DMA_Cmd(DMA2_Stream2,DISABLE); //使DMA通道停止工作,【必须在进行配置之前关闭DMA】
DMA_ClearFlag(DMA2_Stream2,DMA_LISR_TCIF2); //清除通道传输完成状态标记
DMA2_Stream2->NDTR=USART1_REC_LEN; //设置要传输的数据长度
DMA2_Stream2->M0AR=(uint32_t)USART1_RX_BUF; //设置RAM缓冲区地址
DMA_Cmd(DMA2_Stream2,ENABLE); //启动DMA传输
}
void USART1_DMA_RxISR(void)
{
#ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.
OSIntEnter();
#endif
if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) //空闲总线中断
{
uint16_t RxLen;
USART1->SR;USART1->DR;//读SR再读DR清除USART_IT_IDLE位
RxLen=USART1_REC_LEN-DMA_GetCurrDataCounter(DMA2_Stream2);//接收数目,超出USART1_REC_LEN将被截断
USART1_RX_STA=0x8000|RxLen;
if(DMA_GetFlagStatus(DMA2_Stream2,DMA_FLAG_TCIF2))//溢出
USART1_RX_STA|=0x4000;
USART1_RX_BUF[RxLen]=' ';
USART1_DMA_RxEnable();
}
#ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.
OSIntExit();
#endif
}
#endif
//TX-PC12,RX-PD2
void uart5_init(u32 bound)
{
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOD,ENABLE); //使能GPIOA时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5,ENABLE);//使能USART1时钟
//串口1对应引脚复用映射
GPIO_PinAFConfig(GPIOC,GPIO_PinSource12,GPIO_AF_UART5); //GPIOA9复用为USART1
GPIO_PinAFConfig(GPIOD,GPIO_PinSource2,GPIO_AF_UART5); //GPIOA10复用为USART1
//TX-PC12,RX-PD2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 ; //GPIOA9与GPIOA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOC,&GPIO_InitStructure); //初始化PA9,PA10
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 ; //GPIOA9与GPIOA10
GPIO_Init(GPIOD,&GPIO_InitStructure); //初始化PA9,PA10
//USART1 初始化设置
USART_InitStructure.USART_BaudRate = bound;//波特率设置
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(UART5, &USART_InitStructure); //初始化串口1
USART_Cmd(UART5, ENABLE); //使能串口1
USART_ClearFlag(UART5, USART_FLAG_TC);
USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);//开启相关中断
USART_ITConfig(UART5, USART_IT_IDLE, ENABLE);//存在BUG,当写为USART_IT_RXNE|USART_IT_IDLE无法打开IDLE中断
//应当是因为USART有CR1-3三个寄存器,由于或运算结果不同于原参数,故库函数默认写入CR3,详见源代码
//UART5 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;//串口1中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority =1; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
}
u32 NOW_RX_LEN=0;
u8 USART_RXNE_Func=0x1;
void USART1_IRQHandler(void) //串口1中断服务程序(使用USART_IT_IDLE中断)
{
#if EN_USART1_DMA
USART1_DMA_RxISR();
#else
u16 len=USART1_RX_LEN;//已接收长度
#ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.
OSIntEnter();
#endif
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断
{
USART1_RX_BUF[len]=(uint16_t)(USART1->DR & (uint16_t)0x01FF);//(USART1->DR); //读取接收到的数据
USART1_RX_STA++;
len++;
if(len>=USART1_REC_LEN)//缓冲区溢出
{
USART1_RX_STA|=0x4000;
USART_RxOverflow_Handle();
}
}
if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) //空闲总线中断
{
USART1->SR;
USART1->DR;//读SR再读DR清除USART_IT_IDLE位
if( (USART1_RX_BUF[len-2]==0x0D) && (USART1_RX_BUF[len-1]==0x0A) )//接收到的数据必须是0x0d 0x0a结尾
{
USART1_RX_BUF[len-2]=0;USART1_RX_BUF[len-1]=0;
USART1_RX_STA-=2;
USART1_RX_STA|=0x8000;
}
else USART1_RX_STA=0;
}
#ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.
OSIntExit();
#endif
#endif
}
#if !EN_USART1_DMA
void USART_RxOverflow_Handle(void)
{
//.............自定义缓冲区溢出处理程序................
USART1_RX_STA|=0x8000;
USART1_RX_STA&=0xC000;
//.............
}
#endif
//extern OS_Q osq_uart5;
u8 UART5_RX_BUF[64]; //接收缓冲,最大USART_REC_LEN个字节【应小于0x3FFF即16383】.
u16 UART5_RX_STA=0; //接收状态标记
void UART5_IRQHandler(void) //串口1中断服务程序(使用USART_IT_IDLE中断)
{
u16 len=UART5_RX_LEN;//已接收长度
#ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.
OSIntEnter();
#endif
if(USART_GetITStatus(UART5, USART_IT_RXNE) != RESET) //接收中断
{
UART5_RX_BUF[len]=(uint16_t)(UART5->DR & (uint16_t)0x01FF);//(UART5->DR); //读取接收到的数据
// USART_SendData(USART1,UART5_RX_BUF[len]);
UART5_RX_STA++;
len++;
if(len>=USART1_REC_LEN)//缓冲区溢出
{
UART5_RX_STA|=0x4000;
UART5_RX_STA|=0x8000;
UART5_RX_STA&=0xC000;
}
}
if(USART_GetITStatus(UART5, USART_IT_IDLE) != RESET) //空闲总线中断
{
UART5->SR;
UART5->DR;//读SR再读DR清除USART_IT_IDLE位
if( (UART5_RX_BUF[len-2]==0x0D) && (UART5_RX_BUF[len-1]==0x0A) )//接收到的数据必须是0x0d 0x0a结尾
{
// OS_ERR err;
UART5_RX_BUF[len-2]=0;UART5_RX_BUF[len-1]=0;
// UART5_RX_STA-=2;
// UART5_RX_STA|=0x8000;
UART5_RX_STA=0;//使用操作系统,不需要查询方式检查传输完成
// OSQPost(&osq_uart5,UART5_RX_BUF,len,OS_OPT_POST_FIFO + OS_OPT_POST_ALL,&err);
}
else UART5_RX_STA=0;
}
#ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.
OSIntExit();
#endif
}
//==============================【bootloader】==============================
#else
void uart_init(u32 bound){
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1时钟
//串口1对应引脚复用映射
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //GPIOA9复用为USART1
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //GPIOA10复用为USART1
//USART1端口配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //GPIOA9与GPIOA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA9,PA10
//USART1 初始化设置
USART_InitStructure.USART_BaudRate = bound;//波特率设置
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(USART1, &USART_InitStructure); //初始化串口1
USART_Cmd(USART1, ENABLE); //使能串口1
USART_ClearFlag(USART1, USART_FLAG_TC);
#if EN_USART1_RX
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启相关中断
USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//存在BUG,当写为USART_IT_RXNE|USART_IT_IDLE无法打开IDLE中断
//应当是因为USART有CR1-3三个寄存器,由于或运算结果不同于原参数,故库函数默认写入CR3,详见源代码
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//【bootloader则设定为最高优先级】
NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器、
#endif
}
#include "protocol.h"
#include "check.h"
#include "stm32f429i_discovery_lcd.h"
#define USART_RX_BUF_SIZE (0x800)
extern TransportProtocol_Typedef TransportProtocol;
u32 TOTAL_RX_LEN=0,FRAME_RX_LEN=0;
u8 USART_RX_BUF[USART_RX_BUF_SIZE];
extern u8 flag;
//u8 p_IAP_APP_BASE[1];
//u8 p_IAP_APP_BASE[IAP_BOOTLOADER_SIZE] __attribute__((at(0x20000000+0x10000)));
u8 p_IAP_APP_BASE[IAP_BOOTLOADER_SIZE] __attribute__((at(0x90000000+0xA0000)));
u8 *p_IAP_COPY=(u8*)(&p_IAP_APP_BASE);
//extern u8 *p_IAP_APP_BASE;//前0x50000*2留给LTDC
void USART1_IRQHandler(void) //串口1中断服务程序(使用USART_IT_IDLE中断)
{
u32 Temp_Clear_IDLE;//用于清除USART_IT_IDLE
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断
{
if(FRAME_RX_LEN<=USART_RX_BUF_SIZE)
{
USART_RX_BUF[FRAME_RX_LEN]=(uint8_t)(USART1->DR & (uint16_t)0x01FF);//读取接收到的数据
FRAME_RX_LEN++;
// TOTAL_RX_LEN++;
}
else
printf(" .n[ERROR]This frame is too long! ");
}
if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) //空闲总线中断
{
Temp_Clear_IDLE=USART1->SR;
Temp_Clear_IDLE=USART1->DR;//读SR再读DR清除USART_IT_IDLE位
//获取接收的总字节数
TransportProtocol_Manager.RecieveByteCount = FRAME_RX_LEN;
//解包失败
if(TransportProtocol_Manager.Unpacked()!=UPACKED_SUCCESS)
LCD_ShowString(30,80,"Unpacked Fail!");
else//解包成功
{
uint32_t i=0;
// LCD_ShowString(30,80,"Unpacked OK! ");
TOTAL_RX_LEN+=TransportProtocol.Data_Length;
for(i=0;i<TransportProtocol.Data_Length;i++)//写入
*p_IAP_COPY++=TransportProtocol_Manager.Buf[4+i];
TransportProtocol.Device_Address = 0x01; //设备地址
TransportProtocol.Function_Type = 0x01; //帧功能
TransportProtocol.Sequence = TransportProtocol.Sequence; //帧序列
TransportProtocol.Data_Length = 4; //有效数据大小
TransportProtocol.Data = (u8*)(&TOTAL_RX_LEN); //要发送的数据
TransportProtocol_Manager.Packed(); //打包
for(i=0;i<TransportProtocol_Manager.FrameTotalLength;i++)
{
while(((USART1->SR&0X40)==0));//循环发送,直到发送完毕
USART1->DR = (u8)TransportProtocol_Manager.Buf
;
}
}
FRAME_RX_LEN=0;
// flag=1;
}
/* if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断
{
p_IAP_APP_BASE[NOW_RX_LEN]=(uint8_t)(USART1->DR & (uint16_t)0x01FF);//(USART1->DR); //读取接收到的数据
NOW_RX_LEN++;
}
if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) //空闲总线中断
{
Temp_Clear_IDLE=USART1->SR;
Temp_Clear_IDLE=USART1->DR;//读SR再读DR清除USART_IT_IDLE位
//跳转到APP.
flag=1;
}
*/
}
#endif
[/mw_shl_code]
加载中...
查看其它6个回答
一周热门
更多
>
相关问题
STM32F4上I2C(在PROTEUS中模拟)调试不通的问题
6 个回答
芯片供应紧张,准备换个MCU,MM32L系列替换STM32L系列的怎么样?
7 个回答
STM32同时使用两个串口进行数据收发时数据丢包的问题
5 个回答
STM32F103串口通信死机问题
4 个回答
STM32WLE5CC连接SX1268在LoRa模式下能与 SX1278互通吗?
2 个回答
相关文章
ST公司第一款无线低功耗单片机模块有效提高物联网设计生产效率
0个评论
如何实现对单片机寄存器的访问
0个评论
通过USB用STM32片内自带Bootloader下载程序及注意事项
0个评论
欲练此功必先自宫之STM32汇编启动,放慢是为了更好的前行
0个评论
×
关闭
采纳回答
向帮助了您的知道网友说句感谢的话吧!
非常感谢!
确 认
×
关闭
编辑标签
最多设置5个标签!
STM32
保存
关闭
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
×
付费偷看金额在0.1-10元之间
确定
×
关闭
您已邀请
0
人回答
查看邀请
擅长该话题的人
回答过该话题的人
我关注的人
我手上只有我自己改过的程序,你不怕麻烦也可以看看
[mw_shl_code=c,true]#include "sys.h"
#include "usart.h"
//////////////////////////////////////////////////////////////////////////////////
//如果使用ucos,则包括下面的头文件即可.
#if SYSTEM_SUPPORT_UCOS
#include "includes.h" //ucos 使用
#endif
//////////////////////////////////////////////////////////////////////////////////
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32F4探索者开发板
//串口1初始化
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//修改日期:2014/6/10
//版本:V1.5
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2009-2019
//All rights reserved
//********************************************************************************
//V1.3修改说明
//支持适应不同频率下的串口波特率设置.
//加入了对printf的支持
//增加了串口接收命令功能.
//修正了printf第一个字符丢失的bug
//V1.4修改说明
//1,修改串口初始化IO的bug
//2,修改了USART_RX_STA,使得串口最大接收字节数为2的14次方
//3,增加了USART_REC_LEN,用于定义串口最大允许接收的字节数(不大于2的14次方)
//4,修改了EN_USART1_RX的使能方式
//V1.5修改说明
//1,增加了对UCOSII的支持
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
//加入以下代码,支持printf函数,而不需要选择use MicroLIB
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
int _sys_exit(int x)
{
x = x;
return 0;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
unsigned int i=0xFFFF;
while(((USART1->SR&0X40)==0)&&(i--));//循环发送,直到发送完毕
USART1->DR = (u8) ch;
return ch;
}
#endif
#ifndef IAP_BOOTLOADER
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误
void USART1_DMA_RxEnable(void);
__align(32) u8 USART1_RX_BUF[USART1_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节【应小于0x3FFF即16383】.
u16 USART1_RX_STA=0; //接收状态标记
/*原子的旧定义,使用空闲中断后旧定义无效
//接收状态
//bit15, 接收完成标志
//bit14, 接收到0x0d
//bit13~0, 接收到的有效字节数目
*/
//bit15, 接收完成标志
//bit14, 缓冲区满标志
//bit13~0, 接收到的有效字节数目
//初始化IO 串口1
//bound:波特率
void USART1_init(u32 bound)
{
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1时钟
//串口1对应引脚复用映射
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //GPIOA9复用为USART1
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //GPIOA10复用为USART1
//USART1端口配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //GPIOA9与GPIOA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA9,PA10
//USART1 初始化设置
USART_InitStructure.USART_BaudRate = bound;//波特率设置
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(USART1, &USART_InitStructure); //初始化串口1
USART_ClearFlag(USART1, USART_FLAG_TC);
#if !EN_USART1_DMA
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启相关中断
#endif
USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//存在BUG,当写为USART_IT_RXNE|USART_IT_IDLE无法打开IDLE中断
//应当是因为USART有CR1-3三个寄存器,由于或运算结果不同于原参数,故库函数默认写入CR3,详见源代码
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority =1; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器、
#if EN_USART1_DMA
USART1_DMA_Init();
USART1_DMA_RxEnable();
#endif
USART_Cmd(USART1, ENABLE); //使能串口1
}
#if EN_USART1_DMA
//RX的DMA常开,中断中处理;TX的在需要时调用USART1_DMA_TxSingle()
//DMA2_Stream7_CHANNEL4->USART1_TX,DMA2_Stream2_CHANNEL4->USART1_RX
void USART1_DMA_Init(void)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//DMA2时钟使能
DMA_DeInit(DMA2_Stream7);
while (DMA_GetCmdStatus(DMA2_Stream7) != DISABLE){}//等待DMA可配置
DMA_DeInit(DMA2_Stream2);
while (DMA_GetCmdStatus(DMA2_Stream2) != DISABLE){}//等待DMA可配置
/* 配置 DMA Stream */
DMA_InitStructure.DMA_Channel = DMA_Channel_4; //通道选择
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;//DMA外设地址
DMA_InitStructure.DMA_Memory0BaseAddr = NULL;//DMA 存储器0地址
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;//存储器到外设模式
DMA_InitStructure.DMA_BufferSize = 0;//数据传输量
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_FIFOMode = DMA_FIFOMode_Enable;//开FIFO
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//存储器突发单次传输
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//外设突发单次传输
DMA_Init(DMA2_Stream7, &DMA_InitStructure);//初始化DMA Stream
/* 配置 DMA Stream */
DMA_InitStructure.DMA_Channel = DMA_Channel_4; //通道选择
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;//DMA外设地址
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)USART1_RX_BUF;//DMA 存储器0地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;//存储器到外设模式
DMA_InitStructure.DMA_BufferSize = USART1_REC_LEN;//数据传输量
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_FIFOMode = DMA_FIFOMode_Disable;//开FIFO
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//存储器突发单次传输
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//外设突发单次传输
DMA_Init(DMA2_Stream2, &DMA_InitStructure);//初始化DMA Stream
USART_DMACmd(USART1,USART_DMAReq_Tx|USART_DMAReq_Rx,ENABLE);
}
void USART1_DMA_TxSingle(uint8_t *buffer,uint16_t len_byte)
{
if( (DMA2_Stream7->CR&(uint32_t)DMA_SxCR_EN)!=0 )//已经使能
while(! DMA_GetFlagStatus(DMA2_Stream7,DMA_FLAG_TCIF7)); //等待DMA通道传输完成
DMA_Cmd(DMA2_Stream7,DISABLE); //使DMA通道停止工作
DMA_ClearFlag(DMA2_Stream7,DMA_FLAG_TCIF7); //清除通道传输完成状态标记
DMA2_Stream7->NDTR=len_byte; //设置要传输的数据长度
DMA2_Stream7->M0AR=(uint32_t)buffer; //设置RAM缓冲区地址
DMA_Cmd(DMA2_Stream7,ENABLE); //启动DMA传输
}
void USART1_DMA_RxEnable(void)
{
// 空闲中断不需要等待接收完成
// if( (DMA2_Stream2->CR&(uint32_t)DMA_SxCR_EN)!=0 )//已经使能
// while(! DMA_GetFlagStatus(DMA2_Stream2,DMA_FLAG_TCIF2)); //等待DMA通道传输完成
DMA_Cmd(DMA2_Stream2,DISABLE); //使DMA通道停止工作,【必须在进行配置之前关闭DMA】
DMA_ClearFlag(DMA2_Stream2,DMA_LISR_TCIF2); //清除通道传输完成状态标记
DMA2_Stream2->NDTR=USART1_REC_LEN; //设置要传输的数据长度
DMA2_Stream2->M0AR=(uint32_t)USART1_RX_BUF; //设置RAM缓冲区地址
DMA_Cmd(DMA2_Stream2,ENABLE); //启动DMA传输
}
void USART1_DMA_RxISR(void)
{
#ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.
OSIntEnter();
#endif
if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) //空闲总线中断
{
uint16_t RxLen;
USART1->SR;USART1->DR;//读SR再读DR清除USART_IT_IDLE位
RxLen=USART1_REC_LEN-DMA_GetCurrDataCounter(DMA2_Stream2);//接收数目,超出USART1_REC_LEN将被截断
USART1_RX_STA=0x8000|RxLen;
if(DMA_GetFlagStatus(DMA2_Stream2,DMA_FLAG_TCIF2))//溢出
USART1_RX_STA|=0x4000;
USART1_RX_BUF[RxLen]=' ';
USART1_DMA_RxEnable();
}
#ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.
OSIntExit();
#endif
}
#endif
//TX-PC12,RX-PD2
void uart5_init(u32 bound)
{
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOD,ENABLE); //使能GPIOA时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5,ENABLE);//使能USART1时钟
//串口1对应引脚复用映射
GPIO_PinAFConfig(GPIOC,GPIO_PinSource12,GPIO_AF_UART5); //GPIOA9复用为USART1
GPIO_PinAFConfig(GPIOD,GPIO_PinSource2,GPIO_AF_UART5); //GPIOA10复用为USART1
//TX-PC12,RX-PD2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 ; //GPIOA9与GPIOA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOC,&GPIO_InitStructure); //初始化PA9,PA10
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 ; //GPIOA9与GPIOA10
GPIO_Init(GPIOD,&GPIO_InitStructure); //初始化PA9,PA10
//USART1 初始化设置
USART_InitStructure.USART_BaudRate = bound;//波特率设置
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(UART5, &USART_InitStructure); //初始化串口1
USART_Cmd(UART5, ENABLE); //使能串口1
USART_ClearFlag(UART5, USART_FLAG_TC);
USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);//开启相关中断
USART_ITConfig(UART5, USART_IT_IDLE, ENABLE);//存在BUG,当写为USART_IT_RXNE|USART_IT_IDLE无法打开IDLE中断
//应当是因为USART有CR1-3三个寄存器,由于或运算结果不同于原参数,故库函数默认写入CR3,详见源代码
//UART5 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;//串口1中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority =1; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
}
u32 NOW_RX_LEN=0;
u8 USART_RXNE_Func=0x1;
void USART1_IRQHandler(void) //串口1中断服务程序(使用USART_IT_IDLE中断)
{
#if EN_USART1_DMA
USART1_DMA_RxISR();
#else
u16 len=USART1_RX_LEN;//已接收长度
#ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.
OSIntEnter();
#endif
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断
{
USART1_RX_BUF[len]=(uint16_t)(USART1->DR & (uint16_t)0x01FF);//(USART1->DR); //读取接收到的数据
USART1_RX_STA++;
len++;
if(len>=USART1_REC_LEN)//缓冲区溢出
{
USART1_RX_STA|=0x4000;
USART_RxOverflow_Handle();
}
}
if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) //空闲总线中断
{
USART1->SR;
USART1->DR;//读SR再读DR清除USART_IT_IDLE位
if( (USART1_RX_BUF[len-2]==0x0D) && (USART1_RX_BUF[len-1]==0x0A) )//接收到的数据必须是0x0d 0x0a结尾
{
USART1_RX_BUF[len-2]=0;USART1_RX_BUF[len-1]=0;
USART1_RX_STA-=2;
USART1_RX_STA|=0x8000;
}
else USART1_RX_STA=0;
}
#ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.
OSIntExit();
#endif
#endif
}
#if !EN_USART1_DMA
void USART_RxOverflow_Handle(void)
{
//.............自定义缓冲区溢出处理程序................
USART1_RX_STA|=0x8000;
USART1_RX_STA&=0xC000;
//.............
}
#endif
//extern OS_Q osq_uart5;
u8 UART5_RX_BUF[64]; //接收缓冲,最大USART_REC_LEN个字节【应小于0x3FFF即16383】.
u16 UART5_RX_STA=0; //接收状态标记
void UART5_IRQHandler(void) //串口1中断服务程序(使用USART_IT_IDLE中断)
{
u16 len=UART5_RX_LEN;//已接收长度
#ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.
OSIntEnter();
#endif
if(USART_GetITStatus(UART5, USART_IT_RXNE) != RESET) //接收中断
{
UART5_RX_BUF[len]=(uint16_t)(UART5->DR & (uint16_t)0x01FF);//(UART5->DR); //读取接收到的数据
// USART_SendData(USART1,UART5_RX_BUF[len]);
UART5_RX_STA++;
len++;
if(len>=USART1_REC_LEN)//缓冲区溢出
{
UART5_RX_STA|=0x4000;
UART5_RX_STA|=0x8000;
UART5_RX_STA&=0xC000;
}
}
if(USART_GetITStatus(UART5, USART_IT_IDLE) != RESET) //空闲总线中断
{
UART5->SR;
UART5->DR;//读SR再读DR清除USART_IT_IDLE位
if( (UART5_RX_BUF[len-2]==0x0D) && (UART5_RX_BUF[len-1]==0x0A) )//接收到的数据必须是0x0d 0x0a结尾
{
// OS_ERR err;
UART5_RX_BUF[len-2]=0;UART5_RX_BUF[len-1]=0;
// UART5_RX_STA-=2;
// UART5_RX_STA|=0x8000;
UART5_RX_STA=0;//使用操作系统,不需要查询方式检查传输完成
// OSQPost(&osq_uart5,UART5_RX_BUF,len,OS_OPT_POST_FIFO + OS_OPT_POST_ALL,&err);
}
else UART5_RX_STA=0;
}
#ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.
OSIntExit();
#endif
}
//==============================【bootloader】==============================
#else
void uart_init(u32 bound){
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1时钟
//串口1对应引脚复用映射
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //GPIOA9复用为USART1
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //GPIOA10复用为USART1
//USART1端口配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //GPIOA9与GPIOA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA9,PA10
//USART1 初始化设置
USART_InitStructure.USART_BaudRate = bound;//波特率设置
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(USART1, &USART_InitStructure); //初始化串口1
USART_Cmd(USART1, ENABLE); //使能串口1
USART_ClearFlag(USART1, USART_FLAG_TC);
#if EN_USART1_RX
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启相关中断
USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//存在BUG,当写为USART_IT_RXNE|USART_IT_IDLE无法打开IDLE中断
//应当是因为USART有CR1-3三个寄存器,由于或运算结果不同于原参数,故库函数默认写入CR3,详见源代码
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//【bootloader则设定为最高优先级】
NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器、
#endif
}
#include "protocol.h"
#include "check.h"
#include "stm32f429i_discovery_lcd.h"
#define USART_RX_BUF_SIZE (0x800)
extern TransportProtocol_Typedef TransportProtocol;
u32 TOTAL_RX_LEN=0,FRAME_RX_LEN=0;
u8 USART_RX_BUF[USART_RX_BUF_SIZE];
extern u8 flag;
//u8 p_IAP_APP_BASE[1];
//u8 p_IAP_APP_BASE[IAP_BOOTLOADER_SIZE] __attribute__((at(0x20000000+0x10000)));
u8 p_IAP_APP_BASE[IAP_BOOTLOADER_SIZE] __attribute__((at(0x90000000+0xA0000)));
u8 *p_IAP_COPY=(u8*)(&p_IAP_APP_BASE);
//extern u8 *p_IAP_APP_BASE;//前0x50000*2留给LTDC
void USART1_IRQHandler(void) //串口1中断服务程序(使用USART_IT_IDLE中断)
{
u32 Temp_Clear_IDLE;//用于清除USART_IT_IDLE
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断
{
if(FRAME_RX_LEN<=USART_RX_BUF_SIZE)
{
USART_RX_BUF[FRAME_RX_LEN]=(uint8_t)(USART1->DR & (uint16_t)0x01FF);//读取接收到的数据
FRAME_RX_LEN++;
// TOTAL_RX_LEN++;
}
else
printf(" .n[ERROR]This frame is too long! ");
}
if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) //空闲总线中断
{
Temp_Clear_IDLE=USART1->SR;
Temp_Clear_IDLE=USART1->DR;//读SR再读DR清除USART_IT_IDLE位
//获取接收的总字节数
TransportProtocol_Manager.RecieveByteCount = FRAME_RX_LEN;
//解包失败
if(TransportProtocol_Manager.Unpacked()!=UPACKED_SUCCESS)
LCD_ShowString(30,80,"Unpacked Fail!");
else//解包成功
{
uint32_t i=0;
// LCD_ShowString(30,80,"Unpacked OK! ");
TOTAL_RX_LEN+=TransportProtocol.Data_Length;
for(i=0;i<TransportProtocol.Data_Length;i++)//写入
*p_IAP_COPY++=TransportProtocol_Manager.Buf[4+i];
TransportProtocol.Device_Address = 0x01; //设备地址
TransportProtocol.Function_Type = 0x01; //帧功能
TransportProtocol.Sequence = TransportProtocol.Sequence; //帧序列
TransportProtocol.Data_Length = 4; //有效数据大小
TransportProtocol.Data = (u8*)(&TOTAL_RX_LEN); //要发送的数据
TransportProtocol_Manager.Packed(); //打包
for(i=0;i<TransportProtocol_Manager.FrameTotalLength;i++)
{
while(((USART1->SR&0X40)==0));//循环发送,直到发送完毕
USART1->DR = (u8)TransportProtocol_Manager.Buf;
}
}
FRAME_RX_LEN=0;
// flag=1;
}
/* if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断
{
p_IAP_APP_BASE[NOW_RX_LEN]=(uint8_t)(USART1->DR & (uint16_t)0x01FF);//(USART1->DR); //读取接收到的数据
NOW_RX_LEN++;
}
if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) //空闲总线中断
{
Temp_Clear_IDLE=USART1->SR;
Temp_Clear_IDLE=USART1->DR;//读SR再读DR清除USART_IT_IDLE位
//跳转到APP.
flag=1;
}
*/
}
#endif
[/mw_shl_code]
一周热门 更多>