近期脑子有点抽象,想一下估计也有家伙和我一样,所以就分享给抽象的大家如何串口控制LED灯
写的不好,希望大家不要喷我。
1、首先是串口的初始化:
初始化串口1,中断优先级随便设置,反正只有一个函数怕啥。速率2MHZ就够了毕竟公司要求我们还是需要节能的。2M狗狗的。校验位啥的看着设,哎无所谓的。随便写的。
#include "USART.h"
extern uint8_t flag;
void USART_Config_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
USART_InitTypeDef USART_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
//初始化GPIOA_PIN9|10号引脚,USART1,AFIO复用功能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1|RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9 ;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
//初始化GPIO引脚
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOA,&GPIO_InitStruct);
USART_InitStruct.USART_BaudRate = 115200; //波特率
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬件流控制
USART_InitStruct.USART_Mode = USART_Mode_Rx|USART_Mode_Tx; //发送接收模式
USART_InitStruct.USART_StopBits = USART_StopBits_1;//停止位
USART_InitStruct.USART_Parity = USART_Parity_No;//奇偶校验
USART_InitStruct.USART_WordLength = USART_WordLength_8b; //数据位
//初始化串口
USART_Init(USART1, &USART_InitStruct);
//配置接受中断源:USART_IT_RXNE
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
//配置中断优先级NVIC
NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStruct);
USART_ClearFlag(USART1,USART_FLAG_TC|USART_FLAG_TXE);
//打开串口1
USART_Cmd(USART1, ENABLE );
}
2、数据发送函数接受函数
相信大家都是聪明人,都看的懂的,不懂就要去学习咯,我也是哦,不懂就去多学习。
为啥定义要用volatile ?可能我比较乐意吧。毕竟没有优化嘛,直接从内存地址中读数据嘛。
void Send_Msg(uint8_t data)
{
USART_SendData(USART1,data);//发送信息
while(SET != USART_GetFlagStatus(USART1,USART_FLAG_TC));//发送标志位获取,知道发送全
}
void Rev_Msg(void)
{
if(SET==USART_GetFlagStatus(USART1,USART_FLAG_RXNE)){//接受数据
USART_ClearFlag(USART1,USART_FLAG_RXNE);//清除标志位置
USART_SendData(USART1,USART_ReceiveData(USART1));//发送信息到串口助手
}
}
extern uint8_t flag;//判断是否接受完全的标志位
extern char ptr[50]; //接受数据数组
volatile uint8_t recv_data;
volatile uint32_t strIndex = 0;
void USART1_IRQHandler(void)
{
//中断服务函数
if(SET == USART_GetFlagStatus(USART1,USART_IT_RXNE))
{
//清除标志位
USART_ClearITPendingBit(USART1,USART_IT_RXNE);//
recv_data = USART_ReceiveData(USART1);//把接受到的数据放到变量中
//USART_SendData(USART1,recv_data);//发送信息到串口助手
// while(SET != USART_GetFlagStatus(USART1,USART_FLAG_TC));
if(recv_data =='\n'){
ptr[strIndex] = '\0';
flag = 1;
strIndex = 0;
}else {
ptr[strIndex] = recv_data;
strIndex++;
}
}
}
3、printf从定向函数
STM32无法使用printf,因为没有屏幕?没关系,直接将打印的东西从定向到串口就是咯。
上面为啥不要USART_SendData(USART1,recv_data);和while(SET != USART_GetFlagStatus(USART1,USART_FLAG_TC));
可能我比较乐意吧,大家想用也可以用,没关系,相信你自己会出手的。
int fputc(int ch,FILE *f)
{
USART1->DR=(uint8_t)ch; //将其强转为char类型数据放入数据寄存器中
while(0==(USART1->SR&(1<<6))); //循环发送
USART1->SR &=~(1<<6);
return ch;
}
4、串口的h文件
哎,头文件啥的,简单写一下就是了。
#ifndef __USART_H
#define __USART_H
#include "stm32f10x.h" // Device header
void Send_Msg(uint8_t data);
void Rev_Msg(void);
void USART_Config_Init(void);
#include "stdio.h"
#include "string.h"
int fputc(int ch,FILE*f);
#endif
5、LED灯的初始化
这个总不用我写吧。
算了还是写一下吧
void LED_Init(void)
{
//打开时钟
RCC->APB2ENR |=(1<<4);
// 1》设置GPIOC8模式为通用推挽输出----GPIOC->CRH的第3---0位配置成0010
GPIOC->CRH &=~(0xf);
GPIOC->CRH |=(1<<1);
GPIOC->CRL &=~(0xf);
GPIOC->CRL |=(1<<29);
GPIOC->CRL |=(1<<25);
// 2》关灯----GPIOC->ODR的第8位配置为1
GPIOC->ODR |=(1<<8);
GPIOC->ODR |=(1<<7);
GPIOC->ODR |=(1<<6);
}
LED头文件
好人做到,送佛送到西,一路写下去咯
#ifndef __LED_H
#define __LED_H
#include "stm32f10x.h" // Device header
#define LED_ON GPIO_ResetBits(GPIOC, GPIO_Pin_8|GPIO_Pin_7|GPIO_Pin_6)
#define LED_OFF GPIO_SetBits(GPIOC, GPIO_Pin_8|GPIO_Pin_7|GPIO_Pin_6)
void LED_Init(void);
#endif
main函数;
就这样了,直接ok了
#include "stm32f10x.h" // Device header
#include "USART.h"
#include "LED.h"
uint8_t flag;
char ptr[20];
int main()
{
LED_Init();
//中断管理方式
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
USART_Config_Init();
while(1){
if(flag){
printf("%s\n",ptr);
if(strncmp(ptr,"open",4)==0){
LED_ON;
flag = 0;
}
if(strncmp(ptr,"close",5)==0){
LED_OFF;
flag = 0;
}
}
}
}
串口结果:
我反正点亮了,你们我就不管了。下班咯