STM32的IO模拟串口
文章目录- 一、为什么要用STM32的普通IO口模拟串口?
- 二、参考程序
- 总结
随着工程的增大,开发者们可能在一开始不能完全利用好STM32的资源,造成串口资源不足。例如:STM32F103C8T6只有3个串口,在不改动硬件资源的情况下,因此只能想到用IO口模拟串口的时序。
二、参考程序代码如下(示例):
IO2USART.c
#include "IO2USART.h" #define BuadRate_9600 104 u8 len = 0; //接收计数 u8 USART_buf[11]; //接收缓冲区 u8 recvStat = COM_STOP_BIT; u8 recvData = 0; void IO_TXD(u8 Data) { u8 i = 0; OI_TXD = 0; delay_us(BuadRate_9600); for(i = 0; i < 8; i++) { if(Data&0x01) OI_TXD = 1; else OI_TXD = 0; delay_us(BuadRate_9600); Data = Data>>1; } OI_TXD = 1; delay_us(BuadRate_9600); } void USART_Send(u8 *buf, u8 len) { u8 t; for(t = 0; t < len; t++) { IO_TXD(buf[t]); } } void IOConfig(void) { GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; EXTI_InitTypeDef EXTI_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOB, ENABLE); //使能PB,PC端口时钟 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); //SoftWare Serial TXD GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_SetBits(GPIOB,GPIO_Pin_4); //SoftWare Serial RXD GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource5); EXTI_InitStruct.EXTI_Line = EXTI_Line5; EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt; EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling; //下降沿触发中断 EXTI_InitStruct.EXTI_LineCmd=ENABLE; EXTI_Init(&EXTI_InitStruct); NVIC_InitStructure.NVIC_IRQChannel= EXTI9_5_IRQn ; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2; NVIC_InitStructure.NVIC_IRQChannelSubPriority =2; NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_InitStructure); } void TIM4_Int_Init(u16 arr,u16 psc) { TIM_TimebaseInitTypeDef TIM_TimebaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //时钟使能 //定时器TIM4初始化 TIM_TimebaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 TIM_TimebaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 TIM_TimebaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim TIM_TimebaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 TIM_TimebaseInit(TIM4, &TIM_TimebaseStructure); //根据指定的参数初始化TIMx的时间基数单位 TIM_ClearITPendingBit(TIM4, TIM_FLAG_Update); TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断 //中断优先级NVIC设置 NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; //TIM4中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //先占优先级1级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //从优先级1级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能 NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器 } void EXTI9_5_IRQHandler(void) { if(EXTI_GetFlagStatus(EXTI_Line5) != RESET) { if(OI_RXD == 0) { if(recvStat == COM_STOP_BIT) { recvStat = COM_START_BIT; TIM_Cmd(TIM4, ENABLE); } } EXTI_ClearITPendingBit(EXTI_Line5); } }总结
提示:亲测稳定运行,需要完整工程联系QQ:2858054751
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)