mian.c
#include "stm32f10x.h"
#include "stm32f10x_pal.h"
#include "queue.h"
#include <string.h>
static Queue_HandleTypeDef hQueue;
static Queue_HandleTypeDef hTxQueue;
static void USART_Echo_Init(void);
static void USART_Echo_Proc(void);
static void USART1_SendString(const char *Str);
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
PAL_Init();
USART_Echo_Init();
while(1)
{
USART_Echo_Proc();
}
}
static void USART_Echo_Init(void)
{
GPIO_InitTypeDef GPIOInitStruct;
Queue_Init(&hQueue);
Queue_Init(&hTxQueue);
// 1. 初始化IO引脚
// PB6 PB7
// Tx
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIOInitStruct.GPIO_Pin = GPIO_Pin_6;
GPIOInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIOInitStruct.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOB, &GPIOInitStruct);
// Rx
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIOInitStruct.GPIO_Pin = GPIO_Pin_7;
GPIOInitStruct.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIOInitStruct);
// AFIO
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE);
// 2. 使能USART1的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
// 3. 配置USART1的参数
USART_InitTypeDef USARTInitStruct;
USARTInitStruct.USART_BaudRate = 9600;
USARTInitStruct.USART_WordLength = USART_WordLength_8b;
USARTInitStruct.USART_Parity = USART_Parity_No;
USARTInitStruct.USART_StopBits = USART_StopBits_1;
USARTInitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx ;//| USART_Mode_Rx
USARTInitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART1, &USARTInitStruct);
// 4. 配置中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
NVIC_InitTypeDef NVICInitStruct;
NVICInitStruct.NVIC_IRQChannel = USART1_IRQn;
NVICInitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVICInitStruct.NVIC_IRQChannelSubPriority = 0;
NVICInitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVICInitStruct);
// 5. 闭合USART1的总开关
USART_Cmd(USART1, ENABLE);
}
void USART1_IRQHandler(void)
{
uint8_t c;
if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
{
c = USART_ReceiveData(USART1);
Queue_Enqueue(&hQueue, c);
}
else if(USART_GetITStatus(USART1, USART_IT_TXE) == SET)
{
if(Queue_Dequeue(&hTxQueue, &c) == SUCCESS)
{
USART_SendData(USART1, c);
}
else
{
USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
}
}
}
static uint8_t a[100];
static uint16_t cursor = 0; //游标
static void USART_Echo_Proc(void)
{
uint8_t c;
USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
ErrorStatus error = Queue_Dequeue(&hQueue, &c);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
if(error == SUCCESS)
{
a[cursor++] = c;
if(cursor>2 && a[cursor-2] == '\r'&& a[cursor - 1] == '\n') // 收到新行
{
// 发送出去
a[cursor] = 0;
USART1_SendString((const char *)a);
cursor=0;
}
}
}
static void USART1_SendString(const char *Str)
{
uint32_t i;
USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
for(i=0;i<strlen(Str);i++)
{
Queue_Enqueue(&hTxQueue, Str[i]);
}
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
}
2 queue.c
#include "queue.h"
void Queue_Init(Queue_HandleTypeDef *hQueue)
{
hQueue->Tail = 0;
}
void Queue_Enqueue(Queue_HandleTypeDef *hQueue, uint8_t Element)
{
hQueue->Data[hQueue->Tail ++] = Element;
}
ErrorStatus Queue_Dequeue(Queue_HandleTypeDef *hQueue, uint8_t *pElement)
{
uint32_t i;
if(hQueue->Tail == 0) return ERROR; // 队列空,操作无效
*pElement = hQueue->Data[0];
for(i=0;i<hQueue->Tail-1;i++)
{
hQueue->Data[i] = hQueue->Data[i+1];
}
hQueue->Tail--;
return SUCCESS;
}
3 queue.h
#ifndef _QUEUE_H_
#define _QUEUE_H_
#include "stm32f10x.h"
typedef struct
{
uint8_t Data[100];
uint16_t Tail; // 队尾
} Queue_HandleTypeDef;
void Queue_Init(Queue_HandleTypeDef *hQueue);
void Queue_Enqueue(Queue_HandleTypeDef *hQueue, uint8_t Element);
ErrorStatus Queue_Dequeue(Queue_HandleTypeDef *hQueue, uint8_t *pElement);
#endif // 防止头文件被重复引用