嵌入式单片机学习之串口接收数据实例

  //通过判断接收连续2个字符之间的时间差不大于10ms来决定是不是一次连续的数据.

  //如果2个字符接收间隔超过10ms,则认为不是1次连续数据.也就是超过10ms没有接收到

  //任何数据,则表示此次接收完毕.

  //接收到的数据状态

  //[15]:0,没有接收到数据;1,接收到了一批数据.

  //[14:0]:接收到的数据长度

  vu16 USART3_RX_STA=0;

  一。uart3.c中的函数

  1. 初始化串口3

  

//初始化IO 串口3

  //pclk1:PCLK1时钟频率(Mhz)

  //bound:波特率

  void usart3_init(u32 bound)

  {

  NVIC_InitTypeDef NVIC_InitStructure;

  GPIO_InitTypeDef GPIO_InitStructure;

  USART_InitTypeDef USART_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // GPIOB时钟

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE); //串口3时钟使能

  USART_DeInit(USART3); //复位串口3

  //USART3_TX PB10

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PB10

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出

  GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PB10

  //USART3_RX PB11

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入

  GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PB11

  USART_InitStructure.USART_BaudRate = bound;//波特率一般设置为9600;

  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(USART3, &USART_InitStructure); //初始化串口3

  USART_Cmd(USART3, ENABLE); //使能串口

  //使能接收中断

  USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启中断

  //设置中断优先级

  NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2 ;//抢占优先级3

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能

  NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器

  ////////////////////////////////////////////////////////////////////////////////////////////////////////

  //定时器7定为10ms中断,检测如果10ms内接收到的数据为同一个数据包中的数据,如果超过10ms

  就算这次接收完成。

  TIM7_Int_Init(1000-1,7200-1); //10ms中断

  USART3_RX_STA=0; //清零

  TIM_Cmd(TIM7,DISABLE); //关闭定时器7

  }

  2.串口3中断函数

 

 void USART3_IRQHandler(void)

  {

  u8 res;

  if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)//接收到数据

  {

  res =USART_ReceiveData(USART3);

  if((USART3_RX_STA&(1<<15))==0)//接收完的一批数据,还没有被处理,则不再接收其他数据

  {

  if(USART3_RX_STA //还可以接收数据

  {

  TIM_SetCounter(TIM7,0); //计数器清空,定时器7开始下一次定时

  if(USART3_RX_STA==0) //使能定时器7的中断

  {

  TIM_Cmd(TIM7,ENABLE);//使能定时器7

  }

  USART3_RX_BUF[USART3_RX_STA++]=res; //记录接收到的值

  }else

  {

  USART3_RX_STA|=1<<15; //强制标记接收完成

  }

  }

  }

  }

  3. 串口2的printf函数

 

 //串口3,printf 函数

  //确保一次发送数据不超过USART3_MAX_SEND_LEN字节

  void u3_printf(char* fmt,...)

  {

  u16 i,j;

  va_list ap;

  va_start(ap,fmt);

  vsprintf((char*)USART3_TX_BUF,fmt,ap);

  va_end(ap);

  i=strlen((const char*)USART3_TX_BUF); //此次发送数据的长度

  for(j=0;j //循环发送数据

  {

  while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕

  USART_SendData(USART3,USART3_TX_BUF[j]);

  }

  }

  4.串口3printf函数的引用

 

 u3_printf("%s",p); //发送该数据到WIFI模块

  u3_printf("%s\r\n",cmd); //发送命令

  二。timer.c中定时器7的设置

  1. 初始化

 

 //通用定时器7中断初始化

  //这里时钟选择为APB1的2倍,而APB1为42M

  //arr:自动重装值。

  //psc:时钟预分频数

  //定时器溢出时间计算方法:Tout=((arr+1)*(psc+1))/Ft us.

  //Ft=定时器工作频率,单位:Mhz

  //通用定时器中断初始化

  //这里始终选择为APB1的2倍,而APB1为36M

  //arr:自动重装值。

  //psc:时钟预分频数

  void TIM7_Int_Init(u16 arr,u16 psc)

  {

  NVIC_InitTypeDef NVIC_InitStructure;

  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE);//TIM7时钟使能

  //定时器TIM7初始化

  TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的 值

  TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值

  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim

  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式

  TIM_TimeBaseInit(TIM7, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位

  TIM_ITConfig(TIM7,TIM_IT_Update,ENABLE ); //使能指定的TIM7中断,允许更新中断

  TIM_Cmd(TIM7,ENABLE);//开启定时器7

  NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//抢占优先级0

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //子优先级2

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能

  NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器

  }

  二。定时器7的中断函数

 

 //定时器7中断服务程序

  void TIM7_IRQHandler(void)

  {

  if (TIM_GetITStatus(TIM7, TIM_IT_Update) != RESET)//是更新中断

  {

  USART3_RX_STA|=1<<15; //标记接收完成

  TIM_ClearITPendingBit(TIM7, TIM_IT_Update ); //清除TIM7更新中断标志

  TIM_Cmd(TIM7, DISABLE); //关闭TIM7

  }

  }

分享些资料便于后期的学习参考

(stm32串口应用)
http://www.makeru.com.cn/live/1392_1164.html?s=45051
PWM脉宽调制技术
http://www.makeru.com.cn/live/4034_2146.html?s=45051
基于STM32讲解串口操作
http://www.makeru.com.cn/live/1758_490.html?s=45051
通过Z-stack协议栈实现串口透传
http://www.makeru.com.cn/live/1758_330.html?s=45051

猜你喜欢

转载自www.cnblogs.com/923327iu/p/11856412.html