《SLAM机器人基础教程》第三章 单片机与STM32:串口收发实验

3.4节串口收发实验

本节将学习STM32使用串口与电脑进行通信

a.实验准备:USB转串口模块,ST-Llink下载器,CHEAPX机器人控制板

b.实验目的:STM32串口的使用

c.相关知识点:

串口是一种电子设备间常用的串行通讯方式,电子工程师在调试设备时也经常使用该通讯方式输出调试信息。串口是全双工通信,即可以同时收数据和发数据。发数据使用TX管脚,收数据使用RX管脚。STM32中的USART串口外设已经实现了串口底层协议,所以我们直接使用就行。STM32中的USART串口通信,一般使用中断模式。但有数据过来是,产生中断信号,CPU直接跳转进中断函数运行。注意,STM32是单核单线程处理器,硬件中断的存在,让STM32可以实现上位机多线程类似效果。

d.编程及运行

(1)初始化芯片的串口管脚A9 A10和配置USART,位置如下图。步骤如下:打开对应GPIO口,串口的时钟,再配置管脚参数,配置串口参数。

void initDebugSerial(u32 bound){

  GPIO_InitTypeDef  GPIO_InitStruct;
    USART_InitTypeDef USART_InitStruct;
    NVIC_InitTypeDef  NVIC_InitStruct;
    
    //Config Clock 配置时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);    //Enable Clock:USART1,GPIOA
  
    //Config GPIO A9 A10 配置芯片管脚
  GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_9; 
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_AF_PP;      
  GPIO_Init(GPIOA, &GPIO_InitStruct);//传入结构GPIO_InitStruct,配置GPIOA
   
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStruct); //传入结构GPIO_InitStruct,配置GPIOA

  //Config NVIC 配置中断
  NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;       //IRQChannel 配置中断通道为USART1_IRQn
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=3 ;//PreemptionPriority 抢占优先级
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 3;           //SubPriority 子优先级
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;               //ENABLE IRQChannel 使能中断通道
    NVIC_Init(&NVIC_InitStruct);    //传入结构体NVIC_InitStruct,配置NVIC
  
  //Config USART 配置串口
    USART_InitStruct.USART_BaudRate   = bound; //bound 波特率
    USART_InitStruct.USART_WordLength = USART_WordLength_8b;//WordLength 字长8位
    USART_InitStruct.USART_StopBits   = USART_StopBits_1;//StopBits 停止位
    USART_InitStruct.USART_Parity     = USART_Parity_No;//Parity 奇偶校验
    USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//HardwareFlowControl
    USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;    //USART_Mode 串口模式:收发模式
  USART_Init(USART1, &USART_InitStruct);  //传入结构体USART_InitStruct,配置串口USART1
    
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //使能串口中断
  USART_Cmd(USART1, ENABLE); //使能串口
}

(2)编写串口接收中断函数。使用数组debugRxBuf[20]保存接收到的数据(每接收到一个8位数据,产生一次中断,运行一次USART1_IRQHandler()函数),全局变量debugRxCount用于计数,同时改变数组debugRxBuf[20]下标值,实现数据从debugRxBuf[0],debugRxBuf[1].....依次保存。

u8  debugRxBuf[20]; 
u8  debugRxCount=0;
void USART1_IRQHandler(void)    //串口1中断函数,函数名不可改,已在汇编文件startup_stm32f10x_hd.s 中规定好     
{
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到串口数据)
    {
        debugRxBuf[debugRxCount] =USART_ReceiveData(USART1);    //读取接收到的数据        
        debugRxCount++;//计数
    }
} 

(3)编写主函数,如下:

//串口收发实验
int main(void)
{        
    u8 i;
    u8 txbuf[10]={0,1,2,3,4,5,6,7,8,9};
    
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //PriorityGroupConfig NVIC中断分组设置 组2(2位抢占优先级,2位响应优先级)
    initDebugSerial(500000);

    //先往串口发送十个数
    for(i=0;i<10;i++)
    {
            while((USART1->SR&0X40)==0);//等待发送完毕   
            USART1->DR = txbuf[i];      //填充数据
    }
    
    while(1)
    {
        if(debugRxCount>=10)//接收满10个字节,返回该10个数
        {
            for(i=0;i<10;i++)
            {
                txbuf[i]=debugRxBuf[i];
            }
            debugRxCount=0;//重新从debugRxBuf[0]开始填充
            
            for(i=0;i<10;i++)
            {
                while((USART1->SR&0X40)==0);//等待发送完毕   
                USART1->DR = txbuf[i];      //填充数据
            }
        }
    }
}

(4)编译运行。步骤如下:打开sscom串口助手软件,并连接USB转串口模块的端口,sscom串口软件配置如下图。

 (5)实验结果:如上图所示,程序运行时,串口首先收到十个HEX十六进制数据。我们在sscom串口助手的数据输入窗口中,编写十个十六进制数,点击发送。然后回收单片机回传的这十个数。

 

 

e.实验总结:串口的初始化配置和GPIO配置一样,都有标准流程,我们后续使用串口时,参考该程序就可以了。

posted @ 2020-07-25 21:18  baronluu  阅读(685)  评论(0编辑  收藏  举报