最近在学单片机的串口,首先从串口发送接收开始吧,串口发送比较简单,下面讲讲串口接收字符串的情况。
单片机型号用的是 stm32f103rct6,IDE版本是keil 5。本代码是操作寄存器实现串口接收字符串。代码如下:
usart.h
#ifndef USTART_H
#define USTART_H
#include <stm32f10x.h>
#include <stm32f10x_usart.h>
#include "sys.h"
void USART1_Init();
void USART_SendString(USART_TypeDef* USARTx, char *DataString);
#endif
usart.c
#include "usart.h"
#include <string.h>
#include "stdio.h" //ucos 使用
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (u8) ch;
return ch;
}
#endif
void USART1_Init()
{
GPIO_InitTypeDef GPIOInit_Struct;
USART_InitTypeDef USARTInit_Struct;
//1、使能时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
//2、初始化对应的IO引脚复用为USART1功能
//RCC_AHB1PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIOInit_Struct.GPIO_Mode=GPIO_Mode_AF_PP;
GPIOInit_Struct.GPIO_Pin=GPIO_Pin_9;
GPIOInit_Struct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIOInit_Struct);
/* 将USART RX(A10)的GPIO设置为浮空输入模式 */
GPIOInit_Struct.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIOInit_Struct.GPIO_Pin=GPIO_Pin_10;
GPIO_Init(GPIOA,&GPIOInit_Struct);
//将PA9 PA10复用为USART1功能
//GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
//GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
//3、USART1初始化
USARTInit_Struct.USART_BaudRate = 115200; //波特率
USARTInit_Struct.USART_Parity = USART_Parity_No; //无校验位
USARTInit_Struct.USART_StopBits = USART_StopBits_1; //1位停止位
USARTInit_Struct.USART_WordLength = USART_WordLength_8b; //8位数据位
USARTInit_Struct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USARTInit_Struct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件控制流
USART_Init(USART1,&USARTInit_Struct);
//4、开启串口
USART_Cmd(USART1,ENABLE);
}
void USART_SendString(USART_TypeDef* USARTx, char *DataString)
{
int i = 0;
USART_ClearFlag(USARTx,USART_FLAG_TC); //发送字符前清空标志位(否则缺失字符串的第一个字符)
while(DataString[i] != '\0') //字符串结束符
{
USART_SendData(USARTx,DataString[i]); //每次发送字符串的一个字符
while(USART_GetFlagStatus(USARTx,USART_FLAG_TC) == 0); //等待数据发送成功
USART_ClearFlag(USARTx,USART_FLAG_TC); //发送字符后清空标志位
i++;
}
}
led.c
#include "led.h"
//初始化PB5和PE5为输出口.并使能这两个口的时钟
//LED IO初始化
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD, ENABLE); //使能PA,PD端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //LED0-->PA.8 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA.8
GPIO_SetBits(GPIOA,GPIO_Pin_8); //PA.8 输出高
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //LED1-->PD.2 端口配置, 推挽输出
GPIO_Init(GPIOD, &GPIO_InitStructure); //推挽输出 ,IO口速度为50MHz
GPIO_SetBits(GPIOD,GPIO_Pin_2); //PD.2 输出高
}
led.h
#ifndef __LED_H
#define __LED_H
#include "sys.h"
#define LED0 PAout(8) // PA8
#define LED1 PDout(2) // PD2
void LED_Init(void);//初始化
#endif
main.c 代码如下:
#include "stm32f10x.h"
#include "led.h"
#include "usart.h"
#include <stdio.h>
int main()
{
char USART1_ReceiveData = 0;
LED_Init(); //LED灯初始化
USART1_Init(); //串口初始化
USART_SendString(USART1, "Hello world!\r\n"); //发送字符串
//接收PC端发送过来的字符
USART_ClearFlag(USART1,USART_FLAG_RXNE); //接收前先清空标志位
while(1)
{
if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == 1) //USART_FLAG_RXNE判断数据,== 1则有数据
{
USART1_ReceiveData = USART_ReceiveData(USART1); //通过USART1串口接收字符
USART_ClearFlag(USART1,USART_FLAG_RXNE); //接收后先清空标志位
}
if( '1' == USART1_ReceiveData ) //如果数据为1,LED1灯电平翻转
{
LED0 =0;
}
if( '2' == USART1_ReceiveData ) //如果数据为2,LED2灯电平翻转
{
LED0=1;
}
USART1_ReceiveData = 0; //数据清零
}
}
版权声明:本文为CSDN博主「朝朝暮暮柳十岁」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42952472/article/details/122594719
最近在学单片机的串口,首先从串口发送接收开始吧,串口发送比较简单,下面讲讲串口接收字符串的情况。
单片机型号用的是 stm32f103rct6,IDE版本是keil 5。本代码是操作寄存器实现串口接收字符串。代码如下:
usart.h
#ifndef USTART_H
#define USTART_H
#include <stm32f10x.h>
#include <stm32f10x_usart.h>
#include "sys.h"
void USART1_Init();
void USART_SendString(USART_TypeDef* USARTx, char *DataString);
#endif
usart.c
#include "usart.h"
#include <string.h>
#include "stdio.h" //ucos 使用
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (u8) ch;
return ch;
}
#endif
void USART1_Init()
{
GPIO_InitTypeDef GPIOInit_Struct;
USART_InitTypeDef USARTInit_Struct;
//1、使能时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
//2、初始化对应的IO引脚复用为USART1功能
//RCC_AHB1PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIOInit_Struct.GPIO_Mode=GPIO_Mode_AF_PP;
GPIOInit_Struct.GPIO_Pin=GPIO_Pin_9;
GPIOInit_Struct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIOInit_Struct);
/* 将USART RX(A10)的GPIO设置为浮空输入模式 */
GPIOInit_Struct.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIOInit_Struct.GPIO_Pin=GPIO_Pin_10;
GPIO_Init(GPIOA,&GPIOInit_Struct);
//将PA9 PA10复用为USART1功能
//GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
//GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
//3、USART1初始化
USARTInit_Struct.USART_BaudRate = 115200; //波特率
USARTInit_Struct.USART_Parity = USART_Parity_No; //无校验位
USARTInit_Struct.USART_StopBits = USART_StopBits_1; //1位停止位
USARTInit_Struct.USART_WordLength = USART_WordLength_8b; //8位数据位
USARTInit_Struct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USARTInit_Struct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件控制流
USART_Init(USART1,&USARTInit_Struct);
//4、开启串口
USART_Cmd(USART1,ENABLE);
}
void USART_SendString(USART_TypeDef* USARTx, char *DataString)
{
int i = 0;
USART_ClearFlag(USARTx,USART_FLAG_TC); //发送字符前清空标志位(否则缺失字符串的第一个字符)
while(DataString[i] != '\0') //字符串结束符
{
USART_SendData(USARTx,DataString[i]); //每次发送字符串的一个字符
while(USART_GetFlagStatus(USARTx,USART_FLAG_TC) == 0); //等待数据发送成功
USART_ClearFlag(USARTx,USART_FLAG_TC); //发送字符后清空标志位
i++;
}
}
led.c
#include "led.h"
//初始化PB5和PE5为输出口.并使能这两个口的时钟
//LED IO初始化
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD, ENABLE); //使能PA,PD端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //LED0-->PA.8 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA.8
GPIO_SetBits(GPIOA,GPIO_Pin_8); //PA.8 输出高
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //LED1-->PD.2 端口配置, 推挽输出
GPIO_Init(GPIOD, &GPIO_InitStructure); //推挽输出 ,IO口速度为50MHz
GPIO_SetBits(GPIOD,GPIO_Pin_2); //PD.2 输出高
}
led.h
#ifndef __LED_H
#define __LED_H
#include "sys.h"
#define LED0 PAout(8) // PA8
#define LED1 PDout(2) // PD2
void LED_Init(void);//初始化
#endif
main.c 代码如下:
#include "stm32f10x.h"
#include "led.h"
#include "usart.h"
#include <stdio.h>
int main()
{
char USART1_ReceiveData = 0;
LED_Init(); //LED灯初始化
USART1_Init(); //串口初始化
USART_SendString(USART1, "Hello world!\r\n"); //发送字符串
//接收PC端发送过来的字符
USART_ClearFlag(USART1,USART_FLAG_RXNE); //接收前先清空标志位
while(1)
{
if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == 1) //USART_FLAG_RXNE判断数据,== 1则有数据
{
USART1_ReceiveData = USART_ReceiveData(USART1); //通过USART1串口接收字符
USART_ClearFlag(USART1,USART_FLAG_RXNE); //接收后先清空标志位
}
if( '1' == USART1_ReceiveData ) //如果数据为1,LED1灯电平翻转
{
LED0 =0;
}
if( '2' == USART1_ReceiveData ) //如果数据为2,LED2灯电平翻转
{
LED0=1;
}
USART1_ReceiveData = 0; //数据清零
}
}
版权声明:本文为CSDN博主「朝朝暮暮柳十岁」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42952472/article/details/122594719
暂无评论