GD32450i-EVAL测试二值信号量

测试二值信号量

前言:

先准备一个带有freertos的工程,没有的话可以参考我以前的博客------>点我跳转

测试的方法是
创建二值信号量 > 任务来获取信号量 > 按键释放信号量
按键释放有两种方法:查询点平法和外部中断法。

废话少说,开搞

电平查询法

我们用的按键是GPIO_PIN_13
main函数

#include "gd32f4xx.h"
#include "gd32f450i_eval.h"
#include <stdio.h>
#include "systick.h"

#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"

void CrateTask(void *pvParameters);
void task_a(void *pvParameters);
void task_b(void *pvParameters);

TaskHandle_t StartTask_Handler;  //任务句柄
xSemaphoreHandle xSemaphore = NULL;   //二值信号量
/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
	    gd_eval_key_init(KEY_TAMPER, KEY_MODE_GPIO);    //KEY_MODE_GPIO 查询点平的模式
		gd_eval_com_init(EVAL_COM0);   //初始化串口
		vSemaphoreCreateBinary(xSemaphore);  //新建二值信号量
		if(xSemaphore != NULL)    //判断是否创建成功
		printf("二值信号量创建成功!\r\n");
	    xTaskCreate(CrateTask ,"CrateTask" , 256, NULL, 1, &StartTask_Handler); //创建任务
		vTaskStartScheduler();          //开启任务调度
}

void CrateTask(void *pvParameters){
	taskENTER_CRITICAL();  //打开临阶段
	xTaskCreate(task_a , "task_a" ,128 ,NULL , 2 ,0);  //创建任务A
	xTaskCreate(task_b , "task_b" ,128 ,NULL , 2 ,0);   //创建任务B
	vTaskDelete(StartTask_Handler);   //删除创建任务
	taskEXIT_CRITICAL();   //关闭临界段
}

void task_a(void *pvParameters)
{  
	while(1){
        /* check if the tamper key is pressed */
        if(RESET == gd_eval_key_state_get(KEY_TAMPER)){  //消除按键抖动
            vTaskDelay(50);
            if(RESET == gd_eval_key_state_get(KEY_TAMPER)){
                vTaskDelay(50);
                if(RESET == gd_eval_key_state_get(KEY_TAMPER)){								
										xSemaphoreGive( xSemaphore);   //释放二值信号量
                }
            }
        }
				vTaskDelay(250);
    }
}   

void task_b(void *pvParameters)
{
	while(1){

				if(pdTRUE == xSemaphoreTake( xSemaphore, 500 ))       //获取信号量
			 {
					printf("获取成功!\r\n");
				}else{
					printf("等待take!\r\n");
				}
				vTaskDelay(1000);
	}
}

/* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{
    usart_data_transmit(EVAL_COM0, (uint8_t)ch);
    while(RESET == usart_flag_get(EVAL_COM0, USART_FLAG_TBE));
    return ch;
}

这样我们在main函数里面直接创建了二值信号量,然后有一个任务每隔1s获取信号量,我们可以通过按键来释放信号量。

外部按键中断法

main函数


#include "gd32f4xx.h"
#include "gd32f450i_eval.h"
#include <stdio.h>
#include "systick.h"

#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"

void task(void *pvParameters);
xSemaphoreHandle xSemaphore = NULL;
portBASE_TYPE xHigherPriorityTaskWoken = pdTRUE; //解除比当前中断优先级高的任务的阻塞态
/*
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
	    gd_eval_key_init(KEY_TAMPER, KEY_MODE_EXTI);   //KEY_MODE_EXTI 外部按键中断模式
		gd_eval_com_init(EVAL_COM0);                   //初始化串口
		vSemaphoreCreateBinary(xSemaphore);            //创建二值信号量
		if(xSemaphore != NULL)                         //判断信号量是否创建成功	
		printf("信号量创建成功!\r\n");
		else
		printf("信号量创建失败!\r\n");
		xTaskCreate(task , "task" ,128 ,NULL , 2 ,0);  //创建任务
		vTaskStartScheduler();                         //开启任务调度
}

void task(void *pvParameters)
{
	while(1){
		if(pdTRUE == xSemaphoreTake( xSemaphore, 500 )) //获取二值信号量
			printf("获取成功!\r\n");
		else
			printf("等待take!\r\n");
		vTaskDelay(1000);
	}
}

/* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{
    usart_data_transmit(EVAL_COM0, (uint8_t)ch);
    while(RESET == usart_flag_get(EVAL_COM0, USART_FLAG_TBE));
    return ch;
}

gd32f4xx_it.c在最后添加下面的代码

extern xSemaphoreHandle xSemaphore;
extern portBASE_TYPE xHigherPriorityTaskWoken;

void EXTI10_15_IRQHandler (void)                                    //按键的中断函数
{
	xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken ); //释放二值信号量
	exti_interrupt_flag_clear(EXTI_13);                             //清除中断标志位
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值