实验4:串口通讯实验

一、串口通信协议简介

    (0)串口线及电平简介

    (1)物理层

            1》RS232标准

            2》USB转串口

            3》原生的串口到串口

    (2)协议层

            起始位:由1个逻辑0的数据位表示。

            数据位:在起始位后紧接着的就是有效数据,有效数据的长度常被约定为 5、 6、 7 或 8 位长。

            校验位:可选,为的是数据的抗干扰性。 校验方法分为:

                           (1)奇校验(odd) 

                                 有效数据和校验位中“ 1”的个数为奇数。

                                 比如一个 8 位长的有效数据为: 01101001,此时总共有 4 个“ 1”,为达到奇校验效果,校验位为“ 1”,最后传输的数据将是 8 位的有效数据加上 1 位的校验位总共 9 位。

                           (2)偶校验(even)

                                 有效数据和校验位中“ 1”的个数为偶数。

                                 比如一个 8 位长的有效数据为: 01101001,此时总共有 4 个“ 1”,为达到偶校验效果,校验位为“ 0”,最后传输的数据将是 8 位的有效数据加上 1 位的校验位总共 9 位。

                           (3)0校验(space)

                                 是不管有效数据中的内容是什么,校验位总为“ 0”。

                           (4)1校验(mark)

                                 是不管有效数据中的内容是什么,校验位总为“ 1”。

                           (5)无校验(noparity)

                                 数据包中不包含校验位。

            停止位:由 0.5、 1、 1.5 或 2 个逻辑 1 的数据位表示。

二、原理图

三、串口功能框图

    (1)引脚

            TX:数据发送

            RX:数据接收

            SCLK:时钟,仅同步通信时使用

            nRTS:请求发送

            nCTS:允许发送

    (2)数据寄存器

            9位有效,包含一个发送数据寄存器TDR和一个接收数据寄存器RDR。一个地址对应了两个物理寄存器。

    (3)控制器

            标志:

                     TXE---发送完成,当该位被置1的时候,表示 USART_DR 内的数据已经被发送完成了。

                     TXEIE---发送完成时产生中断。

                     TC---发送完成,当该位被置1的时候,表示 USART_DR 内的数据已经被发送完成了。

                     TCIE---发送完成时产生中断。

                     RXNE---读数据寄存器非空,当该位被置 1 的时候,就是提示已经有数据被接收到了,并
且可以读出来了。

                     RXNEIE---接收数据寄存器非空时产生中断。

    (4)波特率

            每秒钟要发送多少数据。

四、结构体初始化    

    typedef struct
    {

        uint32_t   USART_BaudRate;

        uint16_t   USART_WordLength;

        uint16_t   USART_StopBits;

        uint16_t   USART_Parity;

        uint16_t   USART_Mode;

        uint16_t   USART_HardwareFlowControl;

    } USART_InitTypeDef;

    USART_BaudRate:设置串口波特率。

                                      115200

    USART_WordLength:设置串口字长。

                                          USART_WordLength_8b

    USART_StopBits:设置串口停止位。

                                   USART_StopBits_1

    USART_Parity:设置串口校验位。

                                USART_Parity_No

    USART_Mode:设置模式。

                               USART_Mode_Tx

                               USART_Mode_Rx

    USART_HardwareFlowControl:设置硬件流控。

                                                         USART_HardwareFlowControl_None

五、常用固件库函数

    (1)配置GPIO为具体的第二功能

            void GPIO_PinAFConfig (GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF);

    (2)中断配置函数

            void USART_ITConfig (USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);

    (3)串口使能函数

            void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);

    (4)数据发送函数

            //将数据data写入到数据寄存器USART_DR中

            void USART_SendData (USART_TypeDef* USARTx, uint16_t Data);

    (5)数据接收函数

            //从数据寄存器USART_DR中读取接收到的数据

            uint16_t USART_ReceiveData(USART_TypeDef* USARTx);

    (6)中断状态位获取函数

            //读取状态寄存器USART_SR中指定位的值

            ITStatus USART_GetITStatus (USART_TypeDef* USARTx, uint16_t USART_IT);

六、程序

bsp_usart.h文件

#ifndef __BSP_USART_H__
#define __BSP_USART_H__

#include "stm32f4xx_conf.h"

//USART配置
extern void USART_Config(void);
//发送一个字符
extern void USART_SendByte(uint8_t ch);
//发送一个字符串
extern void USART_SendString(char *str);

#endif

bsp_usart.c文件

#include "./usart/bsp_usart.h"
#include "stdio.h"

/*
    Tx---PA9;Rx---PA10
*/

/*******************
    功能:配置串口
    参数:无
    返回值:无
********************/
void USART_Config(void)
{
    GPIO_InitTypeDef initValue;
    USART_InitTypeDef usartInitValue;
    NVIC_InitTypeDef nvicInitValue;
    
    /*1、打开时钟*/
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
    
    /*2、配置GPIO的复用功能*/
    initValue.GPIO_Mode = GPIO_Mode_AF;
    initValue.GPIO_OType = GPIO_OType_PP;
    initValue.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
    initValue.GPIO_PuPd = GPIO_PuPd_NOPULL;
    initValue.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&initValue);
    
    /*3、选择复用管脚*/
    GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
    GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
    
    /*4、初始化串口*/
    usartInitValue.USART_BaudRate = 115200;
    usartInitValue.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    usartInitValue.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
    usartInitValue.USART_Parity = USART_Parity_No;
    usartInitValue.USART_StopBits = USART_StopBits_1;
    usartInitValue.USART_WordLength = USART_WordLength_8b;
    USART_Init(USART1,&usartInitValue);
    
    /*5、配置NVIC*/
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    nvicInitValue.NVIC_IRQChannel = USART1_IRQn;
    nvicInitValue.NVIC_IRQChannelCmd = ENABLE;
    nvicInitValue.NVIC_IRQChannelPreemptionPriority = 1;
    nvicInitValue.NVIC_IRQChannelSubPriority = 1;
    NVIC_Init(&nvicInitValue);
    
    /*6、打开串口的接收中断*/
    USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);

    /*7、使能串口*/
    USART_Cmd(USART1,ENABLE);
}

/********************
    功能:发送一个字符
  参数:要发送的字符
    返回值:无
*********************/
void USART_SendByte(uint8_t ch)
{
    /*1、发送字符*/
    USART_SendData(USART1,ch);
    
    /*2、等待字符发送完成*/
    while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
    
}

/**********************
    功能:发送一个字符串
    参数:要发送的字符串
    返回值:无
***********************/
void USART_SendString(char *str)
{
    do
    {
        USART_SendByte(*str);
        str++;
    }while(*str != '\0');
    
    /*2、等待发送完成*/
    while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);
}

/*
    功能:重定向C库函数printf到串口,重定向后可使用printf函数
    参数:ch---要发送的数据
    返回值:发送的数据
*/
int fputc(int ch,FILE *f)
{
    /*1、发送一个字节的数据到串口*/
    USART_SendData(USART1,(uint8_t)ch);
    
    /*2、等待数据的发送完成*/
    while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
    
    return ch;
}


/*
    功能:重定向C库函数scanf到串口,重定向后可使用scanf、getchar等函数
    参数:
    返回值:接收到的数据
*/
int fgetc(FILE *f)
{
    /*1、等待串口输入数据*/
    while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == RESET);
    
    /*2、接收数据*/
    return (int)USART_ReceiveData(USART1);
}

main.c文件

#include "delay.h"
#include "stdio.h"
#include "./LED/led.h"
#include "./USART/usart.h"

int main(void)
{
    uint8_t ch;
    
    //配置串口
    USART_Config();
    
    //发送一个字符
    USART_SendByte('A');
    
    //发送一个字符串
    USART_SendString("今天是个好日子!!! \r\n");
    
    //检验printf函数
    printf("你的声音真好听!!! \r\n");
    
    //检验scanf函数
    scanf("%c",&ch);
    
    while(1)
    {
        if(ch == '0')
        {
            LED_ON(1);
            LED_ON(3);
        }
    }
}

stm32f4xx_it.c文件

/***********************************
    功能:USART1中断服务函数
    参数:无
    返回值:无
************************************/
void USART1_IRQHandler(void)
{
    uint8_t ch;
    /*1、判断是否由于接收数据产生的中断*/
    if(USART_GetITStatus(USART1,USART_IT_RXNE) == SET)
    {
        /*2、接收数据*/
        ch = USART_ReceiveData(USART1);
        
        /*3、将接收到的数据发送出去*/
        USART_SendData(USART1,ch);
        
        /*4、清除中断标志位*/
        USART_ClearITPendingBit(USART1,USART_IT_RXNE);
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值