中级会员
 
- 积分
- 203
- 金钱
- 203
- 注册时间
- 2022-10-24
- 在线时间
- 39 小时
|
5金钱
本帖最后由 willie1040 于 2023-3-29 09:08 编辑
之前做的项目用的STM32F412RET,现在升级使用STM32F412VGT6。之前RET用的串口1 、2、6 都没有问题。VGT6新增了串口3,初始化什么的,都是跟之前其他串口差不多。现在是一初始化串口3,整个程序编译没有错,烧录就运行不了了。把串口3初始化函数注释掉,其他功能就能正常运行,求大神解救一下~~~
串口3的相关函数如下:
void Init_USART3(uint32_t baud)
{
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
//1.串口时钟和和GPIO时钟使能。
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE); //使能GPIOD时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);//使能USART3时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
//2.设置引脚复用器映射
GPIO_PinAFConfig(GPIOD,GPIO_PinSource8,GPIO_AF_USART3); //GPIOB10复用为USART6
GPIO_PinAFConfig(GPIOD,GPIO_PinSource9,GPIO_AF_USART3); //GPIOB11复用为USART6
//3.GPIO端口模式设置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; //
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(GPIOD,&GPIO_InitStructure); //初始化GPIOB10,和GPIOB11
//4.串口参数初始化:设置波特率,字长,奇偶校验等参数
USART_InitStructure.USART_BaudRate = baud;//波特率一般设置为9600;
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(USART3, &USART_InitStructure); //初始化串口2参数
//5.初始化NVIC
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn ;//串口3中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//抢占优先级0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
//6.开启中断
USART_ITConfig(USART3, USART_IT_TC, ENABLE);//开启发送中断
//USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);//开启空闲中断
//7.使能串口
USART_Cmd(USART3, ENABLE); //使能串口
/* DMA2 Channel5 (串口6 TX) Config */
DMA_Cmd(DMA1_Stream3, DISABLE);
DMA_DeInit(DMA1_Stream3);
while (DMA_GetCmdStatus(DMA1_Stream3) != DISABLE){}//等待DMA可设置
DMA_InitStructure.DMA_Channel = DMA_Channel_4; //恢复缺省值
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(USART3->DR)); //源 设置串口发送数据寄存器
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)USART3_SEND_DATA; //目的 设置发送缓冲区首地址
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; //设置外设位目标,内存缓冲区-->外部寄存器
DMA_InitStructure.DMA_BufferSize = UART3_TX_LEN; //需要发送的字节数,这里其实可以设置为0,因为在实际要发送的时候,会重新设置次值
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址不做增加调整,调整不调整是DMA自动实现的
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存缓冲地址增加调整
DMA_InitStructure.DMA_PeripheralDataSize = DMA_MemoryDataSize_Byte; //外设数据宽度8位,1个字节
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //内存数据宽度8位,1个字节
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //DMA工作模式 单次传输模式
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //优先级设置
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; /* FIFO模式 */
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; /* FIFO大小 */
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; /* 储存器突发传输*/
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; /*外设突发传输*/
DMA_Init(DMA1_Stream3, &DMA_InitStructure); //写入配置
/*Enable DMA Channel5 Interrupt DMA_TX1 */
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//DMA中断设置
DMA_ITConfig(DMA1_Stream3, DMA_IT_TC, ENABLE); //启动发送DMA通道中断
/* Enable USART6 DMA TX request */
USART_DMACmd(USART3, USART_DMAReq_Tx, ENABLE); //使能串口DMA发送
/* DMA2 Channel5 (串口6 RX) Config */
DMA_Cmd(DMA1_Stream1, DISABLE); //关闭DMA接收
DMA_DeInit(DMA1_Stream1);
while (DMA_GetCmdStatus(DMA1_Stream1) != DISABLE); //等待DMA可设置
DMA_InitStructure.DMA_Channel = DMA_Channel_4; //通道选择
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART3->DR; //DMA外设地址
DMA_InitStructure.DMA_Memory0BaseAddr = (u32)USART3_RECEIVE_DATA; //DMA 储存0地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory ; //储存器到外设
DMA_InitStructure.DMA_BufferSize = UART3_RX_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;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; // 储存器突发传输
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //外设突发传输
DMA_Init(DMA1_Stream1, &DMA_InitStructure);//
/*Enable DMA Channel5 Interrupt DMA_RX1*/
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable USART6 DMA RX request */
USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE); //使能串口DMA接收
DMA_Cmd(DMA1_Stream1, ENABLE); //使能DMA14接收通道
}
///////////////////////////////////////////////////////////////////////////
//DMA 发送完成总断
void DMA1_Stream3_IRQHandler(void)
{
if(DMA_GetFlagStatus(DMA1_Stream3,DMA_FLAG_TCIF3)!=RESET)
{
DMA_ClearFlag(DMA1_Stream3,DMA_FLAG_TCIF3);
}
}
//DMA接收总断服务函数,未开启
void DMA1_Stream1_IRQHandler(void)
{
if(DMA_GetFlagStatus(DMA1_Stream1,DMA_FLAG_TCIF1)!=RESET)
{
DMA_ClearFlag(DMA1_Stream1,DMA_FLAG_TCIF1);
}
DMA_Cmd(DMA1_Stream1, DISABLE);
DMA_ClearFlag(DMA1_Stream1,DMA_FLAG_TCIF1 | DMA_FLAG_FEIF1 | DMA_FLAG_DMEIF1 | DMA_FLAG_TEIF1 | DMA_FLAG_HTIF1);
DMA_SetCurrDataCounter(DMA1_Stream1, UART3_RX_LEN);
DMA_Cmd(DMA1_Stream1, ENABLE);
}
//USART3中断服务函数
void USART3_IRQHandler(void)//USART3_IRQHandler
{
u16 data;
if(USART_GetITStatus(USART3, USART_IT_TC) != RESET )
{
USART_ClearFlag(USART3, USART_FLAG_TC);
// RS485_R;
}
if(USART_GetITStatus(USART3,USART_IT_IDLE) != RESET)
{
DMA_Cmd(DMA1_Stream1, DISABLE);
Uart3_DMA_Rx_Data();
}
data = USART3->SR;
data = USART3->DR;
data=data;
DMA_ClearFlag(DMA1_Stream1,DMA_FLAG_TCIF1 | DMA_FLAG_FEIF1 | DMA_FLAG_DMEIF1 | DMA_FLAG_TEIF1 | DMA_FLAG_HTIF1);
DMA_SetCurrDataCounter(DMA1_Stream1, UART3_RX_LEN);
DMA_Cmd(DMA1_Stream1, ENABLE);
USART_ClearITPendingBit(USART3, USART_IT_IDLE);
}
void Uart3_DMA_Rx_Data(void)
{
//u16 CRC_Data;
u16 DATA_LEN=0;
u16 i;
DATA_LEN =UART3_RX_LEN - DMA_GetCurrDataCounter(DMA1_Stream1);
//收到指令数据
if((USART3_RECEIVE_DATA[0]==0xFB)&&(USART3_RECEIVE_DATA[1]==0xFB)&&(USART3_RECEIVE_DATA[2]==0xFB)&&(USART3_RECEIVE_DATA[5]==0x01))
{
for(i=0;i<DATA_LEN;i++)
{
Cmd_Data.cmd_data_rec=USART3_RECEIVE_DATA;
}
//memset(USART6_RECEIVE_DATA,0,DATA_LEN);
/*if((USART6_RECEIVE_DATA[4]==0x01)&&(USART6_RECEIVE_DATA[5]==0x03))//当前为轮灌页面
Cmd_Data.cmd_data_rec[4]=CMD_READ_PROGRAM;*/
Cmd_Data.Uart6_get_cmd=1;
}
//轮灌程序页面
/*if((USART6_RECEIVE_DATA[0]==0xEE)&&(USART6_RECEIVE_DATA[1]==0xB1)&&(USART6_RECEIVE_DATA[2]==0x01)&&(USART6_RECEIVE_DATA[3]==0x00))
{
if(USART6_RECEIVE_DATA[4]==0x03)//轮灌页面
Cmd_Data.cmd_type=CMD_READ_PROGRAM;
if(USART6_RECEIVE_DATA[4]==0x00) //首页
Cmd_Data.cmd_type=CMD_UPDATE_VAVLE_TIME1;
if(USART6_RECEIVE_DATA[4]==0x01)//第二页
Cmd_Data.cmd_type=CMD_UPDATE_VAVLE_TIME2;
Cmd_Data.Uart6_get_cmd=1;
}*/
}
void Uart3_DMA_Tx_Data(u32 len,u8* raed)
{
u32 i;
for(i=0;i<len;i++)USART3_SEND_DATA=raed;
// RS485_T;
DMA_Cmd(DMA1_Stream3, DISABLE);
DMA1_Stream3->NDTR=len; //DMA1,传输数据
DMA_Cmd(DMA1_Stream3, ENABLE);
}
|
|