STM32F103ZET6学习记录-串口通信部分

  1.      开发板原理图

本次实验使用的串口是USART1串口,而它的读写管脚挂接在GPIOA的9、10脚上。如下图

2.   准备工作(此次实验根据上一次的PWM的程序进行改造得来)

串口的使用对于单片机来讲是公用的,也就是说我们这次所书写的程序可以用于以后的程序来使用,

所以可以将该实验的程序代码放在一个公共文件夹我命名为Public(我看的视频教程中的文件夹就是这样,哈哈)中,

和位带程序和Systick程序一起。

 

操作过程复述:

串口配置函数:

(1)     建立Usart.cUsart.h文件,存放于Public文件,添加到工程里。

(2)     查找rcc.h文件,发现USART1串口挂接在APB2总线上,于是先使能APB2总线。


     (3)     既然USART1的读写口都挂接在GPIOA上,就需要将GPIOA使能,

为了增强程序的可移植性,将GPIOA宏定义为USART1_GPIO,相应的管脚也宏定义

使能USART_GPIO

下面配置需要使用的GPIOA的管脚。

 基本步骤,定义一个结构体后配置好相应的参数。

两个管脚的模式为什么要这样设定我还不是很懂。

接下来是串口的配置了。

(4)     类似于GPIO的初始化操作一样。

结构体有6个参数

USART_BaudRate  					比特率
USART_WordLength  					数据字节长度
USART_StopBits						停止位长度
USART_Parity						奇偶校验选项
USART_HardwareFlowControl				硬件流控制选项
USART_Mode						串口模式选项

之后是使能串口

下一步是清除串口中断的标志位,可以不加,加上过后可以提高程序的稳定性。

USART_FLAG_TC表明串口中断完成。

下面是使能串口中断(让串口可以接收中断)

USART_IT_RXNE:接收中断

 

 

(5)最后设置NVIC相关操作。

所有关于串口中断的启动程序就写完了,下面就是关于中断服务函数的书写。

 

 

中断服务函数:

实现的功能是PC向单片机发送数据,然后单片机将数据回显给PC机。

首先,需要有一个可以存储我们PC机发送数据的一个临时变量,首先让变量等于我们的PC机发送的数据,然后再将该变量回发给我们的PC机即可,

 

 

 

while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);

这句话的意思是,当我们的串口发送完成的时候,函数返回值是1,而SET在库函数中的值也是1,此时就会使得while内的条件为0,即为假,while循环便会退出,完成一次中断的服务。

而没有完成发送的时候,函数的返回值是0,while内的条件一直是1,循环就不会退出,使得我们可以继续发送数据,直到我们的数据发送完成。

 

下面是代码部分

Usart.h

#ifndef _USART_H
#define _USART_H


#include "system.h"

void USART1_Init(u32 bound);

#define 	USART1_TX_PIN 	GPIO_Pin_9
#define 	USART1_RX_PIN 	GPIO_Pin_10
#define 	USART1_GPIO 		GPIOA


#endif

 

Usart.c

#include "Usart.h"

//时间:2020-1-14
//制作者:SaBo
//适用:STM32F103ZET6 (普中科技 PZ6800L)


//串口的初始化函数,GPIO、NVIC、USART初始化的程序书写地方
void USART1_Init(u32 bound)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;//定义结构体变量
    USART_InitTypeDef USART_InitStructure;


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);


    //GPIOA_PIN_9是输出数据的管脚,设置为复用输出模式
    //TX
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;  //选择你要设置的IO口
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;	 //设置推挽输出模式
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;	  //设置传输速率

    GPIO_Init(USART1_GPIO,&GPIO_InitStructure); 	   /* 初始化GPIO */

    //GPIOA_PIN_10是数据的接收管脚,设置为浮空输入模式
    //RX
    GPIO_InitStructure.GPIO_Pin=USART1_RX_PIN;  //选择你要设置的IO口
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;	 //设置推挽输出模式

    GPIO_Init(USART1_GPIO,&GPIO_InitStructure); 	   /* 初始化GPIO */


    //串口配置
    USART_InitStructure.USART_BaudRate=bound;														//波特率由参数设置
    USART_InitStructure.USART_WordLength=USART_WordLength_8b;						//八个字节长度
    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);

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

    //清除标志位
    USART_ClearFlag(USART1,USART_FLAG_TC);//发送完成的标识清除,用于增加程序的健壮性

    //使能中断
    USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);


    //设置优先级
    NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;
    NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
    NVIC_Init(&NVIC_InitStructure);


}

//中断服务函数
void USART1_IRQHandler()
{
    u8 r;
    //不等于0,就是接收到中断,执行服务函数
    if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)
    {
        //按字节接收
        //接收数据函数
        r=USART_ReceiveData(USART1);
        USART_SendData(USART1,r);   //发送数据函数
        //发送完成的标识
        while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//发送完成的话,这个标识会被置为1,当返回值是1的时候,就会退出这个while循环表明我们的数据发送完成。
    }

}

 

main.c


#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "pwm.h"
#include "Usart.h"
//时间:2020-1-14
//制作者:SaBo
//适用:STM32F103ZET6 (普中科技 PZ6800L)

/*********************************************
	程序写好后,下载到开发板上,打开我们的串口调试助手,
	设置波特率为9600,数据位8位,停止位1位
	发送什么就会在串口调试助手上回显出来。
	led1的闪烁表明我们的程序是否正常在进行。(检测作用)
*********************************************/


//---------------------------------------
//名称:主函数
//适用:STM32F103ZET6 (普中科技 PZ6800L)
//日期:2020-1-14
//---------------------------------------
int main()
{
	u8 i;
	SysTick_Init(72);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	LED_Init();
	USART1_Init(9600);
	
	while(1)
	{
		i++;
		if(i%20 == 0)
			led1=!led1;
		delay_ms(10);
	}
	
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值