基于RTOS的小汽车游戏
- 信号量
- 信号量的创建
- 信号量的删除
- 信号量的获取与释放
- 小汽车
- 小汽车模型
- 两侧路障
- 简单测试小汽车能否正常显示
- 显示所有的小汽车和路障
- 完整代码
信号量
在RTOS中,信号量包含两种类型:二进制信号量和计数型信号量,其中二进制信号量被创建时初始值为0,而计数型则是可以设定。
信号量的创建
| 二进制信号量 | 计数型信号量 |
|---|---|
| xSemaphoreCreateBinary | xSemaphoreCreateCounting |
| xSemaphoreCreateBinaryStatic | xSemaphoreCreateCountingStatic |
信号量的删除
可以使用下面的函数删除信号量
voidvSemaphoreDelete(SemaphoreHandle_t xSemaphore);信号量的获取与释放
| 类别 | 在任务中使用 | 在ISR中使用 |
|---|---|---|
| give | xSemaphoreGive | xSemaphoreGiveFromISR |
| take | xSemaphoreTake | xSemaphoreTakeFromISR |
小汽车
可以设计三个小汽车去争抢两个信号量,抢到信号量的汽车先出发,然后到达终点释放信号量
小汽车模型
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);}