#ifndef __USART_H__ #define __USART_H__#include "stm32f10x.h" #include <stdio.h>//重定向的函数要用#define USART1_SEND_BYTE_NUM 512//定义发送字节数extern uint16_t USART1_RX_STATE; extern uint16_t USART1_SEND_BYTE[];void USART1_GPIO_Init(void); int fputc(int ch, FILE *f);#endif
usart.h
#include "usart.h"uint16_t USART1_RX_STATE = 0;//定义标志位 uint16_t USART1_SEND_BYTE[USART1_SEND_BYTE_NUM];void USART1_GPIO_Init(void) {//1.指定并配置GPIO端口//2.配置串口1//3.使能端口时钟,具体的复用功能时钟//4.使能串口1 GPIO_InitTypeDef GPIO_InitStruct;USART_InitTypeDef USART_InitStruct;//PA9 复用功能USART1 TX---需要配置为复用推挽输出--具体模式说在参考手册GPIO章节能查询到,我并未查到GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;//使能时钟-端口时钟,复用功能时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);GPIO_Init(GPIOA, &GPIO_InitStruct);//PA10 复用功能USART1 RX---需要配置为浮空输入 --具体模式说在参考手册GPIO章节能查询到,我并未查到 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; // GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;GPIO_Init(GPIOA, &GPIO_InitStruct);//配置USART1USART_InitStruct.USART_BaudRate = 9600;//常用波特率值USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;USART_InitStruct.USART_WordLength = USART_WordLength_8b;USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStruct.USART_Parity = USART_Parity_No;USART_InitStruct.USART_StopBits = USART_StopBits_1;USART_Init(USART1, &USART_InitStruct);//使能串口1 USART_Cmd(USART1, ENABLE);//串口中断设置USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//配置接收非空产生中断 }//实现串口打印功能需要调用printf函数,需要重定向fputc函数int fputc(int ch, FILE *f) {while(USART_GetFlagStatus(USART1, USART_FLAG_TC) != SET);USART_SendData(USART1, (unsigned char)ch);//该函数本来是把要打印的字符串ch输出到数据流中;被串口从中拿到数据ch的拷贝,并发通过USART_SendData发送到数据输出寄存器USART_DR // while(USART_GetFlagStatus(USART1, USART_FLAG_TC) != SET);//数据发送到USART_DR时,USART_FLAG_TC会标志位置高;USART_GetITStatus函数一般是用在中断里确认是哪种中断 //因为这句放下面会经常出现缺少一个字符,所以移动到上面了,不知道啥原因return ch; //数据继续发送到数据流中 }//void USART1_Send(uint16_t msg) //{ // //}
usart.c
#ifndef __NVIC_H__ #define __NVIC_H__#include "stm32f10x.h"void NVIC_GPIO_Init(void);#endif
nvic.h
#include"nvic.h"void NVIC_GPIO_Init(void) {NVIC_InitTypeDef NVIC_InitStruct;NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_Init(&NVIC_InitStruct); }
nvic.c
#include "stm32f10x_it.h" #include "usart.h"extern uint16_t USART1_RX_STATE; extern uint16_t USART1_SEND_BYTE[];void USART1_IRQHandler(void) {uint8_t res = 0;//进入该中断,说明数据接收寄存器RDR接收到数据if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)// 接收数据寄存器RDR接收到数据时 {res = USART_ReceiveData(USART1);if((USART1_RX_STATE & 0x8000) == 0) //如果最高位为0,说明没有接收完成 {if(USART1_RX_STATE&0x4000)//次高位为1情况下 {if(res == 0x0a) //次高位为1情况下,如果收到0x0a,需要最高位标志位置1 {USART1_RX_STATE |= 0x8000;}else //次高位已经收到0X0D,最后一个字节却不是0X0A,数据都不要了 {USART1_RX_STATE = 0;//次高位已经收到0X0D,最后一个字节却不是0X0A,数据都不要了 }}else//次高位并没有置1,没有收到0x0d {if(res == 0x0d) //如果这一个数据正好是0x0d,则次高位置1 {USART1_RX_STATE |= 0x4000;}else //这个数据并不是0X0D,则是USART1_RX_STATE&0x3fff之前的接收序号数据 {USART1_SEND_BYTE[USART1_RX_STATE&0x3fff] = res;USART1_RX_STATE ++;if(USART1_RX_STATE > USART1_SEND_BYTE_NUM-1){USART1_RX_STATE = 0;}}}} // else // { // // // } } }
stm32f10x_it.c
#include "stm32f10x.h" #include "usart.h" #include "nvic.h" //mcu transmit data to PC repeatedly ,while PC transmit data to MCU,then MCU will transmit the data what the PC transmit; //MCU重复不断给PC发数据,当PC给MCU发数据时,MCU会把收到的信息发回给PCint main(void) {uint8_t t,len;NVIC_GPIO_Init();USART1_GPIO_Init();printf("hello,world!\r\n");while(1){if(USART1_RX_STATE&0x8000){len = USART1_RX_STATE&0x3fff;for(t = 0; t < len; t++){USART_SendData(USART1, USART1_SEND_BYTE[t]);while(USART_GetFlagStatus(USART1, USART_FLAG_TC) != SET);}USART1_RX_STATE = 0;}} }
main.c