1,创建队列
先在挡球板任务里创建队列,后面将while里读buffer改为读队列(写程序的顺序和执行程序的顺序是反的,有点反直觉)
/* 挡球板任务 */
static void platform_task(void *params)
{
byte platformXtmp = platformX;
uint8_t dev, data, last_data;
struct platfrom_queue_data idata;
// Draw platform
draw_bitmap(platformXtmp, g_yres - 8, platform, 12, 8, NOINVERT, 0);
draw_flushArea(platformXtmp, g_yres - 8, 12, 8);
/*创建挡球板队列*/
g_platfromqueue = xQueueCreate( 10, sizeof(struct platfrom_queue_data) );
while (1)
{
/* 读取红外遥控器 */
// if (0 == IRReceiver_Read(&dev, &data))
if (pdPASS== xQueueReceive( g_platfromqueue,&idata,portMAX_DELAY))
{
data=idata.val;
if (data == 0x00)
{
data = last_data;
}
if (data == 0x02) /* Left */
{
btnLeft();
}
if (data == 0xc2) /* Right */
{
btnRight();
}
last_data = data;
// Hide platform
draw_bitmap(platformXtmp, g_yres - 8, clearImg, 12, 8, NOINVERT, 0);
draw_flushArea(platformXtmp, g_yres - 8, 12, 8);
// Move platform
if(uptMove == UPT_MOVE_RIGHT)
platformXtmp += 3;
else if(uptMove == UPT_MOVE_LEFT)
platformXtmp -= 3;
uptMove = UPT_MOVE_NONE;
// Make sure platform stays on screen
if(platformXtmp > 250)
platformXtmp = 0;
else if(platformXtmp > g_xres - PLATFORM_WIDTH)
platformXtmp = g_xres - PLATFORM_WIDTH;
// Draw platform
draw_bitmap(platformXtmp, g_yres - 8, platform, 12, 8, NOINVERT, 0);
draw_flushArea(platformXtmp, g_yres - 8, 12, 8);
platformX = platformXtmp;
}
}
}
后面修改ir接收函数里,所有写buffer的程序改为写队列,就结束了
static int IRReceiver_IRQTimes_Parse(void)
{
uint64_t time;
int i;
int m, n;
unsigned char datas[4];
unsigned char data = 0;
int bits = 0;
int byte = 0;
struct platfrom_queue_data idata;
/* 1. 判断前导码 : 9ms的低脉冲, 4.5ms高脉冲 */
time = g_IRReceiverIRQ_Timers[1] - g_IRReceiverIRQ_Timers[0];
if (time < 8000000 || time > 10000000)
{
return -1;
}
time = g_IRReceiverIRQ_Timers[2] - g_IRReceiverIRQ_Timers[1];
if (time < 3500000 || time > 55000000)
{
return -1;
}
/* 2. 解析数据 */
for (i = 0; i < 32; i++)
{
m = 3 + i*2;
n = m+1;
time = g_IRReceiverIRQ_Timers[n] - g_IRReceiverIRQ_Timers[m];
data <<= 1;
bits++;
if (time > 1000000)
{
/* 得到了数据1 */
data |= 1;
}
if (bits == 8)
{
datas[byte] = data;
byte++;
data = 0;
bits = 0;
}
}
/* 判断数据正误 */
datas[1] = ~datas[1];
datas[3] = ~datas[3];
if ((datas[0] != datas[1]) || (datas[2] != datas[3]))
{
g_IRReceiverIRQ_Cnt = 0;
return -1;
}
// PutKeyToBuf(datas[0]);
// PutKeyToBuf(datas[2]);
/*写platfrom队列*/
idata.dev=datas[0];
idata.val=datas[2];
xQueueSendToBackFromISR(g_platfromqueue,&idata,0);
return 0;
}
注意点:
1,我用的vet6不是c8t6,只移植了nwatch文件夹里的函数,也可以使用
2,写队列和读队列函数的让传入的数据指针,这里传的是结构体的指针,他是在函数里定义的,只是临时变量,它只是用暂时中转数据不是队列的buffer,后面就放到了全局变量的那个结构体(这也是队列真正传输数据的地方),为了方便,这些结构体的名字和内容一样,但是作用不一样
3,回调函数IRReceiver_IRQ_Callback,
回调函数的核心特性是被其他代码调用,而非直接由开发者主动调用。其本质是一种双向调用机制:开发者将函数指针传递给系统或框架,后者在特定事件发生时触发该函数。
在哪被调用的就不知道了