STM32----------串口通信(USART)

#include "stm32f10x.h"
#include "platform_config.h"
#include "stm32f10x_usart.h"
#include "misc.h"
#include "stdarg.h"

USART_InitTypeDef USART_InitStructure;
uint8_t TxBuffer1[] = "USART Interrupt Example: This is USART2 DEMO";  
uint8_t RxBuffer1[],rec_f,tx_flag;
__IO uint8_t TxCounter1 = 0x00;
__IO uint8_t RxCounter1 = 0x00; 

uint32_t Rec_Len;

void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);

void Delay(__IO uint32_t nCount);
void USART_OUT(USART_TypeDef* USARTx, uint8_t *Data,...);
char *itoa(int value, char *string, int radix);
void USART_Config(USART_TypeDef* USARTx);

GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStruct;
USART_ClockInitTypeDef USART_ClockInitStruct;

void USART_Config(USART_TypeDef* USARTx){
  USART_InitStructure.USART_BaudRate = 115200;						
  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;					//

  USART_Init(USARTx, &USART_InitStructure);							//
 
  /* Enable USARTx Receive and Transmit interrupts */
  USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); //使能接收端中断,TXE发送中断,TC传输完成中断,RXNE接收中断
  USART_ITConfig(USART2, USART_IT_TXE, ENABLE);		//使能发送端空中断

  /* Enable the USARTx */
  USART_Cmd(USART2, ENABLE);	
}

int main(void)
{

   uint8_t a=0;
  /* System Clocks Configuration */
  RCC_Configuration();											 
  NVIC_Configuration();											 
  GPIO_Configuration();											 
  USART_Config(USART2);											
  
  USART_OUT(USART2,"****(C)       COPYRIGHT 2014 ·              ******\r\n");    	 
  USART_OUT(USART2,"*                                                 *\r\n");    	  	
  USART_OUT(USART2,"*                                                 *\r\n");    	
  USART_OUT(USART2,"*                 www.ourstm.net                  *\r\n");   
  USART_OUT(USART2,"*                                                 *\r\n");    	 	
  USART_OUT(USART2,"***************************************************\r\n"); 
  USART_OUT(USART2,"\r\n"); 
  USART_OUT(USART2,"\r\n");    	
   while (1)
  {
	if(rec_f==1){												  
		rec_f=0;
		USART_OUT(USART2,"你将发送的数据是 :\r\n");    
		USART_OUT(USART2,&TxBuffer1[0]);
		if(a==0) {GPIO_SetBits(GPIOB, GPIO_Pin_5); a=1;}                         
		else {GPIO_ResetBits(GPIOB, GPIO_Pin_5);a=0;  }
	}
  }
}

void Delay(__IO uint32_t nCount)
{
  for(; nCount != 0; nCount--);
}


void USART_OUT(USART_TypeDef* USARTx, uint8_t *Data,...){ 
	const char *s;
    int d;
    char buf[16];
    va_list ap;
    va_start(ap, Data);

	while(*Data!=0){				                          
		if(*Data==0x5c){									  //'\'
			switch (*++Data){
				case 'r':							          //
					USART_SendData(USARTx, 0x0d);	   

					Data++;
					break;
				case 'n':							          //
					USART_SendData(USARTx, 0x0a);	
					Data++;
					break;
				
				default:
					Data++;
				    break;
			}	 
		}
		else if(*Data=='%'){									  //
			switch (*++Data){				
				case 's':										  //
                	s = va_arg(ap, const char *);
                	for ( ; *s; s++) {
                    	USART_SendData(USARTx,*s);
						while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET);
                	}
					Data++;
                	break;
            	case 'd':										  //
                	d = va_arg(ap, int);
                	itoa(d, buf, 10);
                	for (s = buf; *s; s++) {
                    	USART_SendData(USARTx,*s);
						while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET);
                	}
					Data++;
                	break;
				default:
					Data++;
				    break;
			}		 
		}
		else USART_SendData(USARTx, *Data++);
		while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET);
	}
}

char *itoa(int value, char *string, int radix)
{
    int     i, d;
    int     flag = 0;
    char    *ptr = string;

    /* This implementation only works for decimal numbers. */
    if (radix != 10)
    {
        *ptr = 0;
        return string;
    }

    if (!value)
    {
        *ptr++ = 0x30;
        *ptr = 0;
        return string;
    }

    /* if this is a negative value insert the minus sign. */
    if (value < 0)
    {
        *ptr++ = '-';

        /* Make the value positive. */
        value *= -1;
    }

    for (i = 10000; i > 0; i /= 10)
    {
        d = value / i;

        if (d || flag)
        {
            *ptr++ = (char)(d + 0x30);
            value -= (d * i);
            flag = 1;
        }
    }

    /* Null terminate the string. */
    *ptr = 0;

    return string;

} /* NCL_Itoa */

void RCC_Configuration(void)
{
   SystemInit(); 
   RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
                           RCC_APB2Periph_AFIO  , ENABLE); 
   RCC_APB1PeriphClockCmd( RCC_APB1Periph_USART2, ENABLE);  
}
  
void GPIO_Configuration(void)
{

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;				     
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;			 
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);					 

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;	         		 //USART2 TX

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    		 //
  GPIO_Init(GPIOA, &GPIO_InitStructure);		    		 //

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;	         	 	 //USART2 RX
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   	 //
  GPIO_Init(GPIOA, &GPIO_InitStructure);		         	 //

}

void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);	  
  
  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;			     	
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;	     	
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;				
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;					
  NVIC_Init(&NVIC_InitStructure);
}

上面的是main.c  ,下面是stm32f10x_it.c中断服务程序

<span style="font-size:18px;">#include "stm32f10x_it.h"
#include "stm32f10x_usart.h"
extern uint8_t TxBuffer1[]; 
extern uint8_t TxBuffer2[]; 
extern uint8_t RxBuffer1[];
extern uint8_t RxBuffer2[];
extern __IO uint8_t TxCounter1;
extern __IO uint8_t TxCounter2;
extern __IO uint8_t RxCounter1; 
extern __IO uint8_t RxCounter2;

extern uint8_t rec_f,tx_flag;
void USART2_IRQHandler(void)      //串口2中断服务函数
{
  unsigned int i;
  if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)	   //判断读寄存器是否为空,也就是是否有数据发送进来,是否发生接收中断
  {	
    
    RxBuffer1[RxCounter1++] = USART_ReceiveData(USART2);   //将读寄存器的数据存到接收缓冲区里面
	
    if(RxBuffer1[RxCounter1-2]==0x0d&&RxBuffer1[RxCounter1-1]==0x0a)     //判断结束标志位是否为0x0d 0x0a (\r\n)  也就是是否为回车  </span>
   {
	  for(i=0; i< RxCounter1; i++) TxBuffer1[i]	= RxBuffer1[i]; 	     //将接收区数据送到发送缓冲区,准备转发
	  rec_f=1;								     //接收成功标志 
	  TxBuffer1[RxCounter1]=0;		                                     //发送缓冲区结束符    
	  RxCounter1=0;
	  
    }
  }
  
  if(USART_GetITStatus(USART2, USART_IT_TXE) != RESET)                   //这段是为了STM32 UART 第一个字节发送不出去的BUG
  { 
     USART_ITConfig(USART2, USART_IT_TXE, DISABLE);					     //禁止发缓冲器空中断
  }	
  
}


STM32笔记之九:打断它来为我办事,EXIT (外部I/O中断)应用

a) 目的:跟串口输入类似,不使用中断进行的IO输入效率也很低,而且可以通过EXTI插入按钮事件,本节联系EXTI中断。

b) 初始化函数定义:

void EXTI_Configuration(void); //定义IO中断初始化函数

c) 初始化函数调用:

EXTI_Configuration();//IO中断初始化函数调用简单应用:

d) 初始化函数:

void EXTI_Configuration(void)

{ EXTI_InitTypeDef EXTI_InitStructure; //EXTI初始化结构定义

EXTI_ClearITPendingBit(EXTI_LINE_KEY_BUTTON);//清除中断标志

GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource3);//管脚选择

GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource4);

     GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource5);

     GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource6);

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//事件选择

    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//触发模式

    EXTI_InitStructure.EXTI_Line = EXTI_Line3 | EXTI_Line4; //线路选择

    EXTI_InitStructure.EXTI_LineCmd = ENABLE;//启动中断

    EXTI_Init(&EXTI_InitStructure);//初始化

}

e) RCC初始化函数中开启I/O时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);

GPIO初始化函数中定义输入I/O管脚。

//IO输入,GPIOA的4脚输入

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;        //上拉输入

    GPIO_Init(GPIOA, &GPIO_InitStructure);              //初始化

f) 在NVIC的初始化函数里面增加以下代码打开相关中断:

    NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel; //通道

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//占先级

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应级

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //启动

    NVIC_Init(&NVIC_InitStructure); //初始化

g) 在stm32f10x_it.c文件中找到void USART1_IRQHandler函数,在其中添入执行代码。一般最少三个步骤:先使用if语句判断是发生那个中断,然后清除中断标志位,最后给字符串赋值,或做其他事情。

    if(EXTI_GetITStatus(EXTI_Line3) != RESET)                                //判断中断发生来源

{ EXTI_ClearITPendingBit(EXTI_Line3);                                         //清除中断标志

USART_SendData(USART1, 0x41);                                            //发送字符“a”

GPIO_WriteBit(GPIOB, GPIO_Pin_2, (BitAction)(1-GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_2)));//LED发生明暗交替

}

h) 中断注意事项:

中断发生后必须清除中断位,否则会出现死循环不断发生这个中断。然后需要对中断类型进行判断再执行代码。

使用EXTI的I/O中断,在完成RCC与GPIO硬件设置之后需要做三件事:初始化EXTI、NVIC开中断、编写中断执行代码。

中断注意事项:

可以随时在程序中使用USART_ITConfig(USART1, USART_IT_TXE, DISABLE);来关闭中断响应。

NVIC_InitTypeDef NVIC_InitStructure定义一定要加在NVIC初始化模块的第一句。

全局变量与函数的定义:在任意.c文件中定义的变量或函数,在其它.c文件中使用extern+定义代码再次定义就可以直接调用了。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值