USART串口练习

USART串口练习

这两天学校刚好在教串口的使用,把课堂练习记录一下吧
下面通过PC机发送指令来控制STM32板子的LED状态

一.要求:

1.首先通过以中断的方式发送单个字符来控制led的亮灭   
2.PC机发送字符串“fast"LED0快速闪烁      
3.PC机发送字符串slow"LED0慢速闪烁      
4.PC机发送字符串“alter'实现LED0 和LED1交替闪烁   
5.PC机发送字符串"off"LED熄灭。 

二.串口相关参数配置

这里就不具体介绍串口的一些内部原理了,简单的分享一下需要用到的结构体配置
步骤:
1.使能RX和TX引脚GPIO时钟和USART时钟;
2.初始化GPIO,并将GPIO复用到USART上;
3.配置USART参数;
4.配置中断控制器并使能USART接收中断;
5.使能USART;
6.在USART接收中断服务函数实现数据接收和发送。 .

上代码吧

usart头文件

#ifndef _USART_H_
#define _USART_H_
#include "stm32f10x.h"
#include <stdio.h>
#include <string.h>

void Usart_Init(void);
void USARTSendChar(USART_TypeDef* USARTx, uint16_t Data);
void UsartSendStr(USART_TypeDef* USARTx, char *str);

int fputc(int ch, FILE *f);

int fgetc(FILE *f);
#endif
#include "usart.h"
#include "stm32f10x.h"

void Usart_Init(void)
{
	GPIO_InitTypeDef   Gpio_Init;   //GPIO结构体定义
	USART_InitTypeDef  Usart_Init ;//串口结构体
	NVIC_InitTypeDef nvic_init;  //串口中断
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级配置
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA ,ENABLE);   //gpio时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO ,ENABLE);   //复用时钟
	RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 ,ENABLE); //串口时钟
	
	//配置GPIO结构体  rx
	
	Gpio_Init.GPIO_Mode   =   GPIO_Mode_AF_PP;
	Gpio_Init.GPIO_Pin    =   GPIO_Pin_9   ;
	Gpio_Init.GPIO_Speed  =   GPIO_Speed_50MHz;
	GPIO_Init(GPIOA ,&Gpio_Init);   //初始化GPIO
	
	
	//配置PA10 接受引脚  tx
	Gpio_Init.GPIO_Mode   =    GPIO_Mode_IN_FLOATING;
	Gpio_Init.GPIO_Pin    =    GPIO_Pin_10 ;
	GPIO_Init(GPIOA ,&Gpio_Init);
	
	
	//串口结构体配置
	Usart_Init.USART_BaudRate     =  115200;  //波特率
	Usart_Init.USART_HardwareFlowControl  = USART_HardwareFlowControl_None  ;
	Usart_Init.USART_Mode        =   USART_Mode_Rx  | USART_Mode_Tx  ;  //接受发送均可以
	Usart_Init.USART_Parity      =   USART_Parity_No ;  //优先位
	Usart_Init.USART_StopBits    =   USART_StopBits_1; //停止位
	Usart_Init.USART_WordLength  =   USART_WordLength_8b ;   //位数
	
	USART_Init (USART1 , &Usart_Init);  //初始化
	USART_ITConfig( USART1,  USART_IT_RXNE  , ENABLE);
	USART_Cmd (USART1 ,ENABLE );    //打开串口1
	
	
	
	 nvic_init.NVIC_IRQChannel    =   USART1_IRQn;
	 nvic_init.NVIC_IRQChannelCmd  = ENABLE ;
	 nvic_init.NVIC_IRQChannelPreemptionPriority =1;
	 nvic_init.NVIC_IRQChannelSubPriority   = 1;
	 NVIC_Init(&nvic_init);
		
	
}


//发送字符
void  USARTSendChar(USART_TypeDef* USARTx, uint16_t Data)
{
	
	USART_SendData(USARTx, Data);
	while(USART_GetFlagStatus(USARTx  ,USART_FLAG_TXE ) == RESET);
	
}



//发送字符串
void  UsartSendStr(USART_TypeDef* USARTx, char *str)
{
	uint16_t i=0;
	do
	{
		 USARTSendChar(USARTx ,*(str+i));
		 i++;
	}while(*(str+i)!='\0');
	
	while(USART_GetITStatus( USARTx,USART_FLAG_TC) == RESET) ;  //字符串发送判断

}

//重写printf 相当于c语言中直接使用printf
int fputc(int ch, FILE *f)
{     
	
	USART_SendData(USART1 ,(uint8_t )ch);
	while(USART_GetFlagStatus(USART1  ,USART_FLAG_TXE ) == RESET);
	return (ch);
}

//putchar getchar
int fgetc(FILE *f)
{
	while(USART_GetFlagStatus(USART1  ,USART_FLAG_RXNE  ) == RESET);
	
	return (int)(USART_ReceiveData(USART1));
}

主函数

#include "stm32f10x.h"
#include"delay.h"
#include "usart.h"
#include "led.h"
int  main(void)
{
	
	Usart_Init();//串口初始化
	Led_Init();//led初始化我这里led是PB5 /PE5两个led
	printf("***********************测试实验***********************\r\n");
	while(1)
	{
		
	}
}


//串口中断服务函数
void USART1_IRQHandler()
{
	u8 temp ;//用于接收我们发送的数据
	if( USART_GetITStatus( USART1, USART_IT_RXNE)!=RESET)  //发送中断
	{
		temp =  USART_ReceiveData(USART1);//接收数据
		if(temp == 'O')
		{
			 GPIO_ResetBits(GPIOB, GPIO_Pin_5);
			 UsartSendStr(USART1 ,"LED Open");
		}
	 if(temp == 'C')
		{
				GPIO_SetBits(GPIOB,  GPIO_Pin_5);
		  	UsartSendStr(USART1,"LED Close");
		}
	//	while(USART_GetFlagStatus(USART1,  USART_FLAG_TC)!=SET);

	}
	 USART_ClearITPendingBit(USART1, USART_IT_RXNE);//清除中断标志位
	

}

三.字符串形式控制led

#include "stm32f10x.h"
#include "usart.h"
#include "system.h" //延时函数头文件
#include "led.h"

unsigned char temp[12] ={'\0'};//用于存储接收到的字符串
uint8_t num = 0;//数组下标 用于计算字符串的个数大小
uint8_t flag = 0; //返回标志位在实现相应功能中会使用
int main(void)
{
	
	Init_Led();//led初始化
	Usart_Init();//串口初始化
	printf("**************************测试实验****************************\r\n");
	while(1)
	{
		printf("flag :%d\r\n",flag);//打印出当前状态标志
		delay_ms(2000);
		switch(flag)
		{
		//大家根据自己led来实现相关功能就好了
			case 1:xxxxx;break; //PC机发送字符串“fast"LED0快速闪烁  
			case 2:xxxxx;break;//PC机发送字符串slow"LED0慢速闪烁
			case 3:xxxxx;break;//PC机发送字符串“alter'实现LED0 和LED1交替闪烁   
			case 4:xxxxx;break;//PC机发送字符串"off"LED熄灭。 
		}
	}	
}


//串口中断服务函数
void USART1_IRQHandler()
{
	
	if( USART_GetITStatus( USART1, USART_IT_RXNE) !=RESET)  //发送中断
	{
		temp[num++] =  USART_ReceiveData(USART1);
		if(strcmp(( char *)temp,"fast")== 0)
		{
			 memset(temp,0,sizeof(temp));
			 num = 0;
			 flag = 1;	
		}
	 if(strcmp(( char *)temp,"slow") == 0)
		{
			  memset(temp,0,sizeof(temp));
				num = 0;
				flag = 2;
		}
		if(strcmp(( char *)temp,"alter") == 0)
		{
			  memset(temp,0,sizeof(temp));
				num = 0;
				flag = 3;
		}
		if(strcmp(( char *)temp,"off") == 0)
		{
			  memset(temp,0,sizeof(temp));
				num = 0;
				flag = 4;
		}
		
	//清除中断标志位	USART_ClearITPendingBit(USART1,USART_IT_RXNE);
	
	} 
	
}

加油^ ^

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小殷学长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值