单片机 > 单片机程序设计 > 详情

STM32F407Z 模拟串口(115200波特率)

发布时间:2020-06-16 发布时间:
|

PCB板打样回来发现串口1 TXD 和RXD 与CH340的TXD RXD没有交叉相连,导致串口1无法使用,于是将错就错,采用模拟串口的方式弥补了这个错误。波特率可达115200,支持printf函数。


#include "sys.h"

#include "delay.h"

#include "led.h"

#include "stdio.h"

 

#define TX_L() GPIO_ResetBits(GPIOA, GPIO_Pin_10)

#define TX_H() GPIO_SetBits(GPIOA, GPIO_Pin_10)

#define RX_READ() (GPIOA->IDR & GPIO_Pin_9)

 

u8 recvData=0;//!

u32 delayTime = 8; //1000000/115200=8.6us  

/*!

 * @brief 模拟串口1 TX IO口配置

 * @param none

 * @return none

 * @note Tx(PA10)

 */

void MUSART1_TX_init(void)

{  

    GPIO_InitTypeDef GPIO_InitStructure;

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;

    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_SetBits(GPIOA, GPIO_Pin_10);//TXD 空闲状态是高电平

}

 

/*!

 * @brief 模拟串口1 RX IO口配置

 * @param none

 * @return none

 * @note Rx(PA9)

 */

void MUSART1_RX_init(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;

    EXTI_InitTypeDef EXTI_InitStructure;

    NVIC_InitTypeDef NVIC_InitStructure;

 

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//!

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟

 

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;

    GPIO_Init(GPIOA, &GPIO_InitStructure);

 

    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource9);

 

    EXTI_InitStructure.EXTI_Line=EXTI_Line9;

    EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;

    EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;//下降沿中断

    EXTI_InitStructure.EXTI_LineCmd=ENABLE;

    EXTI_Init(&EXTI_InitStructure);

 

    NVIC_InitStructure.NVIC_IRQChannel=EXTI9_5_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x2; //抢占优先级 2,

    NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x1;

    NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;

    NVIC_Init(&NVIC_InitStructure);

}

/*!

 * @brief 定时器14初始化

 * @param   定时器14复位后时钟=168M/2=84M

 * @return NONE

 * @note 8us定时器,用于串口数据采样

 */

void Time14Init(void)

{

    TIM_TimeBaseInitTypeDef TIM_TimerBaseStruct;

    NVIC_InitTypeDef NVIC_InitStructure;

 

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14, ENABLE);//!

    TIM_DeInit(TIM14); //!

    TIM_TimerBaseStruct.TIM_Period=8;//!

    TIM_TimerBaseStruct.TIM_Prescaler=83; //!

    TIM_TimerBaseStruct.TIM_ClockDivision=0; //!

    TIM_TimerBaseStruct.TIM_CounterMode=TIM_CounterMode_Up; //!

    TIM_TimeBaseInit(TIM14,&TIM_TimerBaseStruct);

 

 

    NVIC_InitStructure.NVIC_IRQChannel=TIM8_TRG_COM_TIM14_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;//定时器优先级一定要最高

    NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;

    NVIC_Init(&NVIC_InitStructure);


    TIM_ClearITPendingBit(TIM14, TIM_FLAG_Update);

    TIM_ITConfig(TIM14,TIM_IT_Update,ENABLE);  //!

    TIM_Cmd(TIM14,DISABLE);                      //!

}

 

/*!

 * @brief 模拟串口1发送一个字节

 * @param

 * @return none

 * @note 数据低位在前高位在后

 */

void MUSART1_SendData(u8 data)//发送一个数据

{

    u8 i = 0;

    TX_L(); //!

    delay_us(delayTime);

    for(i = 0; i < 8; i++) 

  {

        if(data & 0x01)

            TX_H();

        else

            TX_L();

        delay_us(delayTime);

        data >>= 1;

    }

    TX_H(); //!

    delay_us(delayTime);

}

 

u8 RevSucc=0;//接收完成标志位

u8 MUSART1_ReadData(void)//接收一个数据

{

  while(RevSucc==0){};

RevSucc=0;

  return  recvData;

}

 

/*!

 * @brief 串口接收IO中断处理函数

 * @param none

 * @return NONE

 * @note none

 */

void EXTI9_5_IRQHandler(void)

{

    if (EXTI_GetITStatus(EXTI_Line9) != RESET) 

{

  EXTI->IMR &= 0<<9;//关闭EXTI_Line9上的中断(如果要开启中断,则反操作即可)

        if(RX_READ() == 0x00)

{            

                recvData = 0; 

                TIM_SetCounter(TIM14,0);

                TIM_Cmd(TIM14, ENABLE); //打开定时器,接收数据    

        }    

        EXTI_ClearITPendingBit(EXTI_Line9);

        

    }

}

 

/*!

 * @brief 定时器14中断处理函数

 * @param

 * @return NONE

 * @note

 */

 

u8 count=0;

 

void TIM8_TRG_COM_TIM14_IRQHandler(void)

{

    if(TIM_GetITStatus(TIM14, TIM_IT_Update) != RESET)

    {      

        if(RX_READ())

        {

            recvData |= (1 << count);//读RX电平

        }

count++;

if(count==8)//数据读取完成

        {

            TIM_Cmd(TIM14, DISABLE);//!

  count = 0;

  RevSucc=1;//接收完成   

  EXTI->IMR|=1<<9; //开启外部中断 准备下一次接收       

        }    

        TIM_ClearITPendingBit(TIM14, TIM_FLAG_Update);

    }

}

 

 

 

#ifndef SIMULATION_USART1_H

#define SIMULATION_USART1_H

 

 

void MUSART1_TX_init(void);

void MUSART1_RX_init(void);

void Time14Init(void);

void MUSART1_SendData(u8 data);

u8 MUSART1_ReadData(void);

 

 

 

#endif

/****************************************************************/

/*名称: fputc */

/*功能: 重定向Printf*/

/*输入: 无*/

/*输出: 无*/

/**/

/****************************************************************/

int fputc(int ch, FILE *f)

{

    //while((USART1->SR&0X40)==0);//循环发送,直到发送完毕

   // USART1->DR = (u8) ch;

  MUSART1_SendData(ch);

    return ch;

}

 


关键字:STM32F407Z  模拟串口  115200波特率 


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
ARM基础知识八