初级会员
- 积分
- 62
- 金钱
- 62
- 注册时间
- 2015-7-24
- 在线时间
- 6 小时
|
1金钱
[mw_shl_code=c,true]#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "malloc.h"
#include "string.h"
#include "adc.h"
/************************************************
************************************************/
//任务优先级
#define START_TASK_PRIO 1
//任务堆栈大小
#define START_STK_SIZE 256
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);
//任务优先级
#define LED0_TASK_PRIO 2
//任务堆栈大小
#define LED0_STK_SIZE 256
//任务句柄
TaskHandle_t LED0Task_Handler;
//任务函数
void led0_task(void *pvParameters);
//任务优先级
#define LED1_TASK_PRIO 3
//任务堆栈大小
#define LED1_STK_SIZE 256
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);
#define MESSAGE_Q_NUM 1 //发送数据的消息队列的数量
QueueHandle_t Message_Queue; //信息队列句柄
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
delay_init(); //延时函数初始化
uart_init(115200); //初始化串口
uart_init_2(9600);
LED_Init(); //初始化LED
// P_IN1=0; //控制电机转动
// P_IN2=1;
// P_IN3=0;
// P_IN4=1;
RUN=1;
STOP=1;
//创建开始任务
xTaskCreate((TaskFunction_t )start_task, //任务函数
(const char* )"start_task", //任务名称
(uint16_t )START_STK_SIZE, //任务堆栈大小
(void* )NULL, //传递给任务函数的参数
(UBaseType_t )START_TASK_PRIO, //任务优先级
(TaskHandle_t* )&StartTask_Handler); //任务句柄
vTaskStartScheduler(); //开启任务调度
}
//开始任务任务函数
void start_task(void *pvParameters)
{
taskENTER_CRITICAL(); //进入临界区 critical 临界的
//创建LED0任务
Message_Queue=xQueueCreate(MESSAGE_Q_NUM,USART_REC_LEN); //创建消息Message_Queue,队列项长度是串口接收缓冲区长度
xTaskCreate((TaskFunction_t )led0_task,
(const char* )"led0_task",
(uint16_t )LED0_STK_SIZE,
(void* )NULL,
(UBaseType_t )LED0_TASK_PRIO,
(TaskHandle_t* )&LED0Task_Handler);
//创建LED1任务
xTaskCreate((TaskFunction_t )led1_task,
(const char* )"led1_task",
(uint16_t )LED1_STK_SIZE,
(void* )NULL,
(UBaseType_t )LED1_TASK_PRIO,
(TaskHandle_t* )&LED1Task_Handler);
vTaskDelete(StartTask_Handler); //删除开始任务
taskEXIT_CRITICAL(); //退出临界区
}
//LED0任务函数
void led0_task(void *pvParameters)
{
while(1)
{
LED0=~LED0; //PC12 RUN
LED1=~LED1;
vTaskDelay(500);
// USART_SendData(USART2, 2);
}
}
//LED1任务函数
void led1_task(void *pvParameters)
{
u8 *buffer;
// BaseType_t xTaskWokenByReceive=pdFALSE;
u8 i;
while(1)
{
if(Message_Queue!=NULL)
{
buffer=mymalloc(SRAMIN,USART_REC_LEN);
memset(buffer,0,USART_REC_LEN); //清除缓冲区 把buffer的前 USART_REC_LEN 个字节设置为 0
}
i=xQueueReceive(Message_Queue,buffer,10);
// if(xQueueReceiveFromISR(Message_Queue,buffer,&xTaskWokenByReceive))
if(xQueueReceive(Message_Queue,buffer,portMAX_DELAY))
{
i=buffer[2];
switch(i)
{
case 0X31:
P_IN1=0; //前进
P_IN2=1;
P_IN3=0;
P_IN4=1;
RUN=0;
STOP=1; break ;
case 0X32:
P_IN1=1; //后退
P_IN2=0;
P_IN3=1;
P_IN4=0;
RUN=0;
STOP=1; break ;
case 0X33 :
P_IN1=0; //左
P_IN2=1;
P_IN3=0;
P_IN4=0;
RUN=0;
STOP=1; break ;
case 0X34 :
P_IN1=0; //右
P_IN2=0;
P_IN3=0;
P_IN4=1;
RUN=0;
STOP=1; break ;
case 0X53 :
P_IN1=0; //停止
P_IN2=0;
P_IN3=0;
P_IN4=0;
RUN=1;
STOP=0; break ;
}
myfree(SRAMIN,buffer); //释放内存
}
vTaskDelay(10);
}
}
[/mw_shl_code][mw_shl_code=c,true]void USART1_IRQHandler(void) //串口1中断服务程序
{
u8 a;
BaseType_t xHigherPriorityTaskWoken;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
a=USART_ReceiveData(USART1); //读取接收到的数据
USART_RX_BUF[Res++]=a;
if(Res>=3)
{
Res=0;
Flag_message=1;
}
}
if(Message_Queue!=NULL&&Flag_message==1)
{
Flag_message=0;
Res=0;
xQueueSendFromISR(Message_Queue,USART_RX_BUF,&xHigherPriorityTaskWoken);//向队列中发送数据
memset(USART_RX_BUF,0,USART_REC_LEN);//清除数据接收缓冲区USART_RX_BUF,用于下一次数据接收
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);//如果需要的话进行一次任务切换
}
} [/mw_shl_code]
这个是修改了原子的队列历程,然后串口接收后,通过队列发送到主函数,来判断后执行一些动作,现在程序是个小车测试用的。现在遇到的问题是,我在进行AD采集,那采集的值该怎么传倒一个任务中呢,裸机是通过全局数组,现在有了RTOS,得通过这些消息队列,信号之类的传送吗?还是说,直接全局数组也是可以的,但看原子的教程说,用全局变量会影响一些东西,那这样的话,上了系统后,编程不是变的很麻烦吗?每次要定义队列,传的时候还要申请内存之类的各种操作。。。。
|
|