千家信息网

STM32怎么用IO口模拟串口

发表于:2024-11-23 作者:千家信息网编辑
千家信息网最后更新 2024年11月23日,本篇文章为大家展示了STM32怎么用IO口模拟串口,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。PB12模拟TXD,PB13模拟RXD 发送时序比较单一,按时
千家信息网最后更新 2024年11月23日STM32怎么用IO口模拟串口

本篇文章为大家展示了STM32怎么用IO口模拟串口,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

PB12模拟TXD,PB13模拟RXD 发送时序比较单一,按时序图可很快实现。 接收比较复杂这里用定时器TM4的溢出中断和PB13的外部中断配合计算电平时间来获取串口数据。

#define BuadRate_9600 100u8 len = 0;      //接收计数u8 USART_buf[11];  //接收缓冲区#define OI_TXD     PBout(12)#define OI_RXD     PBin(13)enum{        COM_START_BIT,        COM_D0_BIT,        COM_D1_BIT,        COM_D2_BIT,        COM_D3_BIT,        COM_D4_BIT,        COM_D5_BIT,        COM_D6_BIT,        COM_D7_BIT,        COM_STOP_BIT,};u8 recvStat = COM_STOP_BIT;u8 recvData = 0;void rf315_IoConfig(){        GPIO_InitTypeDef  GPIO_InitStructure;        NVIC_InitTypeDef NVIC_InitStructure;   EXTI_InitTypeDef EXTI_InitStruct;  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOB, ENABLE);       //使能PB,PC端口时钟                   //SoftWare Serial TXD        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;              //推挽输出  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;          //IO口速度为50MHz        GPIO_Init(GPIOC, &GPIO_InitStructure);                                     GPIO_SetBits(GPIOB,GPIO_Pin_12);                                                                         //SoftWare Serial RXD        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 GPIO_Init(GPIOB, &GPIO_InitStructure);          GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource13);        EXTI_InitStruct.EXTI_Line = EXTI_Line13;        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= EXTI15_10_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 rf315_uart4Init(){        rf315_IoConfig();        TIM4_Int_Init(107, 71);     //1M计数频率}void rf315_SendChar(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 rf315_SendData(u8 *buf, u8 len){        u8 t;        for(t = 0; t < len; t++)        {                rf315_SendChar(buf[t]);        }}void EXTI15_10_IRQHandler(void){        if(EXTI_GetFlagStatus(EXTI_Line13) != RESET)        {                if(OI_RXD == 0)                 {                        if(recvStat == COM_STOP_BIT)                        {                                recvStat = COM_START_BIT;                                TIM_Cmd(TIM4, ENABLE);                        }                }                EXTI_ClearITPendingBit(EXTI_Line13);        }}u8 rf315_data_need_handler=0;void TIM4_IRQHandler(void){          if(TIM_GetFlagStatus(TIM4, TIM_FLAG_Update) != RESET)        {                TIM_ClearITPendingBit(TIM4, TIM_FLAG_Update);                       recvStat++;                if(recvStat == COM_STOP_BIT)                {                        TIM_Cmd(TIM4, DISABLE);                        USART_buf[len++] = recvData;                          /*数据协议尾*/                        if(USART_buf[len-1]==RF315_PROTOCOL_TAIL)                                rf315_data_need_handler=1;                        return;                }                if(OI_RXD)                {                        recvData |= (1 << (recvStat - 1));                }else{                        recvData &= ~(1 << (recvStat - 1));                }         }           }

上述内容就是STM32怎么用IO口模拟串口,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注行业资讯频道。

0