串口实验
PS_1: 本节主要讲的是USART1的配置流程
PS_2: 关于串口的知识,可以看看NI官方的解释,炒鸡详尽
http://digital.ni.com/public.nsf/allkb/9F439B3D68D9072F4825703000383197
PS_3: 加入以下代码,可以使得stm32支持printf()函数
//加入以下代码,支持printf函数,而不需要选择use MicroLIB
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{ int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{ x = x; }
//重定义fputc函数
//可以通过修改USARTx 的数字来将printf应用于不同串口
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0){}//循环发送,直到发送完毕
USART1->DR = (u8) ch;
return ch;
}
#endif
USART串口异步全双工通信方式
1. 特点
· 全双工异步通讯
· 可编程的数据字长度
·可配置的停止位
·可配置的DMA多缓冲通讯
· 单独发送器|接收器使能位
·检测标志: 接受缓存器空 || 发送缓存器空 || 传输结束标志
·多个带标志的中断源
2. 需要配置的参数 (USART_InitTypeDef 结构体中的成员配置)
a. 硬件流控制 (USART_HardwareFlowControl)
PS: 一般来说设置为 HardwareFlowControl_None即可,其他功能以后再表
USART_HardwareFlowControl_None
USART_HardwareFlowControl_RTS
USART_HardwareFlowControl_CTS
USART_HardwareFlowControl_RTS_CTS
b. 数据字长(USART_WordLength)
PS:若加入奇偶校验位,则设置字长为9位,否则为8位
USART_WordLength_8b
USART_WordLength_9b
c. 停止位(USART_StopBits)
USART_StopBits_1
USART_StopBits_0_5
USART_StopBits_2
USART_StopBits_1_5
d. 奇偶校验位(USART_Parity)
USART_Parity_No
USART_Parity_Even
USART_Parity_Odd
e. 波特率设置(USART_BaudRate)
常见的有9600、115200等
3. 常用函数一览
USART_Init(USARTx,&USART_InitStruct)//初始化函数
USART_Cmd(USARTx,ENABLE)//串口使能
USART_ITConfig(USARTx,USART_IT_x,ENABLE);//串口中断使能
PS:其中ITConfig第二个参数是设置中断模式而用的,串口中断模式有:
(可以通过查询stm32f10x_usart.c文件中,按住ctl+f 键入 USART_IT 即可查询)
4. 配置的逻辑顺序
1. 时钟使能 : RCC_APB2PeriphClockCmd()
2. GPIO初始化 : GPIO_Init()
3. 串口的初始化 : USART_Init()
4. 串口使能 : USART_Cmd()
5. 开启串口中断 : USART_ITConfig()
6. 中断配置 : NVIC_Init()
实验1,USART测试
接下来看看我们配置的串口使用情况如何:
(让单片机输出我们输入的东西)
代码如下:
#include"stm32f10x.h"
#include"delay.h"
void usart1_Init()
{
GPIO_InitTypeDef GPIO_InitStruct;
USART_InitTypeDef USART_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
//时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
//GPIO初始化
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
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_Parity =USART_Parity_No ;
USART_InitStruct.USART_StopBits =USART_StopBits_1;
USART_InitStruct.USART_WordLength =USART_WordLength_8b ;
USART_Init(USART1,&USART_InitStruct);
USART_Init(USART1,&USART_InitStruct);//③
USART_Cmd(USART1,ENABLE);//使能串口1
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//开启接收中断
//中断使能
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);
}
void USART1_IRQHandler()
{
char test;
if(USART_GetITStatus(USART1,USART_IT_RXNE))
{
test=USART_ReceiveData(USART1);
USART_SendData(USART1,test);
}
}
int main(void)
{
delay_init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
usart1_Init();
while(1);
}
运行结果如下:
实验2,printf测试
#include "stm32f10x.h"
#include "stdio.h"
#include"delay.h"
//printf所需要的宏定义块
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
_sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (u8) ch;
return ch;
}
#endif
void My_USART1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStrue;
USART_InitTypeDef USART_InitStrue;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//①
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStrue.GPIO_Pin=GPIO_Pin_9;
GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;
GPIO_Init(GPIOA,&GPIO_InitStrue);//②
GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_InitStrue.GPIO_Pin=GPIO_Pin_10;
GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;
GPIO_Init(GPIOA,&GPIO_InitStrue);//②
USART_InitStrue.USART_BaudRate=115200;
USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
USART_InitStrue.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;
USART_InitStrue.USART_Parity=USART_Parity_No;
USART_InitStrue.USART_StopBits=USART_StopBits_1;
USART_InitStrue.USART_WordLength=USART_WordLength_8b;
USART_Init(USART1,&USART_InitStrue);//③
USART_Cmd(USART1,ENABLE);//使能串口1
}
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
My_USART1_Init();
delay_init();
while(1)
{
printf("hello world\n");
delay_ms(500);
}
}
测试效果如图: