1. 程式人生 > 其它 >2021/10/15 智慧傢俱 嵌入式實訓 第五天 串列埠通訊傳送指令控制部件執行 (led beep)

2021/10/15 智慧傢俱 嵌入式實訓 第五天 串列埠通訊傳送指令控制部件執行 (led beep)

先看usart.h

#ifndef __USART_H
#define __USART_H

/* 標頭檔案 */
#include "stm32f10x.h"
#include "stdio.h"
#include "led.h"
#include "beep.h"

/* 串列埠接收資訊封裝 */
typedef struct{
    u8 rx_buff[16]; //儲存接收到的資料
    u8 count;       //記錄接收到資料的個數
    u8 flag;        //狀態:0 -- 正在接收 , 1 -- 接收完成
}USART_RX_Message;
extern USART_RX_Message usart1_rx;

/* 函式介面 */ void Usart1_Config(u32 brr); //初始化 void USART1_Test(void); //串列埠通訊(上位機控制下位機) void USART1_Echo(void); //串列埠回顯 #endif

再看usart.c

#include "usart.h"

USART_RX_Message usart1_rx; //USART1接收封裝
/* 私有函式 */
void USART1_DataTest(u8 *pdata);
/***********************************************************************************
函式功能:USART1初始化 (USB轉串列埠——USART1)
形參:brr -- 波特率
返回值:無
**********************************************************************************
*/ /* 管腳: USART1_Tx PA9 複用推輓輸出 USART1_Rx PA10 浮空輸入 */

定義了變數 和函式

下面usart使能

void Usart1_Config(u32 brr)
{
    /* 配置GPIO */
    //1. 時鐘使能
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    //2. 配置模式
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Speed 
= GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//推輓輸出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_Init(GPIOA, &GPIO_InitStructure); /* 配置USART模式 */ //1. 時鐘使能 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //2. 模式配置 USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = brr; //波特率 (資料傳輸速度) USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //非硬體流 (如何決定收發的時機) USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收發模式 (全雙工) USART_InitStructure.USART_WordLength = USART_WordLength_8b; //RS232協議(資料格式):資料位 8個 USART_InitStructure.USART_Parity = USART_Parity_No; //RS232協議(資料格式):奇偶校驗位 0個 USART_InitStructure.USART_StopBits = USART_StopBits_1; //RS232協議(資料格式):停止位 1個 USART_Init(USART1, &USART_InitStructure); //3. 配置接收中斷(串列埠回顯時註釋掉) USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //接收中斷開啟 NVIC_InitTypeDef NVIC_InitStruct = {0}; NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; NVIC_Init(&NVIC_InitStruct); //4. 初始狀態 -- 使能 USART_Cmd(USART1, ENABLE); }

中斷服務函式

/*
* USART1中斷服務函式
* 通訊格式:0xFF(開始碼)+ 資料+ 0x66(結束碼)  -- 最大16byte
*/
void USART1_IRQHandler(void)
{
    u8 temp = 0;
    if(USART_GetITStatus(USART1,USART_IT_RXNE) == SET)  //接收中斷觸發
    {
        USART_ClearITPendingBit(USART1,USART_IT_RXNE);  //清除中斷標誌位
        temp = USART1->DR;
        if(temp != 0xFF && usart1_rx.count == 0)  return;   //開始碼錯誤或沒有資料 -> 返回
        else 
        {
            usart1_rx.rx_buff[usart1_rx.count++] = temp;
            if(temp == 0x66)    usart1_rx.flag = 1;         //收到結束碼 -> 接收完成標誌位置1
        }
    }

函式介面函式 定義flag buff[0]資料頭

/***********************************************************************************
函式功能: USART1 函式介面
***********************************************************************************/
void USART1_Test(void)
{
    if(usart1_rx.flag != 1)           return;             //沒有接收完畢->返回
    if(usart1_rx.rx_buff[0] != 0xFF)  goto CLEAR_OVER;    //接收到的資料幀頭不是FF -> 資料錯誤
    USART1_DataTest(&usart1_rx.rx_buff[1]);               //串列埠通訊資料解析
CLEAR_OVER:
    usart1_rx.count = 0;
    usart1_rx.flag  = 0;
}
/*
*串列埠通訊資料解析
*/
void USART1_DataTest(u8* pdata)
{
    switch(pdata[0])
    {
        case 0:     if(pdata[1] == 1)                   // 00 + 01 
                    {
                        BEEP(ON);LED1(ON);
                    }
                    else if(pdata[1] == 0)              // 00 + 00
                    {
                        BEEP(OFF);LED1(OFF);
                    }
                    break;
        case 1:     if(pdata[1] == 1)       LED1(ON);   // 01 + 01 
                    else if(pdata[1] == 0)  LED1(OFF);  // 01 + 00
                    break;
        case 2:     if(pdata[1] == 1)       BEEP(ON);   // 02 + 01
                    else if(pdata[1] == 0)  BEEP(OFF);  // 02 + 00
                    break;
    }
}

串列埠回顯

/*
* 串列埠回顯
*/
void USART1_Echo(void)
{
    u8 data = 0;
    while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == RESET);
    data = USART1->DR;
    while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);
    USART1->DR = data;
}

串列埠顯示

/*
* 串列埠列印
*/ 
int fputc(int c, FILE * stream)
{
    while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); // 傳送完畢 -- SET
    USART1->DR = c;                                             //把要列印的內容存到USART1的資料暫存器中
    return c;
}

main函式中新增

#include "main.h"

void JTAG_SWD_Config(void);
/***********************************************************************************
函式功能:main函式
形參:無
返回值:無
***********************************************************************************/
int main(void)
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    JTAG_SWD_Config();
    LED_Config(ON); 
    BEEP_Config();
    KEY_Config();
    EXTI0_Config();
    Motor_Config();
    RGB_Config();
    Relay_Config();

    
    //今日內容:串列埠通訊
    Usart1_Config(9600);
    while(1)
    {         
        //上位機控制下位機
        USART1_Test();
                    USART1_Echo();   
      Dht11_ReadData();        
    }
}
/***********************************************************************************
函式功能:下載介面管腳重對映
形參:無
返回值:無
***********************************************************************************/
void JTAG_SWD_Config(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);          //AFIO時鐘使能
//    GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);         //完全禁用SWD及JTAG 
    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);     //禁用JTAG        
}

主要是

//今日內容:串列埠通訊
Usart1_Config(9600);

//上位機控制下位機
USART1_Test();
USART1_Echo();

原始檔:

https://wwa.lanzoui.com/ivndmvh1uih