即将放年假了,公司目前也没有什么事情是我可做的,便买了一块便宜的stm32板子重新系统学下单片机。目前学到了串口轮询接收字符串,例程是stm32板子自带的看门狗例程,可以把看门狗的实现函数和头文件注释掉,以免影响编译。
板子主控:stm32rct6,他们的库函数其实都差不多,适当修改下即可。主要实现代码如下:
while(1)
{
if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == 1) //USART_FLAG_RXNE判断数据,== 1则有数据
{ for(i=0;i<5;i++){
while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == 0);
USART1_ReceiveData[i] = USART_ReceiveData(USART1); //通过USART1串口接收字符
USART_ClearFlag(USART1,USART_FLAG_RXNE); //接收后先清空标志位
}
}
if( USART1_ReceiveData[0]=='o' && USART1_ReceiveData[1]=='p' && USART1_ReceiveData[2]=='e' && USART1_ReceiveData[3]=='n') //如果数据为1,LED1灯电平翻转
{
printf("\r\n open light \r\n");
LED0 =0;
}
else if( 'c' == USART1_ReceiveData[0] && USART1_ReceiveData[1]=='l' && USART1_ReceiveData[2]=='o' && USART1_ReceiveData[3]=='s' && USART1_ReceiveData[4]=='e') //如果数据为2,LED2灯电平翻转
{
printf("\r\n close light \r\n");
LED0=1;
}
/*else{
printf("\r\n input error \r\n");
}
*/
//USART1_ReceiveData = 0; //数据清零
}
usart,h
#ifndef __USART_H
#define __USART_H
#include "stdio.h"
#include "sys.h"
//1,增加了对UCOSII的支持
#define USART_REC_LEN 200 //定义最大接收字节数 200
#define EN_USART1_RX 1 //使能(1)/禁止(0)串口1接收
extern u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
extern u16 USART_RX_STA; //接收状态标记
//如果想串口中断接收,请不要注释以下宏定义
void uart_init(u32 bound);
void USART1_Init();
#endif
usart.c
#include "sys.h"
#include "usart.h"
//
//如果使用ucos,则包括下面的头文件即可.
#if SYSTEM_SUPPORT_OS
#include "includes.h" //ucos 使用
#endif
//加入以下代码,支持printf函数,而不需要选择use MicroLIB
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
_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
#if EN_USART1_RX //如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误
u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15, 接收完成标志
//bit14, 接收到0x0d
//bit13~0, 接收到的有效字节数目
u16 USART_RX_STA=0; //接收状态标记
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 USART1_IRQHandler(void) //串口1中断服务程序
{
u8 Res;
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
OSIntEnter();
#endif
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
Res =USART_ReceiveData(USART1); //读取接收到的数据
if((USART_RX_STA&0x8000)==0)//接收未完成
{
if(USART_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
else USART_RX_STA|=0x8000; //接收完成了
}
else //还没收到0X0D
{
if(Res==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
OSIntExit();
#endif
}
#endif
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++;
}
}
main.c
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "wwdg.h"
int main(void)
{
uint16_t i;
char USART1_ReceiveData[6] = {0};
delay_init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
//uart_init(9600);
LED_Init();
//LED0=0;
//delay_ms(300);
// WWDG_Init(0X7F,0X5F,WWDG_Prescaler_8);
//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则有数据
{ for(i=0;i<5;i++){
while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == 0);
USART1_ReceiveData[i] = USART_ReceiveData(USART1); //通过USART1串口接收字符
USART_ClearFlag(USART1,USART_FLAG_RXNE); //接收后先清空标志位
}
}
if( USART1_ReceiveData[0]=='o' && USART1_ReceiveData[1]=='p' && USART1_ReceiveData[2]=='e' && USART1_ReceiveData[3]=='n') //如果数据为1,LED1灯电平翻转
{
printf("\r\n open light \r\n");
LED0 =0;
}
else if( 'c' == USART1_ReceiveData[0] && USART1_ReceiveData[1]=='l' && USART1_ReceiveData[2]=='o' && USART1_ReceiveData[3]=='s' && USART1_ReceiveData[4]=='e') //如果数据为2,LED2灯电平翻转
{
printf("\r\n close light \r\n");
LED0=1;
}
/*else{
printf("\r\n input error \r\n");
}
*/
//USART1_ReceiveData = 0; //数据清零
}
}
版权声明:本文为CSDN博主「朝朝暮暮柳十岁」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42952472/article/details/122697617
即将放年假了,公司目前也没有什么事情是我可做的,便买了一块便宜的stm32板子重新系统学下单片机。目前学到了串口轮询接收字符串,例程是stm32板子自带的看门狗例程,可以把看门狗的实现函数和头文件注释掉,以免影响编译。
板子主控:stm32rct6,他们的库函数其实都差不多,适当修改下即可。主要实现代码如下:
while(1)
{
if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == 1) //USART_FLAG_RXNE判断数据,== 1则有数据
{ for(i=0;i<5;i++){
while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == 0);
USART1_ReceiveData[i] = USART_ReceiveData(USART1); //通过USART1串口接收字符
USART_ClearFlag(USART1,USART_FLAG_RXNE); //接收后先清空标志位
}
}
if( USART1_ReceiveData[0]=='o' && USART1_ReceiveData[1]=='p' && USART1_ReceiveData[2]=='e' && USART1_ReceiveData[3]=='n') //如果数据为1,LED1灯电平翻转
{
printf("\r\n open light \r\n");
LED0 =0;
}
else if( 'c' == USART1_ReceiveData[0] && USART1_ReceiveData[1]=='l' && USART1_ReceiveData[2]=='o' && USART1_ReceiveData[3]=='s' && USART1_ReceiveData[4]=='e') //如果数据为2,LED2灯电平翻转
{
printf("\r\n close light \r\n");
LED0=1;
}
/*else{
printf("\r\n input error \r\n");
}
*/
//USART1_ReceiveData = 0; //数据清零
}
usart,h
#ifndef __USART_H
#define __USART_H
#include "stdio.h"
#include "sys.h"
//1,增加了对UCOSII的支持
#define USART_REC_LEN 200 //定义最大接收字节数 200
#define EN_USART1_RX 1 //使能(1)/禁止(0)串口1接收
extern u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
extern u16 USART_RX_STA; //接收状态标记
//如果想串口中断接收,请不要注释以下宏定义
void uart_init(u32 bound);
void USART1_Init();
#endif
usart.c
#include "sys.h"
#include "usart.h"
//
//如果使用ucos,则包括下面的头文件即可.
#if SYSTEM_SUPPORT_OS
#include "includes.h" //ucos 使用
#endif
//加入以下代码,支持printf函数,而不需要选择use MicroLIB
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
_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
#if EN_USART1_RX //如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误
u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15, 接收完成标志
//bit14, 接收到0x0d
//bit13~0, 接收到的有效字节数目
u16 USART_RX_STA=0; //接收状态标记
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 USART1_IRQHandler(void) //串口1中断服务程序
{
u8 Res;
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
OSIntEnter();
#endif
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
Res =USART_ReceiveData(USART1); //读取接收到的数据
if((USART_RX_STA&0x8000)==0)//接收未完成
{
if(USART_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
else USART_RX_STA|=0x8000; //接收完成了
}
else //还没收到0X0D
{
if(Res==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
OSIntExit();
#endif
}
#endif
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++;
}
}
main.c
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "wwdg.h"
int main(void)
{
uint16_t i;
char USART1_ReceiveData[6] = {0};
delay_init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
//uart_init(9600);
LED_Init();
//LED0=0;
//delay_ms(300);
// WWDG_Init(0X7F,0X5F,WWDG_Prescaler_8);
//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则有数据
{ for(i=0;i<5;i++){
while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == 0);
USART1_ReceiveData[i] = USART_ReceiveData(USART1); //通过USART1串口接收字符
USART_ClearFlag(USART1,USART_FLAG_RXNE); //接收后先清空标志位
}
}
if( USART1_ReceiveData[0]=='o' && USART1_ReceiveData[1]=='p' && USART1_ReceiveData[2]=='e' && USART1_ReceiveData[3]=='n') //如果数据为1,LED1灯电平翻转
{
printf("\r\n open light \r\n");
LED0 =0;
}
else if( 'c' == USART1_ReceiveData[0] && USART1_ReceiveData[1]=='l' && USART1_ReceiveData[2]=='o' && USART1_ReceiveData[3]=='s' && USART1_ReceiveData[4]=='e') //如果数据为2,LED2灯电平翻转
{
printf("\r\n close light \r\n");
LED0=1;
}
/*else{
printf("\r\n input error \r\n");
}
*/
//USART1_ReceiveData = 0; //数据清零
}
}
版权声明:本文为CSDN博主「朝朝暮暮柳十岁」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42952472/article/details/122697617
暂无评论