zoukankan      html  css  js  c++  java
  • 串口查询法和串口中断法

      串口查询法

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

      我主要都是在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

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

  • 相关阅读:
    根据svm将视频帧转换为img
    Mp4 to Img
    Python_02 基本数据类型、while循环
    Python_01 执行方式、解释器路径、编码、变量、条件语句
    数字货币,新时代货币革命的起点?
    企业区块链项目中需要避免的常见错误
    2021 年五大物联网 (IoT) 趋势
    揭开AI、机器学习和深度学习的神秘面纱
    物联网的安全性与法规的未来
    为什么分布式云是下一代云计算?Gartner分析师这样解释
  • 原文地址:https://www.cnblogs.com/18689400042qaz/p/13410948.html
Copyright © 2011-2022 走看看