首先进行串口的设置:
串口寄存器:
1:USART_DR:数据的收发是通过该寄存器完成的,这是一个双寄存器,包含了 TDR 和 RDR。
发送:向该寄存器写数据的时候,串口就会自动发送。寄存器发送数据函数为:
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
接收:当串口收到数据的时候,就保存在该寄存器内。读取串口接收数据的函数为:
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);
2:USART_SR:串口的状态可以通过该状态寄存器读取。
注意第 5、 6 位 RXNE 和 TC。
RXNE(读数据寄存器非空),当该位置1时,表示数据接收到了,并可读。这时我们要尽快去读取USART_DR。该位清零方式:通过读 USART_DR 可以将该位清零,也可以向该位写 0,直接清除。
判断串口有没有收到数据寄存器是否非空:USART_GetFlagStatus(USART1, USART_FLAG_RXNE);
TC(发送完成),当该位置1时,表示数据发送完成了,该位设置中断则会中断。清零方式: 读 USART_SR,写USART_DR。 或直接向该位写 0。
判断寄存器中数据有没有从串口发送完:USART_GetFlagStatus(USART1, USART_FLAG_TC)
串口数据发送:
USART_SendData(USART1, USART_RX_BUF[t]);
//寄存器数据向串口 1 发送数据
while
(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
//循环检测,等待发送结束
串口接收数据:
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)//接收中断
Res =USART_ReceiveData(USART1);//从串口1接收的数据存到寄存器中.
串口设置的一般步骤可以总结为如下几个步骤:
1, 串口时钟使能。 串口是挂载在 APB2 下面的外设,所以使能函数为:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1);
2, 串口复位。当外设出现异常的时候可以通过复位设置,实现该外设的复位,然后重新配
置这个外设达到让其重新工作的目的。函数为:
void USART_DeInit(USART_TypeDef* USARTx)
3, GPIO模式设置。函数为:
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
4, 串口参数初始化。函数为:
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
第一个入口参数是指定初始化的串口标号,第二个入口参数是一个 USART_InitTypeDef 类型的结构体指针。
5,开启串口响应中断函数,初始化NVIC函数为:
NVIC_Init(&NVIC_InitStructure);
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT,FunctionalState NewState)第二个入口参数是标示使能串口的类型, 也就是使能哪种中断如:USART_IT_RXNE读数据寄存器非空,USART_IT_TC发送完成。
6,使能串口。函数为:
USART_Cmd(USART1, ENABLE)
串口设置原子已经写在usart.c里边了,会拉进来用就行了
- //初始化 IO 串口 1
- //bound:波特率
- void uart_init(u32 bound)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- USART_InitTypeDef USART_InitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
- //①串口时钟使能, GPIO 时钟使能,复用时钟使能
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能 USART1 ,GPIOA 时钟
- //②串口复位
- USART_DeInit(USART1); //复位串口 1
- //③GPIO 端口模式设置
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //USART1_TX PA.9
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
- GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化 GPIOA.9
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //USART1_RX PA.10
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
- GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化 GPIOA.10
- //④串口参数初始化
- USART_InitStructure.USART_BaudRate = bound; //波特率设置
- USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为 8 位数据格式
- USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
- USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
- USART_InitStructure.USART_HardwareFlowControl= USART_HardwareFlowControl_None;//无硬件数据流控制
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
- USART_Init(USART1, &USART_InitStructure); //初始化串口
- #if EN_USART1_RX //如果使能了接收
- //⑤初始化 NVIC
- NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级 3
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级 3
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道使能
- NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化 VIC 寄存器
- //⑤开启中断
- USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断
- #endif
- //⑥使能串口
- USART_Cmd(USART1, ENABLE); //使能串口
- }
main.c:
- #include "led.h"
- #include "delay.h"
- #include "key.h"
- #include "sys.h"
- #include "usart.h"
- int main(void)
- {
- u8 t;
- u8 len;
- u16 times=0;
- delay_init(); //延时函数初始化
- NVIC_Configuration(); //设置 NVIC 中断分组 2
- uart_init(9600); //串口初始化波特率为 9600
- LED_Init(); //LED 端口初始化
- KEY_Init(); //初始化与按键连接的硬件接口
- while(1)
- {
- if(USART_RX_STA&0x8000)
- { len=USART_RX_STA&0x3f; //得到此次接收到的数据长度
- printf("\r\n 您发送的消息为:\r\n\r\n");
- for(t=0;t<len;t++)
- { USART_SendData(USART1, USART_RX_BUF[t]); //向串口 1 发送数据
- while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
- //循环检测,等待发送结束 USART_GetFlagStatus()这个函数返回值为SET或RESET
- }
- printf("\r\n\r\n"); //插入换行
- USART_RX_STA=0;
- }else
- { times++;
- if(times%5000==0)
- { printf("\r\n 串口实验\r\n");
- printf("哥很霸气\r\n\r\n");
- }
- if(times%200==0)printf("请输入数据,以回车键结束\n");
- if(times%30==0)LED0=!LED0; //闪烁 LED,提示系统正在运行.
- delay_ms(10);
- }
- }