第三:串口收发

在这里插入图片描述

三、串口收发

目标:

前边工程写的震动LED亮一秒依然有效,但不能影响串口对灯的控制

上电串口向PC机发送 “hello usart”,

PC机发送’O’ led灯打开,返回"ON OK",

PC机发送’C’ led灯熄灭,返回"OFF OK",

如果PC机发送其他字符,返回"ERROR".

串口对灯的控制权应该比震动传感器大

引脚:

PA9 :TX

PA10:RX

步骤:

1、创建文件

在工程目录下边创建usart.c和usart.h两个文件

2、编写代码

usart.c

#include "usart.h"
#include "stm32f10x.h"

void usart_init(void)
{
	GPIO_InitTypeDef usart_gpio_init;  //声明配置PA9:TX,和PA10:RX的结构体
	USART_InitTypeDef  usart_init;     //声明配置串口usart1的结构体
	NVIC_InitTypeDef usart_nvic_init;
	
	
	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA的时钟(PA9:USART1_TX,PA10:USART1_RX)
	RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO, ENABLE);  //使能引脚复用时钟
	RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1, ENABLE);//使能usart1时钟
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //设置优先级组
	
	
	//配置PA9 TX的结构体
	usart_gpio_init.GPIO_Mode  = GPIO_Mode_AF_PP;
	usart_gpio_init.GPIO_Pin   = GPIO_Pin_9;
	usart_gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOA, &usart_gpio_init);  //初始化PA9
	
	
	//配置PA10 RX的结构体
	usart_gpio_init.GPIO_Mode  = GPIO_Mode_IN_FLOATING;
	usart_gpio_init.GPIO_Pin   = GPIO_Pin_10;
	
	GPIO_Init(GPIOA, &usart_gpio_init); //初始化PA10
	
	
	//配置串口usaet1的结构体
	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_Cmd(USART1, ENABLE);
	
	
	//配置NVIC(中断控制器)(用中断的方式接收PC机的数据)
	usart_nvic_init.NVIC_IRQChannel = USART1_IRQn;    
	usart_nvic_init.NVIC_IRQChannelCmd = ENABLE;
	usart_nvic_init.NVIC_IRQChannelPreemptionPriority = 1;
	usart_nvic_init.NVIC_IRQChannelSubPriority = 1;
	
	NVIC_Init(&usart_nvic_init);
	
	//使能usart1中断
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
}

//封装发送字符串的函数
void Send_String(char *P)
{
	while(*P != '\0')
	{
		USART_SendData(USART1,*P++);   //发送一个字节
		while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
	}
}

//重定向printf函数,使用printf就可以输出到串口上(不需要声明)
int fputc(int ch,FILE *f)
{
	USART_SendData(USART1,(unsigned int)ch);  //发送数据
	while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);  //等待发送结束
	return ch;
}

//重定向scanf函数,(不需要声明)
int fgetc(FILE *f)
{
	//等待接收完
	while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == RESET);
	
	return (int)USART_ReceiveData(USART1);   //返回接收到的数据
}

usart.h

#include "stdio.h"
//#include "stm32f10x.h"

void usart_init(void);
void Send_String(char *P);

main.c改为:

#include "stm32f10x.h"
#include "main.h"
#include "led.h"     //引入LED相关的文件
#include "exti.h"	//加入刚写的外部中断相关文件
#include "usart.h"  //加入串口相关文件

char buff;  //用来接收PC机发送的数据


void delay(uint16_t time)
{
	uint16_t i = 0;
	while(time--)
	{
		i = 8000;
		while(i--);	
	}
}

int  main()
{
	LED_Init();     //初始化LED(PC13引脚)
	Exti_Init();	//初始化外部中断1
	usart_init();   //初始化串口usart1
	
	
	GPIO_SetBits(GPIOC,GPIO_Pin_13);   //让LED上电的时候熄灭
	
	Send_String("hello usart");  //上电发送"hello usart"
	
	//空循环,等待中断
	while(1)
	{	

	} 	
}

//串口接收的中断函数
void USART1_IRQHandler()
{
	if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET)  //如果接收标志位为SET,则接收完成
	{
		buff = (char)USART_ReceiveData(USART1);   //将数据读到buff变量中
		
		if( buff == 'O'){
			GPIO_ResetBits(GPIOC,GPIO_Pin_13);  //开灯
			Send_String("ON OK\r\n");   //返回相关字符
		}else if(buff == 'C'){
			GPIO_SetBits(GPIOC,GPIO_Pin_13);  //关灯
			Send_String("OFF OK\r\n");
		}else{
			Send_String("ERROR\r\n");
		}
	}
}

//外部中断1服务函数
void EXTI1_IRQHandler(void)
{
	if( EXTI_GetITStatus( EXTI_Line1) != RESET ) //如果中断标志位不是低电平(当PA1有下降沿时,触发中断)
	{
		GPIO_ResetBits(GPIOC,GPIO_Pin_13);		//PC13拉低,点亮LED灯
		delay(1000);							//延时1000ms
		if(buff != 'O'){						//震动传感器不能影响串口对灯的控制
			GPIO_SetBits(GPIOC,GPIO_Pin_13);		//PC13拉高,熄灭LED灯
		}
		EXTI_ClearFlag( EXTI_Line1);			//清除标志位,等待下一次中断
	}
}

3、编译烧录

使用FlyMcu.exe烧录程序

4、打开串口调试助手

发送’O’,‘C’,和其他字符,观察现象;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值