stm32F407ZGT6端口复用

串口1的发送接收引脚是PA9,PA10。当我们把PA9,PA10不用做GPIO,而用做复用功能串口1的发送接收引脚的时候,叫端口复用。

串口2:PA2,PA3

注意,一组串口,不一定只有一组引脚。如:USART2_RX串口2除了PA2,PA3。PD6,PD5也有USART2_RX的功能。

	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

//串口1对应引脚复用映射
    GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //GPIOA9复用为USART1
    GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //GPIOA10复用为USART1。注意这个函数GPIO_PinAFConfig()是复用关键。

当我们需要找该开发板芯片的哪个引脚功能时,需要看芯片手册,注意不是开发手册,开发指南这种,一般是全英的芯片手册,里面只表述芯片的所有信息,并不会表述你买开发板的其他信息,如各种外设等,这是不会提及的。不要看错,打开错芯片手册。(STM32F407ZGT6,STMF4xx中文参考手册)

### STM32F407ZGT6 UART 复用配置与实现 对于STM32F407ZGT6微控制器而言,UART接口可以被灵活配置用于多种通信需求。为了实现多个外设共享同一个UART硬件资源,通常采用软件控制的多路复用技术。 #### 配置GPIO引作为UART功能 在STM32系列MCU中,每个USART模块都有固定的RX/TX管映射到不同的端口上。要启用特定的USART通道并将其分配给相应的物理引,需通过修改`RCC_APB2PeriphClockCmd()`函数来开启对应的时钟源,并调用`GPIO_Init()`设置这些引的工作模式为交替功能推挽输出[^1]。 ```c // 开启USART1及相关GPIO时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); // USART1_TX(PA9), USART1_RX(PA10)初始化结构体定义 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; // TX Pin GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); ``` #### 实现基于DMA的数据传输 当涉及到高频率数据交换时,直接轮询方式会占用大量CPU时间。因此推荐利用DMA(Direct Memory Access)机制完成自动化的数据读写操作。这不仅提高了效率还降低了功耗。具体来说,在发送前先装载好待传缓冲区地址至DMA寄存器;接收则相反,预先指定目标存储位置等待新到来的信息填充。 ```c // 启动DMA发送 void StartDMATransmit(uint8_t* buffer, uint16_t length){ DMA_DeInit(DMA1_Channel4); DMA_InitTypeDef DMA_InitStruct; DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR); DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)buffer; DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStruct.DMA_BufferSize = length; DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStruct.DMA_Mode = DMA_Mode_Normal; DMA_InitStruct.DMA_Priority = DMA_Priority_High; DMA_InitStruct.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel4,&DMA_InitStruct); DMA_Cmd(DMA1_Channel4,ENABLE); } ``` #### 使用中断处理程序管理不同设备间的切换 考虑到实际应用场景下可能存在的并发访问冲突问题,建议引入中断驱动的方法来进行有效的状态管理和调度逻辑设计。每当检测到有新的请求到达时触发相应事件处理器,从而动态调整当前活动链路上的任务优先级或执行必要的参数重载动作。 ```c // 中断服务例程模板 void USART1_IRQHandler(void){ if(USART_GetITStatus(USART1, USART_IT_IDLE)){ // IDLE线检测到停止位后的响应措施... // 清除标志位 USART_ClearITPendingBit(USART1, USART_IT_IDLE); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值