main.c
#include "Config.h"
#include "Command.h"
#include "Control.h"
#include "bsp.h"
#include "delay.h"
#include "24C512.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
//==================================================
//任务优先级
#define START_TASK_PRIO 1
//任务堆栈大小
#define START_STK_SIZE 128
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);
//任务优先级
#define LED1_TASK_PRIO 1
//任务堆栈大小
#define LED1_STK_SIZE 50
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void Led1_task(void *pvParameters);
//任务优先级
#define KEY_TASK_PRIO 1
//任务堆栈大小
#define KEY_STK_SIZE 50
//任务句柄
TaskHandle_t KEYTask_Handler;
//任务函数
void Key_task(void *pvParameters);
//任务优先级
#define uart1_process_TASK_PRIO 1
//任务堆栈大小
#define uart1_process_task_STK_SIZE 128
//任务句柄
TaskHandle_t uart1_process_Task_Handler;
//任务函数
void uart1_process_task(void const *pvParameters);
QueueHandle_t Rx_Message_Queue; //信息队列句柄,用来传递串口接收到的数据
#define MESSAGE_Q_NUM 1000 //接收数据的消息队列的数量 (本实验这里指的是可存储连续10条串口指令) 改大可以缓解大数据量的吞吐
//==================================================
int main(void)
{
BSP_Init();//Board Init,板级初始化
System_init();
//init_config();//调取eeprom参数
//创建任务
//创建开始任务
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(); //开启任务调度
while(1);
}
//
void start_task(void *pvParameters)
{
taskENTER_CRITICAL(); //进入临界区
//Tx_Message_Queue=xQueueCreate(MESSAGE_Q_NUM,sizeof(u8));
Rx_Message_Queue=xQueueCreate(MESSAGE_Q_NUM,sizeof(u8));//MESSAGE_Q_NUM队列的队列长度,这里是队列的项目数,队列中每个项目(消息)的长度,单位为字节
//
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);
xTaskCreate((TaskFunction_t )Key_task,
(const char* )"KEY_task",
(uint16_t )KEY_STK_SIZE,
(void* )NULL,
(UBaseType_t )KEY_TASK_PRIO,
(TaskHandle_t* )&KEYTask_Handler);
//
xTaskCreate((TaskFunction_t )uart1_process_task,
(const char* )"uart1_process_task",
(uint16_t )uart1_process_task_STK_SIZE,
(void* )NULL,
(UBaseType_t )uart1_process_TASK_PRIO,
(TaskHandle_t* )&uart1_process_Task_Handler);
vTaskDelete(StartTask_Handler); //删除开始任务
taskEXIT_CRITICAL(); //退出临界区
}
//
void Led1_task(void *pvParameters)
{
while(1)
{
//GPIO_WriteBit(GPIOC, GPIO_Pin_13, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_13)));
LED1_ON();
vTaskDelay(500);
LED1_OFF();
vTaskDelay(500);
}
}
void Key_task(void *pvParameters)
{
while(1){
Key_Scan();
}
}
//
#define MY_CMD_SIZE 0x0a
enum input_stat
{
NULL__=0,
WATI_NORMAL,
WATI_FUNCTION,
};
struct my_shell
{
enum input_stat stat;
char line[MY_CMD_SIZE];
uint8_t line_position;//队头
uint8_t line_curpos;//队尾
};
struct my_shell _shell,*shell;
//
void uart1_process_task(void const *pvParameters)
{
uint8_t ch;
shell=&_shell;//结构体指针指向结构体变量
while(1)
{
// if( USARTStructure2.RX_Flag==1 ){ /*If receive the command*/
// USARTStructure2.RX_Flag=0; //清标志位
// USARTStructure2.RX_TMEP_Len=0;
// USARTStructure2.RX_Len=0;
// Command_exec((char*)USARTStructure2.RX_TEMP_BUFF);
// //Check2((char *)USARTStructure2.RX_TEMP_BUFF); /*Run the action*/
// }
while(xQueueReceive( Rx_Message_Queue, &ch, 10 ) != pdPASS){//没有收到数据继续读,读到就跳出执行163行后面程序,(读取队列Rx_Message_Queue过程中把读到的数据拷贝到ch缓冲区中,读取成功以后就会将队列中的这条数据删除)
if (shell->line_curpos == 0)//一条正确格式的指令后就会清0 看182行
continue;//继续执行155行
shell->line_position--; //频繁接收出错(shell->line_curpos!=0) 队头指针回0位置 正常不会执行到这里
shell->line_curpos--; //队尾指针回0位置
shell->line[shell->line_position]= 0; //出错清除shell队列里面内容
}
if(ch=='\r'){
char next;
if(xQueueReceive( Rx_Message_Queue , &next, 10 ) == pdPASS){//如果队列读取成功
if(next=='\0'){
ch='\r';
}
else {
ch=next;//正常带\r\n的指令 解析\r的时候执行到这儿 ch=0x0A 接着执行178行
}
}
else{
ch='\r';//如果队列读取失败
}
}
/* handle end of line, break 处理命令行结尾*/
if (ch == '\r' || ch == '\n'){
Command_exec(shell->line); //解析队列里面的内容
memset(shell->line, 0, sizeof(shell->line));
shell->line_curpos = shell->line_position = 0;//初始化为0位置
continue;//跳转到146行
}
/* it's a large line, discard it 命令行太长*/
if (shell->line_position>=MY_CMD_SIZE)//判断是否是长指令
{
shell->line_position = 0;
shell->line_curpos = 0;
}
shell->line[shell->line_position] = ch;//把指令存到缓冲区里面
ch=0;//接收数据变量清0
shell->line_position++; //收到数据队头指针向后移一位
shell->line_curpos++; //收到数据队尾指针向后移一位
}
}
uart2.c
extern QueueHandle_t Rx_Message_Queue;
unsigned char uart2_data;
void USART2_IRQHandler(void)
{
BaseType_t xHigherPriorityTaskWoken=pdFALSE;
BaseType_t err;
if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET) // 串口接收数据触发中断
{
USART_ClearITPendingBit(USART2, USART_IT_RXNE); //清空接收中断标志
uart2_data=USART_ReceiveData(USART2);
err=xQueueSendFromISR(Rx_Message_Queue,&uart2_data,&xHigherPriorityTaskWoken);//发送消息到队尾uart2_data->Rx_Message_Queue
if(err==errQUEUE_FULL){
printf("xQueue is full,send message fail to pc\r\n");
}
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
}
command.c
#include "Config.h"
#include "string.h"
#include "Control.h"
#include "Command.h"
#include "USART1_init.h"
#include "24C512.h"
#include "delay.h"
#include "SysTick.h"
#include "crc16.h"
typedef void (*op_func)();
void Help(void *parameters);
struct _cmd
{
char *str;
uint8_t parameters;
void *f;
};
//===================================================
const struct _cmd Cmd[]=
{
{"HELP",0,Help},
{"FWVER",0,Fwver},
{"SET_OUT",0,Set_OUT},
{"RESET_OUT",0,Reset_OUT},
{"GET_ALL_SENSOR_STATUS",0,Get_ALL_Sensor_Status},
{"RESET",0,Reset},
{"BEEP",0,Beep},
};
#define CMD_LEN sizeof(Cmd)/sizeof(struct _cmd) //84/12
//===================================================
void Help(void *parameters){
int j,i;
i=CMD_LEN;
for(j=0;j<i;j++)
{
printf("%s\r\n",Cmd[j].str);
}
printf("OK\r\n");
}
//===================================================
int uart_strncmp(const char *str,const char *cmd_str)
{
for(;;)
{
if(*cmd_str=='\0')
{
if(((int)*str<48)||(((int)*str>57)&&((int)*str<65))||(((int)*str>90)&&((int)*str<96))||((int)*str>122))
{
if((int)*str!=95)
break;
}
}
if(*str != *cmd_str)return 1;//
str++;
cmd_str++;
}
return 0;
}
//===================================================
char pr[32];
void Command_exec(char *cChar){
int parameterv[8],temp;
unsigned int parameters,i;
op_func p;
for(i=0;i<CMD_LEN;i++) //CMD_LEN为指令的个数
{
if(uart_strncmp(cChar,Cmd[i].str)==0)
{
parameters=Cmd[i].parameters; //保存函数参数个数
sscanf(cChar,"%*[^(](%[^)]" ,pr); //cChar为uart2缓冲区中的指令 %*[^(] + ( + %[^)] 3部分组成 pr含有数字和逗号和句号 例如1,2,3,4,5,6 %*[^(]:忽略(之前的非(字符 %[^):取)之前的字符
p=(op_func)Cmd[i].f; //函数指针指向结构体函数指针
if(p!=NULL){
switch(parameters) //解析函数参数个数
{
case 0:p(pr);break;
case 1:
temp=sscanf(pr,"%d",¶meterv[0]);
if(temp==1){
p(parameterv[0]);
}
else i=CMD_LEN; //错误的指令,退出for循环
break;
case 2:
temp=sscanf(pr,"%d,%d",parameterv,parameterv+1);
if(temp==2){
p(parameterv[0],parameterv[1]);
}
else i=CMD_LEN;//错误的指令,退出for循环 下达指令函数参数只能多不能少 少则出错 多则不报错
break;
default: break;
}
}
break;//跳出for循环 使得i值不增加 为不识别的指令判断创造判断条件
}
}
if(i>=CMD_LEN){
printf("Command Not Found!\r\n"); //无法匹配命令表时 i=CMD_LEN
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)