2021-05-19 FREERTOS计数信号量

计数型信号量
描述:计数型信号量相当于队列项目大于1的队列,不用设置队列的存储内容,只管队列的计数值大小。
用处:
1.事件计数型信号量
一个任务或者中断可以释放该计数信号量,即写入信号量。初始值为0,写入一次加1.设置信号量的最大值为MAX,MAX一般为最大255.
写入的值不能大于该MAX,大于该MAX则写入失败。
其它单个任务包含多个任务都可以获取该计数信号量,可以等待该计数信号量的值,获取成功则执行该任务,获取失败则处于阻塞状态,多个任务同事阻塞,则优先级高的任务优先获取计数型信号量,获取之后数值减1.
2、资源管理计数
例如多个任务执行次数管理,初始化计数为VAL,多个任务可以获取该计数来执行该任务,获取一次则计数减一,中断函数可以通过中断来释放信号量即写入信号量,此时计数加1. 当计数读取为0时则任务阻塞。多个任务则无法执行,等待计数加1.

创建计数型信号量

#include "semphr.h"  //头文件
SemaphoreHandle_t  CountSemaphore;//任务句柄
CountSemaphore=xSemaphoreCreateCounting(255,0);//创建一个计数信号量

释放计数型信号量

xSemaphoreGiveFromISR(CountSemaphore);  //普通任务释放计数型信号量
extern SemaphoreHandle_t  CountSemaphore;
void TIM5_IRQHandler(void)
{
	u8 Phore_Count=0;//计数信号量值的大小
	BaseType_t err;
	BaseType_t pxHigherPriorityTaskWoken;
	pxHigherPriorityTaskWoken=pdFALSE;
	if(TIM_GetITStatus(TIM5,TIM_IT_Update)==SET) //溢出中断
	{
		if(CountSemaphore!=NULL)
		{
		   err=xSemaphoreGiveFromISR(CountSemaphore,&pxHigherPriorityTaskWoken);
		   Phore_Count=uxSemaphoreGetCount(CountSemaphore);//获取信号量的值的大小
		   portYIELD_FROM_ISR(xHigherPriorityTaskWoken);//如果需要的话进行任务切换
		}
	}
	TIM_ClearITPendingBit(TIM5,TIM_IT_Update);  //清除中断标志位
}

获取二值信号量

void battery_task(void *pvParameters)
{	
	 u8 Phore_Countsave=0;
	 float adcdata;
	 u16 tmp,temp;
	 u16 nUNIT=4096/(3.3*11);//每伏电压对应的ADC数值
   while(1)
   {
		 xSemaphoreTake(CountSemaphore,portMAX_DELAY);//获取计数型信号量
		 Phore_Countsave=uxSemaphoreGetCount(CountSemaphore);//得到计数型信号量的值
 			//发送数据帧电量显示
 		  TxBuffer2[0]='S';
 		  TxBuffer2[1]=6;
 		 if(Battery_Update())
 			{
 			  adcdata = (float)Battery_AdcValue/65535.0f;  //16位精度
 			  adcdata *= 3.0f;   //参考电压
 			  adcdata *= 11;     //电路放大倍数
 			  adcdata *= 10;     //发送放大倍数
 			  temp = (u16)adcdata;
 			  TxBuffer2[2] = temp/10;
 			  TxBuffer2[3] = temp%10;
 			}
 			else
 			{
 			   while (DMA_GetFlagStatus(DMA2_Stream4,DMA_FLAG_TCIF4) == RESET){}
 		     tmp = AverageVal(ADC1ConvertedValue,5);	
 				 TxBuffer2[2] = tmp/nUNIT;//电量整数部分	
 			   TxBuffer2[3] = 10*(tmp%nUNIT)/nUNIT;//电量小数部分,精确到点后一位
 		  } 
 			  CRC_check(TxBuffer2,5);//校验和(注:校验和本身之前的所有数据之和)
 		    TxBuffer2[5]='E';
			  //vTaskList(InfoBuffer);							//获取所有任务的信息
 			  USART2_data(TxBuffer2,6);
        vTaskDelay(10);			    
 	 }
    	
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值