介绍

在usart.c中进行了:

  1. usart的初始化
  2. 发送字符串函数的编写
  3. printf和scanf的C库重定向
  4. 中断中根据STM32接受到的信息进行开灯和关灯操作

在led.c中进行了:

  1. led的GPIO的初始化

usart.c

#include "usart.h"

static void NVIC_Config(void)
{
	NVIC_InitTypeDef NVIC_InitStruct;
	
	NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
	NVIC_Init(&NVIC_InitStruct);
}


/**
	* PA9	-	TX
	*	PA10-	RX
	*	USART1
	*/
void USART_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	USART_InitTypeDef USART_InitStruct;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
	
	/*初始化GPIO*/
	//TX
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStruct);
	//RX
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;//浮空输入
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;
	GPIO_Init(GPIOA, &GPIO_InitStruct);
	
	/*初始化USART*/
	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_Parity=USART_Parity_No;
	USART_InitStruct.USART_StopBits=USART_StopBits_1;
	USART_InitStruct.USART_WordLength=USART_WordLength_8b;
	USART_Init(USART1, &USART_InitStruct);
	
	NVIC_Config();
	
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
	
	USART_Cmd(USART1, ENABLE);
}

/** *
	*	字符串发送函数
	*/
void USART_SendStr(uint8_t *a)
{
	uint8_t i = 0;
	while (a[i] != '\0')
	{
		USART_SendData(USART1, a[i++]);
		while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
	}
}


/**
	*	printf函数
	*	重定向c库
	*/
int fputc(int ch, FILE *f)
{	
	USART_SendData( USART1, (uint8_t)ch );
	while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
	return ch;
}

/**
	*   scanf函数
	*   重定向c库
	*/
int fgetc(FILE *f)
{
	while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
	return (int)USART_ReceiveData(USART1);
}

void USART1_IRQHandler(void)
{
	uint16_t cmd = 0;
	if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET)
	{
		cmd =  USART_ReceiveData(USART1);
		switch(cmd)
		{
			case '1':	GPIO_SetBits(GPIOB, GPIO_Pin_0);	break;
			case '2':	GPIO_ResetBits(GPIOB, GPIO_Pin_0);	break;
			default:printf("Error:%d", cmd);
		}
	}
}

usart.h

#ifndef __USART_H
#define __USART_H

#include "stm32f10x.h"
#include <stdio.h>

void USART_Config(void);
void USART_SendStr(uint8_t *a);
int fgetc(FILE *f);
int fputc(int ch, FILE *f);
void USART1_IRQHandler(void);

#endif /*__USART_H*/

led.c

#include "led.h"

void LED_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStruct);
}

led.h

#ifndef __LED_H
#define __LED_H

#include "stm32f10x.h"

void LED_Config(void);

#endif

main.c

int main(void)
{
	USART_Config();
	LED_Config();
	while(1)
	{
		
	}
}

可以不用写发送字符串函数,直接重定向printf和scanf,printf发送字符串更简单
注意要写include <stdio.h>

处理接收到的信息直接在中断里面写,很方便
当然也可以不在中断里写,用scanf或者getchar都行

如果串口没有数据,则需要在魔法棒(Options for Target)中的Targets里勾选Use MicroLib