串口查詢法和串口中斷法


  串口查詢法

  其實我在網上找了許多串口查詢法的例程,可是無一例外,都特別繁瑣,我對這個串口查詢法有趣的是其實現的過程,因為在實際工程應用中基本用不到查詢法,因此我在此拋磚引玉,假若有所遺漏,請各位不膩賜教!覺得不錯的,可以點個贊。

  我主要都是在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!='\0')                          //當發送的字符串還沒結束(即遇到結束字符‘\0’)時
    {
        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\r\n",USART_RX_BUF);        //對接收的數據打印出來,調試用
        memset(USART_RX_BUF,0,100);                //發送完數據之后,要對這個接收數據的數組進行清零,防止串口一直返回1,讓開發板一直發送數據
    }

}

串口中斷法

大家要是想了解一下STM32中串口的中斷法如何使用的話,可以直接搜索下邊這個地址,這是筆者借鑒正點原子的開發例程,其中搭配上筆者的一些見解,請大家感興趣的話,可以了解一下。

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

最后,覺得筆者寫的還可以的,可以給個推薦,謝謝大家!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM