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

 

上一篇:35.XDMA原理详解1-DMA描述符概述及DMA数据传输框图


下一篇:2021/10/15 智能家具 嵌入式实训 第五天 串口通信 (1)