国产化芯片FM33G0系列之低功耗串口

七、低功耗串口
首先,先看官方例程中的LP串口配置。

void LPUart_Init(void)
{
	LPUART_SInitTypeDef init_para;
	
  RCC_PERCLK_SetableEx(LPUFCKEN, ENABLE);	//LPUART功能时钟使能
  RCC_PERCLK_SetableEx(LPUARTCKEN, ENABLE);	//LPUART寄存器总线时钟使能
  
  GPIO_PF4AFSEL_PF4AFS_Set(GPIO_PF4AFSEL_PF4AFS_LPUART_TX);//PF4选择LPUART_TX
	//LPUART IO 配置
	AltFunIO(GPIOF, GPIO_Pin_3, 2);		//PF3 LPUART RX 除匹配接收假如外部没有上拉电阻建议配置上拉电阻
	AltFunIO(GPIOF, GPIO_Pin_4, 0);		//PF4 LPUART TX
 
	/*NVIC中断配置*/
	NVIC_DisableIRQ(LPUART_IRQn);
  NVIC_SetPriority(LPUART_IRQn,2);//中断优先级配置
  NVIC_EnableIRQ(LPUART_IRQn);	
	

	//UART初始化配置
	init_para.BaudRate = 9600;			//波特率
	init_para.DataBit = Eight8Bit;		//数据位数
	init_para.ParityBit = EVEN;			//奇偶校验
	init_para.StopBit = OneBit;			//停止位
	
	LPUART_SInit(&init_para);	//初始化uart(接收中断使用的是接收数据匹配)
}

void LPUART_SInit(LPUART_SInitTypeDef* para)
{
	LPUART_InitTypeDef para2;	
        para2.RXEV =LPUART_LPUCON_RXEV_MATCH;		//接收中断事件配置
	para2.TCIE = DISABLE;		//发送完成中断使能
	para2.TXIE = DISABLE;		//发送buffer空中断使能
	para2.RXIE = DISABLE;		//接收中断使能
	para2.TXPOL = DISABLE;		//数据发送极性取反使能
	para2.RXPOL = DISABLE;		//数据接收极性取反控制
	para2.NEDET = DISABLE;		//下降沿检测使能
	para2.ERRIE = DISABLE;		//错误中断使能	
	
	LPUART_Init(¶2);
}

在LPUART_SInit(&init_para);函数里面的接收中断事件配置:是接收数据匹配成功。意思是从上位机或者串口发送的数据,必须得有设置的匹配字节才能接收,该匹配的字节可以通过LPUART_COMPARE_Write(0x33);//写数据匹配寄存器
随意设置。接收中断事件配置的设置又关系到串口中断函数的判断。

初始化完成,测试低功耗串口,通过发送数据测试串口是否通讯成功。

void Test_LPUart(void)
{
	LPUART_LPUEN_RXEN_Setable(ENABLE);		//打开接收使能
	LPUART_LPUEN_TXEN_Setable(ENABLE);		//打开发送使能
	
  //中断发送数组
	LPUARTOp.TxBuf = TestTxData;
	LPUARTOp.TxLen = 12;
	LPUARTOp.TxOpc = 1;
	
  //清除发送中断标志
  LPUART_LPUIF_TXIF_Clr();
  LPUART_LPUIF_TC_IF_Clr();

  LPUART_LPUCON_TCIE_Setable(ENABLE); //使能发送中断
  LPUART_LPUTXD_Write(LPUARTOp.TxBuf[0]);//启动第一个数据的发送	
	TicksDelayMs(10, NULL );//软件延时
	LPUART_LPUCON_TCIE_Setable(DISABLE); //禁止发送中断
	
  LPUART_COMPARE_Write(0x33);//写数据匹配寄存器
  LPUART_LPUCON_RXIE_Setable(ENABLE);//使能接收中断
	
}

在这里需要注意的有几点:其一是发送完成需要使能接收中断,不然接收不到数据;其二是如果有禁止中断指令,那上一句的软件延时时间一定要大于发送的数组长度,最好是不要禁止发送中断。其三是注意发送的长度,当接收或者发送不是预想中的长度时,看是否设置的发送长度与想发送的数组一致。

以下是低功耗串口中断函数:

void LPUART_IRQHandler(void)
{
	uint08 tmp08;
	//接收中断处理
	if((ENABLE == LPUART_LPUCON_RXIE_Getable())
		&&(SET == LPUART_LPUSTA_MATCH_Chk()))//接收数据匹配中断
	{
		tmp08 = LPUART_LPURXD_Read();   
       LPUART_LPUSTA_MATCH_Clr();      //清除数据匹配标志
	}
	
	//发送中断处理
	if((ENABLE == LPUART_LPUCON_TCIE_Getable())
		&&(SET == LPUART_LPUIF_TC_IF_Chk()))
	{
		//发送指定长度的数据
		if(LPUARTOp.TxOpc < LPUARTOp.TxLen)
		{
			LPUART_LPUTXD_Write(LPUARTOp.TxBuf[LPUARTOp.TxOpc]); //发送一个数据
		}
		//清除发送中断标志
    LPUART_LPUIF_TC_IF_Clr();
    LPUARTOp.TxOpc++;
	}
}

当在初始化中设置的数据匹配,中断中判断的是LPUART_LPUSTA_MATCH_Chk(),且接收完一个字节就清除匹配标志,那只能接收一个字节,并且每次都必须是匹配字节。

	if((ENABLE == LPUART_LPUCON_RXIE_Getable())
		&&(SET == LPUART_LPUSTA_MATCH_Chk()))//接收数据匹配中断
	{
		tmp08 = LPUART_LPURXD_Read();
		BUFFER[i]=tmp08;
		i++;					 
    LPUART_LPUSTA_MATCH_Clr();      //清除数据匹配标志
	}
	
	//发送中断处理
	.......
}

当在初始化中设置的数据匹配,中断中判断的是LPUART_LPUIF_RXIF_Chk();如果在接收到每个字节后清除接收中断标志 :LPUART_LPUIF_RXIF_Clr(); 到接收完一定长度的字节后清除匹配标志:LPUART_LPUSTA_MATCH_Clr(); 那就能一个字节一个字节的接收到一定长度的数据。代码见下(具体中断里的代码怎么写根据自己的需求):

void LPUART_IRQHandler(void)
{
	uint08 tmp08;	
	//接收中断处理
	if((ENABLE == LPUART_LPUCON_RXIE_Getable())
		&&(SET == LPUART_LPUIF_RXIF_Chk())) 
	{
		tmp08 = LPUART_LPURXD_Read();
		BUFFER[i]=tmp08;
		i++;					
	  if(i==3) 
	  {
		  i=0;
		  flag=1;
	     LPUART_LPUSTA_MATCH_Clr();      //清除数据匹配标志
	 }		 
    LPUART_LPUIF_RXIF_Clr();        //清除接收中断标志
	}
	
	//发送中断处理
	if((ENABLE == LPUART_LPUCON_TCIE_Getable())
		&&(SET == LPUART_LPUIF_TC_IF_Chk()))
	{
		//发送指定长度的数据
		if(LPUARTOp.TxOpc < LPUARTOp.TxLen)
		{
			LPUART_LPUTXD_Write(LPUARTOp.TxBuf[LPUARTOp.TxOpc]); //发送一个数据
		}
		//清除发送中断标志
    LPUART_LPUIF_TC_IF_Clr();
    LPUARTOp.TxOpc++;
	}
}

如果在LPUART_SInit(&init_para);函数里面的接收中断事件配置是:LPUART_LPUCON_RXEV_1BYTE,则在低功耗下,任何字节都可以进行唤醒。发送给串口的数据也不需要特定字节。代码如下:

void LPUART_IRQHandler(void)
{
	uint08 tmp08=0;        //从寄存器中读取到的值 
	
	if((ENABLE == LPUART_LPUCON_RXIE_Getable())
		&&((SET == LPUART_LPUIF_RXIF_Chk())))    //接收完成中断标志位检测函数
	{
		tmp08 = LPUART_LPURXD_Read(); 	
		readLPchar=tmp08;
		LPComcheckflag=1;
		//只接收不处理		
	   if(LPComcheckflag==1)
	   {
			ReFromComputer[LPnum]=readLPchar;
			LPnum++;
		}
		if(((LPnum == ReFromComputer[2] + 4))&&(LPComcheckflag==1))   //普通模式下:2*帧头+1*数据长度+x*数据内容+校验。 说明接收完成。
			{
				LPComcheckflag=0;           //进入接收标志清零                    
			}
     }
		LPUART_LPUIF_RXIF_Clr();        //清除接收中断标志   接收完成中断标志位清0函数
	 }
	
	//发送中断处理
	if((ENABLE == LPUART_LPUCON_TCIE_Getable())
		&&(SET == LPUART_LPUIF_TC_IF_Chk()))
	{
		if(LPUARTOp.LPTxOpc < LPUARTOp.LPTxLen)    //发送指定长度的数据
		{
			LPUART_LPUTXD_Write(LPUARTOp.LPTxBuf[LPUARTOp.LPTxOpc]); //发送一个数据
		}
		//清除发送中断标志
    LPUART_LPUIF_TC_IF_Clr();
    LPUARTOp.LPTxOpc++;          
	}
}

我所使用到的低功耗串口大概就是这两种,且它在低功耗下最高只支持9600。有什么问题可以通过提问完善。

你可能感兴趣的:(国产化芯片FM33G0系列之低功耗串口)