目的:
使用USART进行通信,收发数据
更多介绍:
stm32_CN -> p516页
框图:
中断请求:
TXE 位于USART_SR(状态寄存器)中第七位:
TC位于USART_SR(状态寄存器)中第六位:
CTS位于USART_SR(状态寄存器)中第九位:
寄存器:
(1)状态寄存器(USART_SR):
(2)数据寄存器(USART_DR):包含了发送或接收的数据。由于它是由
两个寄存器
组成的,一个给
发送用(TDR)
,一个给
接收用(RDR)
,该寄存器兼具读和写的功能。TDR寄存器提供了内部总线和输出移位寄存器之间的并行接口(参见图248)。RDR寄存器提供了输入移位寄存器和内部总线之间的并行接口。当使能校验位(USART_CR1中PCE位被置位)进行发送时,写到MSB的值(根据数据的长度不同,MSB是第7位或者第8位)会被后来的校验位该取代。当使能校验位进行接收时,读到的MSB位是接收到的校验位。
(3)波特比率寄存器(USART_BRR):
(4)控制寄存器 1(USART_CR1)和控制寄存器 2(USART_CR2)和 控制寄存器 3(USART_CR3):p545
配置步骤:
1.配置相应I/O口:
GPIO_InitTypeDef GPIO_IniStructure;
GPIO_IniStructure.GPIO_Mode=GPIO_Mode_AF_PP;//推挽复用输出TX
GPIO_IniStructure.GPIO_Pin=GPIO_Pin_9;
GPIO_IniStructure.GPIO_Speed=GPIO_Speed_10MHz;
GPIO_Init(GPIOA,&GPIO_IniStructure);
GPIO_IniStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//浮空
GPIO_IniStructure.GPIO_Pin=GPIO_Pin_10;
GPIO_Init(GPIOA,&GPIO_IniStructure);
2.使能时钟:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//gpio时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//串口时钟
3.串口初始化
波特率,奇偶校验位,停止位等的设置
USART_InitTypeDef USART_InitTStructure;
USART_InitTStructure.USART_BaudRate=115200;//波特率
USART_InitTStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//一般不用
USART_InitTStructure.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;//模式选择,tx rx
USART_InitTStructure.USART_Parity=USART_Parity_No;//奇偶校验
USART_InitTStructure.USART_StopBits=USART_StopBits_1;//停止位1位
USART_InitTStructure.USART_WordLength=USART_WordLength_8b;//字长8
USART_Init(USART1,&USART_InitTStructure);
USART_Cmd(USART1,ENABLE);//使能串口
4.(待选,如果开启中断则用)中断分组:
NVIC_InitTypeDef NVIC_InitTStructure;
NVIC_InitTStructure.NVIC_IRQChannel=USART1_IRQn;
NVIC_InitTStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitTStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitTStructure.NVIC_IRQChannelSubPriority=0;
NVIC_Init(&NVIC_InitTStructure);
5.使能接收中断:
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//Enables or disables the specified USART interrupts.
1
Enables or disables the specified USART interrupts.:启用或禁用指定的USART中断。
USART_IT_PE 奇偶错误中断
USART_IT_TXE 发送中断
USART_IT_TC 传输完成中断
USART_IT_RXNE 接收中断
USART_IT_IDLE 空闲总线中断
USART_IT_LBD LIN中断检测中断
USART_IT_CTS CTS中断
USART_IT_ERR 错误中断
中断服务函数编写:
void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //判断是否是接收中断
{
Res =USART_ReceiveData(USART1); //接收数据
if((USART_RX_STA&0x8000)==0)//判断是否接收完成(if内部为未完成)
{
if(USART_RX_STA&0x4000)//是否为0x0d(if内部是0x0d)
{
if(Res!=0x0a)USART_RX_STA=0;//error
else USART_RX_STA|=0x8000; //res 是0x0a,接收结束
}
else //不是0x0d
{
if(Res==0x0d)USART_RX_STA|=0x4000;
else//接收正确数据中
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;//USART_RX_BUF自己定义的数组
USART_RX_STA++;//USART_RX_STA自己定义的16位标志
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//超过约定长度
}
}
}
} }
USART_RX_STA:16位
当接收到0x0A 最高位至1
接收到0x0D 次高位至1
其余位为接受res一组的个数,接受一个则加一。
可以通过USART_RX_STA&&0X3FFF判断所接收的个数是多少。
USART_GetITStatus:
Checks whether the specified USART interrupt has occurred or not.:检查指定的usart中断是否已发生
USART_IT_PE 奇偶错误中断
USART_IT_TXE 发送中断
USART_IT_TC 发送完成中断
USART_IT_RXNE 接收中断
USART_IT_IDLE 空闲总线中断
USART_IT_LBD LIN中断探测中断
USART_IT_CTS CTS中断
USART_IT_ORE 溢出错误中断
USART_IT_NE 噪音错误中断
USART_IT_FE 帧错误中断
代码:
#define USART_REC_LEN 200
u8 USART_RX_BUF[USART_REC_LEN];
u16 USART_RX_STA=0;
void usart1(void)
{
GPIO_InitTypeDef GPIO_IniStructure;
USART_InitTypeDef USART_InitTStructure;
NVIC_InitTypeDef NVIC_InitTStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
GPIO_IniStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_IniStructure.GPIO_Pin=GPIO_Pin_9;
GPIO_IniStructure.GPIO_Speed=GPIO_Speed_10MHz;
GPIO_Init(GPIOA,&GPIO_IniStructure);
GPIO_IniStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_IniStructure.GPIO_Pin=GPIO_Pin_10;
GPIO_Init(GPIOA,&GPIO_IniStructure);
USART_InitTStructure.USART_BaudRate=115200;
USART_InitTStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
USART_InitTStructure.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;
USART_InitTStructure.USART_Parity=USART_Parity_No;
USART_InitTStructure.USART_StopBits=USART_StopBits_1;
USART_InitTStructure.USART_WordLength=USART_WordLength_8b;
USART_Init(USART1,&USART_InitTStructure);
NVIC_InitTStructure.NVIC_IRQChannel=USART1_IRQn;
NVIC_InitTStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitTStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitTStructure.NVIC_IRQChannelSubPriority=0;
NVIC_Init(&NVIC_InitTStructure);
USART_Cmd(USART1,ENABLE);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
void USART1_IRQHandler(void) //´®¿Ú1ÖжϷþÎñ³ÌÐò
{
u8 Res;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //½ÓÊÕÖжÏ(½ÓÊÕµ½µÄÊý¾Ý±ØÐëÊÇ0x0d 0x0a½áβ)
{
Res =USART_ReceiveData(USART1); //¶ÁÈ¡½ÓÊÕµ½µÄÊý¾Ý
if((USART_RX_STA&0x8000)==0)//½ÓÊÕδÍê³É
{
if(USART_RX_STA&0x4000)//½ÓÊÕµ½ÁË0x0d
{
if(Res!=0x0a)USART_RX_STA=0;//½ÓÊÕ´íÎó,ÖØпªÊ¼
else USART_RX_STA|=0x8000; //½ÓÊÕÍê³ÉÁË
}
else //»¹Ã»ÊÕµ½0X0D
{
if(Res==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//½ÓÊÕÊý¾Ý´íÎó,ÖØпªÊ¼½ÓÊÕ
}
}
}
}
}
}