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);
}
}
加油^ ^