STM32F103 串口1和串口3對發數據 配合藍牙模塊 實現手機和單片機的簡單通信demo


@

前言

開發板:正點原子 STM32F103 精英版
語言:C語言
開發環境:Keil5
使用了 KEY LED USART USB轉TTL模塊 智向的藍牙模塊(ps:電腦安裝驅動CH340)
代碼下載碼雲 GitHub
在這里插入圖片描述

代碼參考:正點原子 源碼 串口實驗例程
功能介紹
1、LED的0.2秒一閃,表示程序正在運行。
2、串口1收到的數據會發給串口3,串口3收到的數據會發給串口1。
3、按鍵KEY1按下會向串口1發送數據‘1’,按鍵KEY0按下會向串口3發送數據‘3’。

接線

USB轉TTL

在這里插入圖片描述

在這里插入圖片描述
在這里插入圖片描述

藍牙

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

效果圖

USB轉TTL

在這里插入圖片描述

藍牙

使用的手機軟件(安卓)為 BLE調試助手
在這里插入圖片描述
打開軟件、藍牙、給予權限等
掃描到我們的藍牙模塊,然后連接
在這里插入圖片描述
連接成功后
在這里插入圖片描述
點擊最下面的 Unkonwn Service,展開,有接收 和 發送 按鈕
在這里插入圖片描述

手機收 電腦發

在這里插入圖片描述
在這里插入圖片描述

手機發 電腦收

在這里插入圖片描述
在這里插入圖片描述

藍牙的連接/斷開

藍牙收到了手機發來的 連接 和 斷開 信息
在這里插入圖片描述

參考用圖

STM32F103

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

藍牙模塊相關

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

核心代碼

完整代碼下載碼雲 GitHub

main.c

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart1.h"
#include "usart3.h"

// 串口收發函數 type為1,串口1收,發往串口3  type不為1,串口3,發往串口1
void usart_recv_send(u8 type);

int main(void)
{
    vu8 key = 0;
    delay_init();												 // 延時函數初始化
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 設置NVIC中斷分組2:2位搶占優先級,2位響應優先級
    usart1_init(115200);									 // USART1初始化 波特率115200 默認數據位8 停止位1 校驗位none
    usart3_init(115200);									 // USART3初始化 波特率115200 默認數據位8 停止位1 校驗位none
    LED_Init();												 // LED端口初始化
    KEY_Init();										  	 	 // 初始化與按鍵連接的硬件接口
    while (1)
    {
        // 串口收發
        usart_recv_send(1);
        usart_recv_send(3);

        // 得到鍵值
        key = KEY_Scan(0);
        if (key)
        {
            switch (key)
            {
                case KEY1_PRES: // 向串口1發送'1'
                    usart1_send_byte(0x31);
                    break;
                case KEY0_PRES: // 向串口3發送'3'
                    usart3_send_byte(0x33);
                    break;
            }
        }

        LED0 = !LED0; //閃爍LED,提示系統正在運行.
        delay_ms(100);
    }
}

// 串口收發函數 type為1,串口1收,發往串口3  type不為1,串口3,發往串口1
void usart_recv_send(u8 type)
{
    u8 i = 0;
    u8 tmp_len = 0;
    // 數據緩存
    static u8 buf[255] = {0};
    // 數據長度
    u8 buf_len = 0;

    // 返回緩存區數據的個數
    if(1 == type)
        tmp_len = usart1_getdata_count();
    else
        tmp_len = usart3_getdata_count();

    for(i=0; i<tmp_len; i++)
    {
        // 返回緩存區當前指針所指數據
        if(1 == type)
            buf[i] = usart1_receive_data();
        else
            buf[i] = usart3_receive_data();

        buf_len++;
        // 超過約定的上限長度
        if(buf_len >= 250)
        {
            buf_len=0;
            break;
        }
    }

    // 數據不為空
    if(0 != buf_len)
    {
        // 串口數據發送
        if(1 == type)
            usart3_send_bytes(buf, buf_len);
        else
            usart1_send_bytes(buf, buf_len);
    }
}

usart1.c

#include "usart1.h"
#include "stdio.h"

static uint8_t usart1_buffer[255];
static uint8_t usart1_index;
static uint8_t usart1_count;

// USART1初始化 默認數據位8 停止位1 校驗位none
void usart1_init(u32 bound)
{
    // GPIO端口設置
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    /* config USART1 clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); // 使能USART1,GPIOA時鍾

    /* USART1 GPIO config */
    /* Configure USART1 Tx (PA.09) as alternate function push-pull */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推挽輸出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化GPIOA.9
    /* Configure USART1 Rx (PA.10) as input floating */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空輸入
    GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA.10

    // Usart1 NVIC 配置
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//搶占優先級3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;		//子優先級3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);	//根據指定的參數初始化VIC寄存器

    USART_InitStructure.USART_BaudRate = bound; // 串口波特率
    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(USART1, &USART_InitStructure); // 初始化串口1
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // 開啟串口接受中斷

    USART_Cmd(USART1, ENABLE); // 使能串口1

    usart1_index=0;
    usart1_count=0;
}

// 中斷服務函數
void USART1_IRQHandler(void)
{
    // 接收中斷
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {
        if(usart1_count==usart1_index)
        {
            // 緩存區無數據,回到起點開始存儲
            usart1_count=0;
            usart1_index=0;
        }
        usart1_buffer[usart1_count]=USART1->DR;
        usart1_count++;
        if(usart1_count>=250)
        {
            // 沒有及時取出數據,導致存儲位置到達末尾,回到起點
            usart1_count=0;
            usart1_index=0;
        }
    }
}

/*返回緩存區數據的個數*/
uint8_t usart1_getdata_count(void)
{
    return usart1_count-usart1_index;
}

/*返回緩存區當前指針所指數據*/
uint8_t usart1_receive_data(void)
{
    return usart1_buffer[usart1_index++];
}

/*串口數據發送函數
data_send:發送數據
*/
void usart1_send_byte(uint8_t data_send)
{
    USART_SendData(USART1, data_send);
    while (!(USART1->SR & USART_FLAG_TXE));
}

/*串口數據發送函數
data_buffer:發送數據串的首地址
length:發送數據的長度
*/
void usart1_send_bytes(uint8_t* data_buffer,uint8_t length)
{
    uint8_t i;
    for(i=0; i<length; i++)
    {
        usart1_send_byte(data_buffer[i]);
    }
}

usart3.c

#include "usart3.h"
#include "stdio.h"

static uint8_t usart3_buffer[255];
static uint8_t usart3_index;
static uint8_t usart3_count;

// USART3初始化 默認 數據位8 停止位1 校驗位none
void usart3_init(u32 bound)
{
	// GPIO端口設置
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    /* config USART3 clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); //使能USART3,GPIOB時鍾

    /* USART3 GPIO config */
    /* Configure USART3 Tx (PB.10) as alternate function push-pull */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    /* Configure USART3 Rx (PB.11) as input floating */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//搶占優先級3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;		//子優先級3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);	//根據指定的參數初始化VIC寄存器

    USART_InitStructure.USART_BaudRate = bound; // 串口波特率
    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_ITConfig(USART3, USART_IT_RXNE, ENABLE); // 開啟串口接受中斷

    USART_Cmd(USART3, ENABLE); // 使能串口3 

    usart3_index=0;
    usart3_count=0;
}

// 中斷服務函數
void USART3_IRQHandler(void)
{
    if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
    {
        if(usart3_count==usart3_index)
        {
            //緩存區無數據,回到起點開始存儲
            usart3_count=0;
            usart3_index=0;
        }
        usart3_buffer[usart3_count]=USART3->DR;
        usart3_count++;
        if(usart3_count>=250)
        {
            //沒有及時取出數據,導致存儲位置到達末尾,回到起點
            usart3_count=0;
            usart3_index=0;
        }
    }
}

/*返回緩存區數據的個數*/
uint8_t usart3_getdata_count(void)
{
    return usart3_count-usart3_index;
}

/*返回緩存區當前指針所指數據*/
uint8_t usart3_receive_data(void)
{
    return usart3_buffer[usart3_index++];
}

/*串口數據發送函數
data_send:發送數據
*/
void usart3_send_byte(uint8_t data_send)
{
    USART_SendData(USART3, data_send);
    while (!(USART3->SR & USART_FLAG_TXE));
}

/*串口數據發送函數
data_buffer:發送數據串的首地址
length:發送數據的長度
*/
void usart3_send_bytes(uint8_t* data_buffer,uint8_t length)
{
    uint8_t i;
    for(i=0; i<length; i++)
    {
        usart3_send_byte(data_buffer[i]);
    }
}

拓展應用

實現簡單的賬號認證,通過命令控制LED1和蜂鳴器的開關

功能介紹

手機連接藍牙,發送登錄命令login#admin#admin

login#用戶名#密碼#

在這里插入圖片描述

登錄成功后,發送控制命令

cmd#device#status#

最后發送登出命令cmd#login#out
在這里插入圖片描述

效果圖

在這里插入圖片描述

在這里插入圖片描述

代碼

main.c
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart1.h"
#include "usart3.h"
#include "string.h"
#include "stdio.h"
#include "beep.h"

u8 login = 0;
u8 username[21] = "admin";
u8 password[21] = "admin";

// 串口收發函數 type為1,串口1收,發往串口3  type不為1,串口3收,發往串口1
void usart_recv_send(u8 type);
// 檢查登錄 傳入收到的數據和數據長度 返回 0驗證成功,1賬號或密碼錯誤,2數據超長
u8 check_login(u8* buf, u8 len);
/*
	函數功能: 命令解析
	傳參:     收到的數據和數據長度
	命令格式: cmd#device#status#
	返回: 	   0不符合規則 1解析成功
*/
u8 cmd_analysis(u8* buf, u8 len);

int main(void)
{
    vu8 key = 0;
    delay_init();											 // 延時函數初始化
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 		 // 設置NVIC中斷分組2:2位搶占優先級,2位響應優先級
    usart1_init(115200);									 // USART1初始化 波特率115200 默認數據位8 停止位1 校驗位none
    usart3_init(115200);									 // USART3初始化 波特率115200 默認數據位8 停止位1 校驗位none
    LED_Init();												 // LED端口初始化
    KEY_Init();										  	 	 // 初始化與按鍵連接的硬件接口
	BEEP_Init();									  	 	 // 蜂鳴器初始化
	LED0 = 1;
    while (1)
    {
        // 串口收發
        usart_recv_send(1);
        usart_recv_send(3);

        // 得到鍵值
        key = KEY_Scan(0);
        if (key)
        {
            switch (key)
            {
				case KEY1_PRES: // 向串口1發送'1'
					usart1_send_byte(0x31);
					break;
				case KEY0_PRES: // 向串口3發送'3'
					usart3_send_byte(0x33);
					break;
            }
        }

        LED0 = !LED0; //閃爍LED,提示系統正在運行.
        delay_ms(100);
    }
}

// 串口收發函數 type為1,串口1收,發往串口3  type不為1,串口3收,發往串口1
void usart_recv_send(u8 type)
{
    u8 i = 0;
    u8 tmp_len = 0;
    // 數據緩存
    static u8 buf[255] = {0};
    //static u8 buf2[255] = {0};
    // 數據長度
    u8 buf_len = 0;

    // 返回緩存區數據的個數
    if(1 == type)
        tmp_len = usart1_getdata_count();
    else
        tmp_len = usart3_getdata_count();

    for(i=0; i<tmp_len; i++)
    {
        // 返回緩存區當前指針所指數據
        if(1 == type)
            buf[i] = usart1_receive_data();
        else
            buf[i] = usart3_receive_data();

        buf_len++;
        // 超過約定的上限長度
        if(buf_len >= 250)
        {
            buf_len=0;
            break;
        }
    }

    // 數據不為空
    if(0 != buf_len)
    {
        // 串口數據發送
        if(1 == type)
            usart3_send_bytes(buf, buf_len);
        else
        {
            usart1_send_bytes(buf, buf_len);
			printf("\r\n");
            // 如果沒有登錄
            if(0 == login)
            {
                // 檢查登錄
                if(0 == check_login(buf, buf_len))
                {
                    login = 1;
                    printf("登錄成功\r\n");
                }
                else if(2 == check_login(buf, buf_len))
                {
                    printf("賬號或密碼超長\r\n");
                }
				else if(3 == check_login(buf, buf_len))
                {
                    printf("命令過短,請發送命令\"login#賬號#密碼#\"登錄\r\n");
                }
                else
                {
                    printf("賬號或密碼錯誤,請發送命令\"login#賬號#密碼#\"登錄\r\n");
                }
            }
            // 已經登錄
            else
            {
				cmd_analysis(buf, buf_len);
            }
        }
    }
}

// 檢查登錄 傳入收到的數據 返回 0驗證成功,1賬號或密碼錯誤,2數據超長,3數據過短
u8 check_login(u8* buf, u8 len)
{
    u8 i = 0, j = 0;
    u8 str_username[21] = {0};
    u8 str_password[21] = {0};
	if(len < 9)
	{
		return 3;
	}
    // 登錄命令
    if(buf[0] == 'l' && buf[1] == 'o' && buf[2] == 'g' && buf[3] == 'i' && buf[4] == 'n' && buf[5] == '#')
    {
        // 解析數據獲取username和password 分隔符為'#'
        j = 0;
        i = 6;
        while(buf[i] != '#' && i < len)
        {
            // 數據超長
            if(j >= 20)
            {
                return 2;
            }
            str_username[j++] = buf[i++];
        }
        str_username[j] = '\0';

        j = 0;
        i++;
        while(buf[i] != '#' && i < len)
        {
            // 數據超長
            if(j >= 20)
            {
                return 2;
            }
            str_password[j++] = buf[i++];
        }
        str_password[j] = '\0';

        if(0 == strcmp((char *)str_username, (char *)username) && 0 == strcmp((char *)str_password, (char *)password))
        {
            return 0;
        }
        else
        {
            return 1;
        }
    }
    else
    {
        return 1;
    }
}

/*
	函數功能: 命令解析
	命令格式: cmd#device#status#
	返回: 	   0不符合規則 1解析成功
*/
u8 cmd_analysis(u8* buf, u8 len)
{
	u8 device[10] = {0};
	u8 status[6] = {0};
	u8 i = 0, j = 0;
	if(len < 7)
	{
		printf("命令過短\r\n");
		return 0;
	}
	
	// 命令格式校驗
	if(buf[0] == 'c' && buf[1] == 'm' && buf[2] == 'd' && buf[3] == '#')
	{
		// 解析數據獲取devicestatus 分隔符為'#'
        j = 0;
        i = 4;
        while(buf[i] != '#' && i < len)
        {
            // 數據超長
            if(j >= 9)
            {
				printf("device超長\r\n");
                return 0;
            }
            device[j++] = buf[i++];
        }
        device[j] = '\0';
		
		j = 0;
        i++;
        while(buf[i] != '#' && i < len)
        {
            // 數據超長
            if(j >= 5)
            {
				printf("status超長\r\n");
                return 0;
            }
            status[j++] = buf[i++];
        }
        status[j] = '\0';
		
		// LED1的命令 ON/OFF
		if(0 == strcmp((char *)device, "LED1"))
        {
			if(0 == strcmp((char *)status, "ON"))
			{
				LED1 = 0;
				printf("LED1打開\r\n");
				return 1;
			}
			else if(0 == strcmp((char *)status, "OFF"))
			{
				LED1 = 1;
				printf("LED1關閉\r\n");
				return 1;
			}
			else
			{
				printf("命令錯誤\r\n");
				return 0;
			}  
        }
		else if(0 == strcmp((char *)device, "BEEP"))
        {
			if(0 == strcmp((char *)status, "ON"))
			{
				BEEP = 1;
				printf("BEEP打開\r\n");
				return 1;
			}
			else if(0 == strcmp((char *)status, "OFF"))
			{
				BEEP = 0;
				printf("BEEP關閉\r\n");
				return 1;
			}
			else
			{
				printf("命令錯誤\r\n");
				return 0;
			}  
        }
		else if(0 == strcmp((char *)device, "login"))
        {
			if(0 == strcmp((char *)status, "out"))
			{
				login = 0;
				printf("賬號登出\r\n");
				return 1;
			}
			else
			{
				printf("命令錯誤\r\n");
				return 0;
			}  
        }
		else
		{
			printf("命令錯誤\r\n");
			return 0;
		}
	}
	else
	{
		printf("命令錯誤\r\n");
		return 0;
	}
}



usart1.c
#include "usart1.h"
#include "stdio.h"

static uint8_t usart1_buffer[255];
static uint8_t usart1_index;
static uint8_t usart1_count;

//加入以下代碼,支持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 

// USART1初始化 默認數據位8 停止位1 校驗位none
void usart1_init(u32 bound)
{
    // GPIO端口設置
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    /* config USART1 clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); // 使能USART1,GPIOA時鍾

    /* USART1 GPIO config */
    /* Configure USART1 Tx (PA.09) as alternate function push-pull */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推挽輸出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化GPIOA.9
    /* Configure USART1 Rx (PA.10) as input floating */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空輸入
    GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA.10

    // Usart1 NVIC 配置
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//搶占優先級3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;		//子優先級3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);	//根據指定的參數初始化VIC寄存器

    USART_InitStructure.USART_BaudRate = bound; // 串口波特率
    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(USART1, &USART_InitStructure); // 初始化串口1
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // 開啟串口接受中斷

    USART_Cmd(USART1, ENABLE); // 使能串口1

    usart1_index=0;
    usart1_count=0;
}

// 中斷服務函數
void USART1_IRQHandler(void)
{
    // 接收中斷
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {
        if(usart1_count==usart1_index)
        {
            // 緩存區無數據,回到起點開始存儲
            usart1_count=0;
            usart1_index=0;
        }
        usart1_buffer[usart1_count]=USART1->DR;
        usart1_count++;
        if(usart1_count>=250)
        {
            // 沒有及時取出數據,導致存儲位置到達末尾,回到起點
            usart1_count=0;
            usart1_index=0;
        }
    }
}

/*返回緩存區數據的個數*/
uint8_t usart1_getdata_count(void)
{
    return usart1_count-usart1_index;
}

/*返回緩存區當前指針所指數據*/
uint8_t usart1_receive_data(void)
{
    return usart1_buffer[usart1_index++];
}

/*串口數據發送函數
data_send:發送數據
*/
void usart1_send_byte(uint8_t data_send)
{
    USART_SendData(USART1, data_send);
    while (!(USART1->SR & USART_FLAG_TXE));
}

/*串口數據發送函數
data_buffer:發送數據串的首地址
length:發送數據的長度
*/
void usart1_send_bytes(uint8_t* data_buffer,uint8_t length)
{
    uint8_t i;
    for(i=0; i<length; i++)
    {
        usart1_send_byte(data_buffer[i]);
    }
}


免責聲明!

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



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