串口查询法和串口中断法

  串口查询法

  其实我在网上找了许多串口查询法的例程,可是无一例外,都特别繁琐,我对这个串口查询法有趣的是其实现的过程,因为在实际工程应用中基本用不到查询法,因此我在此抛砖引玉,假若有所遗漏,请各位不腻赐教!觉得不错的,可以点个赞。

  我主要都是在keil MDK5开发平台上基于stm32f103开发板进行开发。主要函数及其定义都在usart这个函数中

  首先出现的这个是usart.c对应的.h文件,主要是对各个函数和定义进行申明

#ifndef __USART_H
#define __USART_H
#include "stdio.h"    
#include "sys.h" 

#define USART_REC_LEN              200      //定义最大接收字节数 200          

//主要函数,这些函数具体作用在usart.c中有说明
void uart_init(u32 bound);
void USART1_SendOneByte(u8 SendData);
void USART1_SendString(u8 * SendData);
u8 USART1_ReceiveOneByte(void);
u8 USART1_ReceiveString(void);
#endif

 接下来的就是usart.c文件

#include "stm32f10x.h"
#include "usart.h"
//加入以下代码,支持printf函数,而不需要选择use MicroLIB
#if 1
#pragma import(__use_no_semihosting)             
//标准库需要的支持函数                 
struct __FILE 
{ 
    int handle; 

}; 

FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
void _sys_exit(int x) 
{ 
    x = x; 
} 

//重定义fputc函数 
int fputc(int ch, FILE *f)
{      
    while((USART1->SR&0X40)==0); //循环发送,直到发送完毕   
    USART1->DR = (u8) ch;      
    return ch;
}
#endif 


//用于接收电脑端虚拟串口发送过来的数据
//定义了一个接收数组USART_RX_BUF[USART_REC_LEN];
//#define USART_REC_LEN              200      //定义最大接收字节数 200    (在usart.h中)
//定义了一个计算字符串长度的全局变量USART_RX_LEN
u8 USART_RX_BUF[USART_REC_LEN]; 
u8 USART_RX_LEN=0;



/*
函数名:            uart_init
功能:              对串口1进行初始化
带入参数:        波特率(9600)
返回:          void
*/
  void uart_init(u32 bound)
{
    GPIO_InitTypeDef GPIO_InitStrue;
    USART_InitTypeDef USART_InitStrue;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);    //使能串口1对应GPIO口和串口1的时钟
    
    GPIO_InitStrue.GPIO_Pin=GPIO_Pin_9;                                   //PA9 串口1TX   复用推挽输出
    GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;
    GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStrue);
    
    GPIO_InitStrue.GPIO_Pin=GPIO_Pin_10;
    GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING;                  //PA10  串口1RX  浮空输入
    GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStrue);
    
    USART_InitStrue.USART_BaudRate=bound;                                            //串口波特率
    USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None;        //串口是否由硬件控制
    USART_InitStrue.USART_Parity=USART_Parity_No;                                    //奇偶校验位
    USART_InitStrue.USART_StopBits=USART_StopBits_1;                                 //停止位的位数
    USART_InitStrue.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;                         //串口的模式,这里即可接收又可发送
    USART_InitStrue.USART_WordLength=USART_WordLength_8b;                            //串口的字长
    USART_Init(USART1,&USART_InitStrue);                                            //对所有的串口参数形成初始化
    USART_Cmd(USART1,ENABLE);                                                 //串口使能
}



/*
函数名:            USART1_SendOneByte
功能:              对单个字节进行发送
带入参数:        u8 SendData
返回:          void
*/
void USART1_SendOneByte(u8 SendData)
{
    u32 cnt=0;
    USART_SendData(USART1,(u16)SendData);                    //调用stm32f10x_usart.c中的发送函数USART_SendData
    while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET) //等待发送完毕,这个等待函数也可在stm32f10x_usart.c找到
    {
        cnt++;
        if(cnt>100000) break;                               //超过100ms,不管数据是否发送完毕,都不再等待
    }
}


/*
函数名:            USART1_SendString
功能:              对多个字节进行发送
带入参数:        u8 * SendData
返回:          void
*/
void USART1_SendString(u8 * SendData)
{
    while(*SendData!='')                          //当发送的字符串还没结束(即遇到结束字符‘’)时
    {
        USART1_SendOneByte(*SendData++);            //一直一个字节一个字节的发送数据
    }
}




/*
函数名:            USART1_ReceiveOneByte
功能:              对单个字节进行接收
带入参数:        void
返回:          u8
*/
u8 USART1_ReceiveOneByte(void)
{

        while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==RESET){}   //等待接收寄存器接收完毕,USART_FLAG_RXNE将置1,就会跳出这个while循环
        return USART_ReceiveData(USART1);                              //返回接收寄存器中的接收数据

}



/*
函数名:            USART1_ReceiveString
功能:              对多个字节进行接收
带入参数:        void
返回:          u8
*/
u8 USART1_ReceiveString(void)
{
    u8 i=0;
    u32 cnt=0;
    while(1)
    {
        USART_RX_BUF[USART_RX_LEN++]=USART1_ReceiveOneByte();//把接收的字节依次赋给数据缓冲区(USART_RX_BUF数组)
        for(i=0;i<USART_RX_LEN-1;i++)                            //对接收数据的数据进行判断
        {
            if(USART_RX_BUF[i]==0x0d)                            //0x0d回车,就是把光标定位到该行起始位置
        {
            if(USART_RX_BUF[i+1]==0x0a)                        //0x0a换行符,就是把换行到下一行的起始位置
            {
                USART_RX_LEN=0;                   //USART_RX_LEN必须置0,不然你下一次发送时,接收的数据将在USART_RX_BUF[USART_RX_LEN]                                                                
                return 1;                          //而接收的数据要从USART_RX_BUF[0]才行    
                                                                    //当接连遇到0x0d、0x0a表示字符串已经结束了
                                                                    //这是因为电脑虚拟串口在发送数据时会自动给数据添加0x0d、0x0a结尾
            }else
            {
                i=0;
                break;                             //假如不是接连遇到0x0d、0x0a,则重新寻找
            }
        }
        }
    
        cnt++;
        if(cnt>100000) return 0;  //超过100ms,不管数据是否接收完毕,都不再等待
    }
}

接下来将是main函数,main 函数就是开发板将从电脑虚拟串口助手发送过来的数据接收之后,开发板发送这些接收的数据给电脑的电脑虚拟串口助手。

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "string.h"
//这些数组以及数据长度变量已经在usart.c中定义,这里用extern直接申明在外部寻找即可
extern u8  USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 
extern u8 USART_RX_LEN;    

int main(void)
{
    
        u16 t;  
    u16 len;    
    u16 times=0;
    delay_init();                                                                         //延时函数初始化      
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);     //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
    uart_init(9600);                                                                 //串口初始化为115200
     LED_Init();    
     
    while(1)
    {
        if(USART1_ReceiveString()==1)             //开发板一接收到数据
        USART1_SendString(USART_RX_BUF);        //就执行发送数据给电脑的操作
        
//        printf("%s
",USART_RX_BUF);        //对接收的数据打印出来,调试用
        memset(USART_RX_BUF,0,100);                //发送完数据之后,要对这个接收数据的数组进行清零,防止串口一直返回1,让开发板一直发送数据
    }

}

串口中断法

大家要是想了解一下STM32中串口的中断法如何使用的话,可以直接搜索下边这个地址,这是笔者借鉴正点原子的开发例程,其中搭配上笔者的一些见解,请大家感兴趣的话,可以了解一下。

https://www.cnblogs.com/18689400042qaz/p/13378636.html

最后,觉得笔者写的还可以的,可以给个推荐,谢谢大家!!!

原文地址:https://www.cnblogs.com/18689400042qaz/p/13410948.html