1.全局变量实现任务通信
定义一个全局变量,通过串口接收上位机发来的数据,然后保存在全局变量中,然后LED任务根据全局变量数据决定点哪个灯
还需要一个标记flag充当锁的角色,如果没收到数据flag=0,就不会实现灯的反转,和锁一样
1.串口接收数据放到全局变量中,将flag=1,
2.当flag=0说明数据没就绪,如果就绪,就开始灯反转
2.使用队列实现上述操作
该队列为环形队列,满足先进先出
队列的使用
xQueueHandle LEDqueue;
LEDqueue=xQueueCreate(1,1);
void StartUARTTask(void* arg)
{ uint8_t data;
for(;;)
{
HAL_UART_Receive(&huart1,&data,1,HAL_MAX_DELAY);
xQueueSend(LEDqueue,&data,portMAX_DELAY);
}
}
void StartLEDTask(void *arg)
{
uint8_t data;
for(;;)
{
xQueueReceive(LEDqueue,&data,portMAX_DELAY);
switch(data)
{
case '1':
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_10);
break;
case '2':
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_2);
break;
case '3':
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_1);
break;
case '4':
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_0);
break;
}
}
}
当队列中没数据时,xQueueSend函数就会阻塞,当队列中数据满的时候,
xQueueReceive函数阻塞,这样就代替了flag的作用
3.上位机直接控制灯的亮灭
使用队列,队列中每个元素为一个结构体,结构体包含哪个灯以及灯的状态
1.定义结构体
2.队列一个元素,该元素类型为结构体
3.将串口读到的放在数组中,然后传给队列
void StartUARTTask(void* arg)
{ info_t data;
uint8_t ret[2]={0};
for(;;)
{
HAL_UART_Receive(&huart1,ret,2,HAL_MAX_DELAY);
if(ret[0]>='1'&&ret[0]<='4'&&ret[1]>='0'&&ret[1]<='1')
{
data.which=ret[0];
data.state=ret[1];
}
xQueueSend(LEDqueue,&data,portMAX_DELAY);
}
}
4.从队列中取出
void StartLEDTask(void *arg)
{
info_t st;
uint8_t state;
for(;;)
{
xQueueReceive(LEDqueue,&st,portMAX_DELAY);
if(st.state=='0')
{
state=GPIO_PIN_SET; //灯亮
}
else if(st.state=='1')
{
state=GPIO_PIN_RESET; //灯灭
}
switch(st.which)
{
case '1':
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,(GPIO_PinState)state);
break;
case '2':
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,(GPIO_PinState)state);
break;
case '3':
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,(GPIO_PinState)state);
break;
case '4':
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,(GPIO_PinState)state);
break;
}
}
}
4.问题
共享数据使用信号量,互斥锁解决