实验一 串口中断、STM32F103 串口1/串口2/串口3 发送与接收

1. USART2、USART3 配置

1.1 usart2,使能GPIO时钟,这里我用的是A口,以及GPIO口的配置,这里我的串口输出是PA2,输入是PA3

然后初始化usart2,再使能usart2

/* 串口初始化 */
 
void STM_EVAL_COMInit(USART_InitTypeDef* USART_InitStruct)
{
  GPIO_InitTypeDef GPIO_InitStructure;
 
  /* Enable GPIO clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//GPIOA使能
 
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);USART2时钟使能
 
  /* Configure USART Tx as alternate function push-pull */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//输出PA2
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
 
  /* Configure USART Rx as input floating */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//输入PA3
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
 
  /* USART configuration */
  USART_Init(USART2, USART_InitStruct);//USART2初始化
    
  /* Enable USART */
  USART_Cmd(USART2, ENABLE);//使能USART2
}

void USART2_Init (void)
{
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure; 
    
    USART_InitStructure.USART_BaudRate = 115200;                  //波特率
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;   //数据位个数=8
  USART_InitStructure.USART_StopBits = USART_StopBits_1;        //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;
 
  STM_EVAL_COMInit(&USART_InitStructure);
    
    
//数据接收的使能中断
  /* Enable the USARTz Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;//为USART2
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
    
  /* Enable the USARTz Receive Interrupt */
  USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//都能接收数据,需要开启中断
}

1.2 usart3,使能GPIO时钟,这里我用的是B口,以及GPIO口的配置,这里我的串口输出是PB10,输入是PB11 

void usart3_init(u32 bound)
{  
 
    NVIC_InitTypeDef NVIC_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);    // GPIOB时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE); //串口3时钟使能
 
     USART_DeInit(USART3);  //复位串口3
         //USART3_TX   PB10
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PB10
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //复用推挽输出
  GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PB10
   
    //USART3_RX      PB11
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  GPIO_Init(GPIOB, &GPIO_InitStructure);  //初始化PB11
    
    USART_InitStructure.USART_BaudRate = bound;//波特率一般设置为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); //初始化串口    3
  
 
    USART_Cmd(USART3, ENABLE);                    //使能串口 
    
    //使能接收中断
  USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启中断   
    
    //设置中断优先级
    NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//抢占优先级3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;        //子优先级3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;            //IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);    //根据指定的参数初始化VIC寄存器
    
    USART3_RX_STA=0;        //清零
}

1.3. usart1,使能GPIO时钟,这里我用的是A口,以及GPIO口的配置,这里我的串口输出是PA9,输入是PA10 

void USART1_Config(void)
{

    GPIO_InitTypeDef GPIO_InitStructure;
        //USART1配置
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure; 

/*由于UART的TX和RX和AFIO都挂在APB2桥上,
因此采用固件库函数RCC_APB2PeriphClockCmd()进行初始化。
UARTx需要分情况讨论,如果是UART1,则挂在APB2桥上,
因此采用RCC_APB2PeriphClockCmd()进行初始化,其余的UART2~5均挂在APB1上。
*/
    //打开时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);


    /*
    GPIO的属性包含在结构体GPIO_InitTypeDef,其中对于TX引脚,
    GPIO_Mode字段设置为GPIO_Mode_AF_PP(复用推挽输出),
    GPIO_Speed切换速率设置为GPIO_Speed_50MHz;对于RX引脚,
    GPIO_Mode字段设置为GPIO_Mode_IN_FLOATING(浮空输入),
    不需要设置切换速率。最后通过GPIO_Init()使能IO口。
    */

    //USART1 Tx(PA.09) 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    //USART1 Rx(PA.10) 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
    GPIO_Init(GPIOA, &GPIO_InitStructure);

/*通过结构体USART_InitTypeDef来确定。UART模式下的字段如下
USART_BaudRate:波特率,视具体设备而定
USART_WordLength:字长
USART_StopBits:停止位
USART_Parity:校验方式
USART_HardwareFlowControl:硬件流控制
USART_Mode:单/双工
*/

    USART_InitStructure.USART_BaudRate = 115200; 
    USART_InitStructure.USART_WordLength = USART_WordLength_8b; 
    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_Tx | USART_Mode_Rx; 
    USART_Init(USART1, &USART_InitStructure);
    USART_Cmd(USART1, ENABLE); 


    //数据接收的使能中断 USART1_IRQn
      /* Enable the USARTz Interrupt */
    
     /* Enable the USARTy Interrupt */
/*    
        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;      
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
*/
      NVIC_InitStructure.NVIC_IRQChannel = 37;//为 USART1
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
      NVIC_Init(&NVIC_InitStructure);
        
    //NVIC_InitStructure.NVIC_IRQChannel = 37;//为 USART1
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//

}

2 使用SendString函数发送

USART数据发送有两个标志, 一个是TXE=发送数据寄存器空,另一个是TC=发送结束;

例如发送“hello”,串口助手只接收到了“ello”,没有h这是因为stm32的usart的sr寄存器的TC初始为1,导致第一次while时第一个数据被覆盖. 这种情况,将TC修改为TXE即可:USART_FLAG_TXE

2.1 SendString

void SendString (char *s)
{
    while(*s)
    {
        USART_SendData(USART2, *s++);//依次发送
 
  /* Loop until the end of transmission */
  while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET)//TC标志位为reset发送结束
  {

  }
    }
}

2.2 回显

void USART1_IRQHandler_handle(void) // 串口1中断服务函数
{
    u16 res;
    if(USART_GetITStatus(USART1,USART_IT_RXNE)) // 中断标志
     {
         res= USART_ReceiveData(USART1);  // 串口1 接收
         USART_SendData(USART1,res);   // 串口1 发送
      }
}

void USART2_IRQHandler_handle(void) // 串口2中断服务函数
{
    u16 res;
    if(USART_GetITStatus(USART2,USART_IT_RXNE)) // 中断标志
    {
        res= USART_ReceiveData(USART2);  // 串口2 接收
         USART_SendData(USART2,res);   // 串口2 发送
    }
}

效果如下:

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值