USART串口通信

Posted 旭日初扬

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了USART串口通信相关的知识,希望对你有一定的参考价值。

一、同步通信

通信双方时钟一致。

typedef struct 
 uint16_t USART_Clock; // 时钟使能控制
 uint16_t USART_CPOL; // 时钟极性
 uint16_t USART_CPHA; // 时钟相位
 uint16_t USART_LastBit; // 最尾位时钟脉冲
  USART_ClockInitTypeDef;

二、异步通信

需要约定通信双方的的通信波特率。

void UART1Config( uint32_t bound)

	USART_InitTypeDef USART_InitStructure;
  //波特率设置
  USART_InitStructure.USART_BaudRate = bound;
	//字长为8位数据格式
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	//一个停止位
	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;	
	 //初始化串口1
	USART_Init(DEGUG_USARTX, &USART_InitStructure);

三、初始化串口

void UART1Init(void)

	//  使能串口时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	
	//  中断服务分组
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
	
	//  中断嵌套
	NVICInit(USART1_IRQn,0,0);
	
	//  PA9  USART1_TX     
	GPIOInit(USART1_TX_PORT,USART1_TX_PIN,GPIO_Mode_AF_PP);
	
	// PA10  USART1_RX
	GPIOInit(USART1_RX_PORT,USART1_RX_PIN,GPIO_Mode_IN_FLOATING);
	
	//  波特率设置
	UART1Config(115200);

   	USART_Cmd(USART1,ENABLE);
	
	//  接收中断
	USART_ITConfig(DEGUG_USARTX,USART_IT_RXNE,ENABLE);
	
	//  发送中断
	USART_ITConfig(DEGUG_USARTX,USART_IT_TXE,ENABLE);

四、中断配置

void NVICInit(uint8_t IRQChannel,uint8_t IRQC_PTP,uint8_t IRQC_SP)

	
	  //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
    NVIC_InitTypeDef NVIC_InitStructure;
  	//  中断通道
	  NVIC_InitStructure.NVIC_IRQChannel = IRQChannel;
	
	  //  抢占式优先级
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = IRQC_PTP;
	
	  //  响应式优先级/副优先级
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = IRQC_SP;
	
	  //  使能
	  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	
  	NVIC_Init(&NVIC_InitStructure);


/*
外部中断
EXTI 的每根输入线都可单独进行配置,以选择类型(中 断或事件)和相应的触发事件(上升沿触发、下降沿触发或边沿触发)
EXTI线路               说明

EXTI线0~15         对应外部IO口的输入中断
EXTI线 16          连接到PVD输出
EXTI线17           连接到RTC闹钟事件
EXTI线18           连接到USB OTG FS唤醒事件
EXTI线19           连接到以太网唤醒事件

每个 GPIO 端口均有 16 个管脚,每个 端口的 16 个 IO 对应那 16 根中断线 EXTI0-EXTI15。
*/
/*

Function:外部中断

*/

void EXTIInit(uint8_t GPIO_PORT, uint8_t GPIO_Pin,uint32_t EXTILine,EXTIMode_TypeDef Mode, EXTITrigger_TypeDef EXTI_Trigger)

  EXTI_InitTypeDef EXTI_InitStructure;
	
	//  时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	
	//  外部中断的端口  与引脚
	GPIO_EXTILineConfig(GPIO_PORT, GPIO_Pin);
	 
  EXTI_InitStructure.EXTI_Line =EXTILine;          //   中断/事件线 
	EXTI_InitStructure.EXTI_Mode = Mode;             //    EXTI 模式 
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger;  //    EXTI 触发方式 
  EXTI_InitStructure.EXTI_LineCmd =ENABLE;    //    中断线使能或失能
	
	EXTI_Init(&EXTI_InitStructure);

五、GPIO配置

void GPIOInit(uint32_t RCC_APB2Periph,GPIO_TypeDef* GPIOx,uint16_t GPIOPin,uint16_t GPIOMode)

    GPIO_InitTypeDef GPIO_InitStructure;

   

    RCC_APB2PeriphClockCmd(RCC_APB2Periph,ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIOPin;

    GPIO_InitStructure.GPIO_Mode = (GPIOMode_TypeDef)GPIOMode;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOx,&GPIO_InitStructure);


APB2上的时钟可选:

RCC_APB2Periph_AFIO, RCC_APB2Periph_GPIOA, RCC_APB2Periph_GPIOB,
RCC_APB2Periph_GPIOC, RCC_APB2Periph_GPIOD, RCC_APB2Periph_GPIOE,
RCC_APB2Periph_GPIOF, RCC_APB2Periph_GPIOG, RCC_APB2Periph_ADC1,
RCC_APB2Periph_ADC2, RCC_APB2Periph_TIM1, RCC_APB2Periph_SPI1,
RCC_APB2Periph_TIM8, RCC_APB2Periph_USART1, RCC_APB2Periph_ADC3,
RCC_APB2Periph_TIM15, RCC_APB2Periph_TIM16, RCC_APB2Periph_TIM17,
RCC_APB2Periph_TIM9, RCC_APB2Periph_TIM10, RCC_APB2Periph_TIM11     

六、中断服务函数

6.1、方式一

 void DEBUG_USART_IRQHandler(void)
 
 uint8_t ucTemp;
if (USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET) 
 ucTemp = USART_ReceiveData( USART1);
 USART_SendData(USART1,ucTemp);
 

 
 /***************** 发送一个字符 **********************/
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch)
 
/* 发送一个字节数据到 USART */
 USART_SendData(USART1,ch);

/* 等待发送数据寄存器为空 */
 while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
 

/***************** 发送字符串 **********************/
void Usart_SendString( USART_TypeDef * pUSARTx, char *str)

 unsigned int k=0;
 do 
Usart_SendByte( USART1, *(str + k) );
 k++;
  while (*(str + k)!='\\0');
 
/* 等待发送完成 */
while (USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET) 

int main(void)
 
 /*初始化 USART 配置模式为 115200 8-N-1,中断接收*/
 USART1Init();
/* 发送一个字符串 */
Usart_SendString( USART1,"这是一个串口中断接收回显实验\\n");

 while (1) 

6.2、方式二

接收状态
//bit15,    接收完成标志
//bit14,    接收到0x0d
//bit13~0,    接收到的有效字节数目
u16 USART1_RX_STA=0;       

void USART1_IRQHandler(void)                	//串口1中断服务程序

	u8 r;
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断
	
		r =USART_ReceiveData(USART1);//(USART1->DR);	//读取接收到的数据
		if((USART1_RX_STA&0x8000)==0)//接收未完成
		
			if(USART1_RX_STA&0x4000)//接收到了0x0d
			
				if(r!=0x0a)USART1_RX_STA=0;//接收错误,重新开始
				else USART1_RX_STA|=0x8000;	//接收完成了 
			
			else //还没收到0X0D
				
				if(r==0x0d)USART1_RX_STA|=0x4000;
				else
				
					USART1_RX_BUF[USART1_RX_STA&0X3FFF]=r;
					USART1_RX_STA++;
					if(USART1_RX_STA>(USART1_REC_LEN-1))USART1_RX_STA=0;//接收数据错误,重新开始接收	  
						 
			
		   		 
	 
 	
int fputc(int ch,FILE*p)

	//  Transmits single data through the USARTx peripheral.
	//  通过USARTx外围设备传输单个数据。
  USART_SendData(USART1,(u8)ch);
	
	//  Checks whether the specified USART flag is set or not.
	//  检查是否设置USART指定的标志
	while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==!RESET);
	return ch;

void USART1_MAIN_Logic(void)

接收到数据
if(USART1_RX_STA&0x8000)
			//得到此次接收到的数据长度				   
			len=USART1_RX_STA&0x3fff;
			for(t=0;t<len;t++)
			
				USART_SendData(USART1, USART1_RX_BUF[t]);         //向串口1发送数据
				while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
			
			USART1_RX_STA=0;
		

以上是关于USART串口通信的主要内容,如果未能解决你的问题,请参考以下文章

16 . USART 串口通信实验

16 . USART 串口通信实验

16 . USART 串口通信实验

谁能把单片机串口通信SFR介绍下?

USART1串口通信2

USART1串口通信2