栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

GD32450i-EVAL测试二值信号量

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

GD32450i-EVAL测试二值信号量

测试二值信号量

前言:

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

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

废话少说,开搞 电平查询法

我们用的按键是GPIO_PIN_13
main函数

#include "gd32f4xx.h"
#include "gd32f450i_eval.h"
#include 
#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;   //二值信号量

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("二值信号量创建成功!rn");
	    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){
        
        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("获取成功!rn");
				}else{
					printf("等待take!rn");
				}
				vTaskDelay(1000);
	}
}


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 
#include "systick.h"

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

void task(void *pvParameters);
xSemaphoreHandle xSemaphore = NULL;
portbase_TYPE xHigherPriorityTaskWoken = pdTRUE; //解除比当前中断优先级高的任务的阻塞态

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("信号量创建成功!rn");
		else
		printf("信号量创建失败!rn");
		xTaskCreate(task , "task" ,128 ,NULL , 2 ,0);  //创建任务
		vTaskStartScheduler();                         //开启任务调度
}

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


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);                             //清除中断标志位
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/303822.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号