news 2026/8/31 16:00:45

基于信号量的小汽车游戏

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于信号量的小汽车游戏

基于RTOS的小汽车游戏

  • 信号量
    • 信号量的创建
    • 信号量的删除
    • 信号量的获取与释放
  • 小汽车
    • 小汽车模型
    • 两侧路障
    • 简单测试小汽车能否正常显示
    • 显示所有的小汽车和路障
    • 完整代码

信号量

在RTOS中,信号量包含两种类型:二进制信号量和计数型信号量,其中二进制信号量被创建时初始值为0,而计数型则是可以设定。

信号量的创建

二进制信号量计数型信号量
xSemaphoreCreateBinaryxSemaphoreCreateCounting
xSemaphoreCreateBinaryStaticxSemaphoreCreateCountingStatic

信号量的删除

可以使用下面的函数删除信号量

voidvSemaphoreDelete(SemaphoreHandle_t xSemaphore);

信号量的获取与释放

类别在任务中使用在ISR中使用
givexSemaphoreGivexSemaphoreGiveFromISR
takexSemaphoreTakexSemaphoreTakeFromISR

小汽车

可以设计三个小汽车去争抢两个信号量,抢到信号量的汽车先出发,然后到达终点释放信号量

小汽车模型

staticconstbyte carImg[]PROGMEM={0x40,0xF8,0xEC,0x2C,0x2C,0x38,0xF0,0x10,0xD0,0x30,0xE8,0x4C,0x4C,0x9C,0xF0,0x02,0x1F,0x37,0x34,0x34,0x1C,0x0F,0x08,0x0B,0x0C,0x17,0x32,0x32,0x39,0x0F,};

两侧路障

staticconstbyte roadMarking[]PROGMEM={0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,};

简单测试小汽车能否正常显示

voidcar_test(void){g_framebuffer=LCD_GetFrameBuffer(&g_xres,&g_yres,&g_bpp);draw_init();draw_end();draw_bitmap(0,0,carImg,15,16,NOINVERT,0);draw_flushArea(0,0,15,16);draw_bitmap(0,16,roadMarking,8,1,NOINVERT,0);draw_flushArea(0,16,8,1);}

显示所有的小汽车和路障

定义小汽车结构体,方便使用,同时定义对应的结构体数组,方便后续使用。

#definekey10#definekey21#definekey32structcar{intx;inty;intcontrol_key;};structcarcars[3]={{0,0,key1},{0,17,key2},{0,34,key3}};
//绘制路标for(inti=0;i<3;i++){for(intj=0;j<8;j++){draw_bitmap(16*j,16+i*17,roadMarking,8,1,NOINVERT,0);draw_flushArea(16*j,16+i*17,8,1);}}//测试显示三辆汽车for(inti=0;i<3;i++){draw_bitmap(cars[i].x,cars[i].y,carImg,CAR_WIDTH,CAR_LENGTH,NOINVERT,0);draw_flushArea(cars[i].x,cars[i].y,CAR_WIDTH,CAR_LENGTH);}

完整代码

/* * Project: N|Watch * Author: Zak Kemble, contact@zakkemble.co.uk * Copyright: (C) 2013 by Zak Kemble * License: GNU GPL v3 (see License.txt) * Web: http://blog.zakkemble.co.uk/diy-digital-wristwatch/ */#include<stdlib.h>#include<stdio.h>#include<string.h>#include"cmsis_os.h"#include"FreeRTOS.h"// ARM.FreeRTOS::RTOS:Core#include"task.h"// ARM.FreeRTOS::RTOS:Core#include"event_groups.h"// ARM.FreeRTOS::RTOS:Event Groups#include"semphr.h"// ARM.FreeRTOS::RTOS:Core#include"draw.h"#include"resources.h"#include"driver_lcd.h"#include"driver_ir_receiver.h"#include"driver_rotary_encoder.h"#include"driver_mpu6050.h"#defineCAR_COUNT3#defineCAR_WIDTH12#defineCAR_LENGTH15#defineROAD_SPEED6#defineNOINVERTfalse#defineINVERTtrue#definekey10#definekey21#definekey32staticuint32_tg_xres,g_yres,g_bpp;staticuint8_t*g_framebuffer;staticSemaphoreHandle_t g_xSemTicks;structcar{intx;inty;intcontrol_key;};structcarcars[3]={{0,0,key1},{0,17,key2},{0,34,key3}};staticconstbyte carImg[]PROGMEM={0x40,0xF8,0xEC,0x2C,0x2C,0x38,0xF0,0x10,0xD0,0x30,0xE8,0x4C,0x4C,0x9C,0xF0,0x02,0x1F,0x37,0x34,0x34,0x1C,0x0F,0x08,0x0B,0x0C,0x17,0x32,0x32,0x39,0x0F,};staticconstbyte roadMarking[]PROGMEM={0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,};staticconstbyte clearImg[30]={0};staticvoidshowCar(structcar*car){draw_bitmap(car->x,car->y,carImg,15,16,NOINVERT,0);draw_flushArea(car->x,car->y,15,16);}staticvoidhideCar(structcar*car){draw_bitmap(car->x,car->y,clearImg,15,16,NOINVERT,0);draw_flushArea(car->x,car->y,15,16);}staticvoidCarTask(void*params){structcar*car=(structcar*)params;//获得信号量xSemaphoreTake(g_xSemTicks,portMAX_DELAY);while(1){if(car->x<g_xres-CAR_LENGTH){hideCar(car);car->x+=1;if(car->x>g_xres-CAR_LENGTH){car->x=g_xres-CAR_LENGTH;}showCar(car);vTaskDelay(50);if(car->x>=g_xres-CAR_LENGTH){/* 释放信号量 */xSemaphoreGive(g_xSemTicks);vTaskDelete(NULL);}}}}voidcar_test(void){g_framebuffer=LCD_GetFrameBuffer(&g_xres,&g_yres,&g_bpp);draw_init();draw_end();//绘制路标for(inti=0;i<3;i++){for(intj=0;j<8;j++){draw_bitmap(16*j,16+i*17,roadMarking,8,1,NOINVERT,0);draw_flushArea(16*j,16+i*17,8,1);}}//测试显示三辆汽车for(inti=0;i<3;i++){showCar(&cars[i]);}g_xSemTicks=xSemaphoreCreateCounting(3,2);xTaskCreate(CarTask,"Car1",128,&cars[0],osPriorityNormal,NULL);xTaskCreate(CarTask,"Car2",128,&cars[1],osPriorityNormal,NULL);xTaskCreate(CarTask,"Car3",128,&cars[2],osPriorityNormal,NULL);}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/31 15:59:23

HyperMesh网格划分全流程:几何清理到3D体网格操作指南

这次我们来看一个 HyperMesh 的前处理案例&#xff1a;几何体网格划分 308。这个编号不是版本号&#xff0c;也不是官方课程编号&#xff0c;而是给“几何体网格划分”系列里的第 308 个操作示例定名。本质就是走完一条完整链路&#xff1a;把 CAD 几何导入 HyperMesh&#xff…

作者头像 李华
网站建设 2026/8/31 15:48:20

LabWindows/CVI图像处理实战:从灰度化到缺陷检测

简介&#xff1a;本资源是面向LabWindows/CVI初学者与工业图像处理工程师的实践型开发包&#xff0c;聚焦数字图像处理核心算法在测试测量场景中的落地实现。压缩包共9个文件&#xff08;98KB&#xff09;&#xff0c;含2个C源文件&#xff08;算法主体&#xff09;、2个头文件…

作者头像 李华
网站建设 2026/8/31 15:48:06

PDF流式编辑与自动重排:原理、技术路线与代码实现

1. 为什么 PDF 改文字会“牵一发动全身” 做过 PDF 编辑的人&#xff0c;大概率经历过这样的场景&#xff1a;客户发来一份排版精美的 PDF 合同&#xff0c;里面有一句话写错了&#xff0c;需要改一个名字。你打开 PDF 编辑器&#xff0c;把旧名字删掉&#xff0c;敲上新名字&a…

作者头像 李华
网站建设 2026/8/31 15:47:57

MATLAB三维电偶极子电场与电势可视化全解析

简介&#xff1a;本资源是一份面向电磁学教学与MATLAB初学者的三维物理场可视化实践材料&#xff0c;聚焦电偶极子电场与电势的建模与绘图&#xff0c;解决理论公式难以直观理解、三维场分布不易呈现的核心学习难点&#xff0c;适用于高校物理、电子工程及计算电磁学相关课程实…

作者头像 李华
网站建设 2026/8/31 15:47:50

MATLAB雷达杂波仿真:从统计模型到CFAR验证的完整实践

简介&#xff1a;本资源是一套面向雷达系统工程师、信号处理研究者及高校相关专业研究生的MATLAB雷达杂波仿真工具集&#xff0c;聚焦双基地星载雷达场景下的杂波建模与坐标系转换核心问题。资源共15个文件&#xff0c;含13个核心MATLAB函数&#xff08;.m&#xff09;与2个运行…

作者头像 李华
网站建设 2026/8/31 15:47:22

PyTorch还是TensorFlow?深度学习新手选型与环境搭建实战指南

深度学习入门最常被问到的几个问题里&#xff0c;一定包含“应该先学 PyTorch 还是 TensorFlow”。这个问题表面上只是两个框架二选一&#xff0c;背后实际对应三个更具体的问题&#xff1a;你准备用深度学习解决什么任务&#xff0c;你当前的机器能把哪个环境先跑通&#xff0…

作者头像 李华