国产化芯片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(&para2);
}

在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。有什么问题可以通过提问完善。

FM33G0xx的主要特性如下:  宽电压范围: 1.8~5.5V  工作温度范围: -40℃~+85℃  处理器内核  ARM Cortex-M0+  支持用户/特权模式  支持中断向量表重定向(VTOR)  最高40MHz主频  SWD调试接口  低功耗技术平台  典型运行功耗180uA/MHz  32KHz下LPRUN功耗: 15uA  Sleep模式下带LCD显示: 6uA  DeepSleep模式, RTC走时+24KB RAM保持+CPU内核保持: 1.2uA  RTC Backup模式, RTC走时+512字节备份寄存器, 0.9uA  存储器  128/256KB Flash空间  Flash擦写寿命: >20,000次  Flash数据保存时间: 10年@85℃  用户代码保护  24KB RAM空间  最大支持73个GPIO,最多24个外部引脚中断, 最多8个异步唤醒引脚  丰富的模拟外设  高可靠、可配置BOR电路(支持4级可编程下电复位阈值)  超低功耗PDR电路(支持4级可编程下电复位阈值)  可编程电源监测模块(SVD)  2x低功耗模拟比较器  11-bit低功耗∑-△ADC,最大支持9个外部通道  高精度温度传感器,精度优于+/-2℃  通信接口  UART*6  7816智能卡接口*2  SPI*3,主从模式  I2C*1, 主机400K  7通道外设DMA  可编程CRC校验模块  定时资源  8-bit基本定时器*4  16-bit扩展定时器*4  16-bit通用定时器*1  24-bit Systick*1  16-bit低功耗定时器*1,可在休眠模式下工作  带窗口的CPU看门狗定时器*1  系统看门狗定时器*1  低功耗实时时钟日历(RTCC),带有数字调校功能, 最高调校精度+/-0.06ppm
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值