曾经玩Linux时非常喜欢这种基于出串口的控制台, 通过简单的串口TX和RX能实现嵌入式硬件的人机交互,非常实用, 那么STM32能否实现通过超级终端与用户互动的构想呢? 答案是肯定的,由于这个UART控制平台就像应用程序套上一层可访问的外科(Shell)故而我将这种基于UART的控制平台简称Shell,构架和效果如下图:
这张图箭头指向的是输入的指令,其余是STM32串口输出的信息,, 可以看到通过这些简单的指令输入我们通过Shell可以做很多事情:
1. 现场设备发生故障,可以通过Shell可以查看设备的故障状态统计信息
2. 能实现串口程序升级(需要Shell+IAP驱动程序支持)
3. 能读写访问参数区,实现对设备参数的本地配置
4. 配置多功能信号指示灯(LED灯可显示65535种信号,同一时刻只能显示一个.
5. 程序开发阶段基于Shell,可以极其方便的调试编写的驱动程序(开发极力推荐),非常好用.
Shell基础程序只有三个文件:
console.h:用于定义STM32用于Shell的实体串口
shell.cshell平台实现主体
shell.h头文件,任意的驱动文件可调用,就像
shell.c目前包含三个部件:
shell模块(必选)Shell模块初始化时已初始化好Led模块
Led模块(必选)Ledx_on(x),Ledx_off(x),Ledx_div(x),函数是对编码信号进行控制,而不是直接对硬件实体控制,这样每个LED实体就像通道一样可以选择非常多的信号源显示.
精密延时模块(可选)启动需要对其初始化,此模块可用于记录时间点,并判断时间是否到(再也不用Delayms()这样的函数浪费效率实现时序了.
/*********************************Copyright (c)*********************************
**
** FIVE工作组
**
**---------------------------------File Info------------------------------------
** File Name: shell_hal.h
** Last modified Date: 2014/5/26 14:22:35
** Last Version: V1.0
** Description: 本地Shell文件接口
**
**------------------------------------------------------------------------------
** Created By: wanxuncpx
** Created date: 2014/5/26 14:22:34
** Version: V2
** Descriptions: 只适合STM32程序
**------------------------------------------------------------------------------
** Libraries: STM32F10x_StdPeriph_Driver
** version V3.5
*******************************************************************************/
/******************************************************************************
更新说明:
******************************************************************************/
/******************************************************************************
********************************* 应 用 资 料 ********************************
******************************************************************************/
#ifndef _SHELL_HAL_
#define _SHELL_HAL_
/******************************************************************************
********************************* 文件引用部分 ********************************
******************************************************************************/
//包含库文件
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_tim.h"
/******************************************************************************
******************************** 可 配 置 参 数 *******************************
******************************** MNCS_IMAGE图像板 *****************************
******************************************************************************/
/*---------------------*
* UART端口配置
*----------------------*/
//IO配置
#define CONSOLE USART3
#define CONSOLE_TX_PORT GPIOB
#define CONSOLE_TX_PIN GPIO_Pin_10
#define CONSOLE_RX_PORT GPIOB
#define CONSOLE_RX_PIN GPIO_Pin_11
//时钟配置
#define CONSOLE_GPIO_RCC_INIT() RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE)
#define CONSOLE_UART_RCC_INIT() RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE)
//中断优先级
#define CONSOLE_UART_PRIO 7 //建议[0..15]
//中断向量配置
#define CONSOLE_IRQn USART3_IRQn;
#define CONSOLE_IRQHandler USART3_IRQHandler
/*---------------------*
* 四个LED定义
*----------------------*/
#define LED0_VALID 1 //非零表示使能对应的LED,0:无效
#define LED0_PORT GPIOB
#define LED0_PIN GPIO_Pin_13
#define LED1_VALID 1 //非零表示使能对应的LED,0:无效
#define LED1_PORT GPIOB
#define LED1_PIN GPIO_Pin_15
#define LED2_VALID 0 //非零表示使能对应的LED,0:无效
#define LED2_PORT GPIOA
#define LED2_PIN GPIO_Pin_11
#define LED3_VALID 0 //非零表示使能对应的LED,0:无效
#define LED3_PORT GPIOA
#define LED3_PIN GPIO_Pin_11
#define LED4_VALID 0 //非零表示使能对应的LED,0:无效
#define LED4_PORT GPIOA
#define LED4_PIN GPIO_Pin_11
#define LED5_VALID 0 //非零表示使能对应的LED,0:无效
#define LED5_PORT GPIOA
#define LED5_PIN GPIO_Pin_11
/*---------------------*
* 时基BASE
*----------------------*/
#define TIMEDly TIM4
#define TIMEDly_IRQn TIM4_IRQn
#define TIMEDly_IRQHandler TIM4_IRQHandler
//时钟配置
#define TIMEDly_RCC_INIT() RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
//初始化LGPIO口
#define LEDx_GPIO_RCC_INIT() RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE)
//------------------------------------------------------------------------------
/******************************************************************************
******************************* 以下参数无需更改 ******************************
******************************************************************************/
/*---------------------*
* 注意以下区域无需用户更改
*----------------------*/
#if LED0_VALID
#define LED0_ON() (LED0_PORT->BRR = LED0_PIN)
#define LED0_OFF() (LED0_PORT->BSRR = LED0_PIN)
#define LED0_DIV() (LED0_PORT->ODR ^= LED0_PIN)
#else
#define LED0_ON() __NOP()
#define LED0_OFF() __NOP()
#define LED0_DIV() __NOP()
#endif
#if LED1_VALID
#define LED1_ON() (LED1_PORT->BRR = LED1_PIN)
#define LED1_OFF() (LED1_PORT->BSRR = LED1_PIN)
#define LED1_DIV() (LED1_PORT->ODR ^= LED1_PIN)
#else
#define LED1_ON() __NOP()
#define LED1_OFF() __NOP()
#define LED1_DIV() __NOP()
#endif
#if LED2_VALID
#define LED2_ON() (LED2_PORT->BRR = LED2_PIN)
#define LED2_OFF() (LED2_PORT->BSRR = LED2_PIN)
#define LED2_DIV() (LED2_PORT->ODR ^= LED2_PIN)
#else
#define LED2_ON() __NOP()
#define LED2_OFF() __NOP()
#define LED2_DIV() __NOP()
#endif
#if LED3_VALID
#define LED3_ON() (LED3_PORT->BRR = LED3_PIN)
#define LED3_OFF() (LED3_PORT->BSRR = LED3_PIN)
#define LED3_DIV() (LED3_PORT->ODR ^= LED3_PIN)
#else
#define LED3_ON() __NOP()
#define LED3_OFF() __NOP()
#define LED3_DIV() __NOP()
#endif
#if LED4_VALID
#define LED4_ON() (LED4_PORT->BSRR = LED4_PIN)
#define LED4_OFF() (LED4_PORT->BRR = LED4_PIN)
#define LED4_DIV() (LED4_PORT->ODR ^= LED4_PIN)
#else
#define LED4_ON() __NOP()
#define LED4_OFF() __NOP()
#define LED4_DIV() __NOP()
#endif
#if LED5_VALID
#define LED5_ON() (LED5_PORT->BSRR = LED5_PIN)
#define LED5_OFF() (LED5_PORT->BRR = LED5_PIN)
#define LED5_DIV() (LED5_PORT->ODR ^= LED5_PIN)
#else
#define LED5_ON() __NOP()
#define LED5_OFF() __NOP()
#define LED5_DIV() __NOP()
#endif
/******************************************************************************
******************************* printf支持文件 ********************************
******************************************************************************/
/* Private function prototypes -----------------------------------------------*/
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
/******************************************************************************
*********************************** END ************************************
******************************************************************************/
#endif
/*********************************Copyright (c)*********************************
**
** FIVE工作组
**
**---------------------------------File Info------------------------------------
** File Name: shell.h
** Last modified Date: 2014/3/5 15:42:05
** Last Version: V2
** Description: none
**
**------------------------------------------------------------------------------
** Created By: wanxuncpx
** Created date: 2014/3/5 15:42:11
** Version: V2
** Descriptions: none
**------------------------------------------------------------------------------
** Libraries: 无关
** version 无关
*******************************************************************************/
/******************************************************************************
更新说明:
******************************************************************************/
/******************************************************************************
********************************* 应 用 资 料 ********************************
******************************************************************************/
#ifndef _SHELL_H_
#define _SHELL_H_
/******************************************************************************
********************************* 文件引用部分 ********************************
******************************************************************************/
#include "stdint.h" //包含uint8_t等数据类型
#include "stdbool.h" //包含Bool类型
#include "stdio.h" //包含printf支持
/******************************************************************************
********************************* 参数宏定义 *********************************
******************************************************************************/
//版本定义
#define SHELL_VER 2 //Shell版本
#ifndef SHELL_LED_MAX //LED实体数量
#define SHELL_LED_MAX 4
#endif
//缓冲大小配置
#define SHELL_RX_MAX (256+32) //shell指令接收缓冲大小
#define SHELL_TX_MAX (512) //shell指令发送缓冲大小
/******************************************************************************
********************************* 数 据 声 明 *********************************
******************************************************************************/
/*---------------------*
* Shell接收
*----------------------*/
//接收数据
extern volatile uint16_t shell_rx_rdy; //0:空闲,非零:忙,用户读为非零后清零
extern volatile uint8_t shell_rx_buff[SHELL_RX_MAX+1]; //接收缓冲
/******************************************************************************
********************************* 函 数 声 明 *********************************
******************************************************************************/
/*---------------------*
* 输出函数
*----------------------*/
//调试Shell的接口数量
#if (6 == SHELL_LED_MAX)
extern void shell_GPIO_Config(uint16_t led0_cfg,uint16_t led1_cfg,
uint16_t led2_cfg,uint16_t led3_cfg,
uint16_t led4_cfg,uint16_t led5_cfg);
#elif (5 == SHELL_LED_MAX)
extern void shell_GPIO_Config(uint16_t led0_cfg,uint16_t led1_cfg,
uint16_t led2_cfg,uint16_t led3_cfg,
uint16_t led4_cfg);
#elif (4 == SHELL_LED_MAX)
extern void shell_GPIO_Config(uint16_t led0_cfg,uint16_t led1_cfg,
uint16_t led2_cfg,uint16_t led3_cfg);
#elif (3 == SHELL_LED_MAX)
extern void shell_GPIO_Config(uint16_t led0_cfg,uint16_t led1_cfg,
uint16_t led2_cfg);
#elif (2 == SHELL_LED_MAX)
extern void shell_GPIO_Config(uint16_t led0_cfg,uint16_t led1_cfg);
#elif (1 == SHELL_LED_MAX)
extern void shell_GPIO_Config(uint16_t led0_cfg);
#endif
//检测参数合法性
#if ((SHELL_LED_MAX > 6) || (SHELL_LED_MAX == 0))
#error SHELL_LED_MAX is invaild!
#endif
//初始化Shell
extern void shell_Init(uint32_t baud); //模块初始化
extern void shell_SendStr(void * ptStr); //发送以'\0'结束的字符串
extern void shell_SendHex(void * ptHex,uint16_t size); //发送指定个数的数据
/*---------------------*
* LEDx测试信号定义
*----------------------*/
extern void Ledx_config(uint8_t led_id,uint16_t msg_id); //设置LED的配置信号
extern uint16_t Ledx_read(uint8_t led_id); //读取LED的配置信号(失败返回0)
extern void Ledx_on (uint16_t msg_id); //发送LED开消息
extern void Ledx_off(uint16_t msg_id); //发送LED关消息
extern void Ledx_div(uint16_t msg_id); //发送LED取反消息
/*---------------------*
* 时基延时函数
*----------------------*/
extern void Delay_LibInit(void);
extern void DlyTime_us(uint16_t us);
extern void DlyTime_ms(uint16_t ms);
extern void DlyWait_base(volatile uint64_t * ptCnt); //标记为等待的基点时间
extern uint32_t DlyWait_lost(volatile uint64_t * ptCnt);//判断逝去的时间(us)
/*---------------------*
* 辅助判断指令
*----------------------*/
extern bool StrComp(void * buffer,void * StrCmd); //字符串匹配比较函数
/*---------------------*
* Shell服务
*----------------------*/
//在main.c函数while()中判断shell_rx_rdy是否为非零,为非零才执行以下程序
extern void Shell_Invalid_Service(void); //指令未处理服务(会处理shell_rx_rdy信号)
/******************************************************************************
*********************************** END ************************************
******************************************************************************/
#endif
/*********************************Copyright (c)*********************************
**
** FIVE工作组
**
**---------------------------------File Info------------------------------------
** File Name: shell.c
** Last modified Date: 2014/3/5 16:43:59
** Last Version: V2
** Description: none
**
**------------------------------------------------------------------------------
** Created By: wanxuncpx
** Created date: 2014/3/5 16:43:58
** Version: V2
** Descriptions: 适合于STM32
**------------------------------------------------------------------------------
** Libraries: STM32F10x_StdPeriph_Driver
** version V3.5
*******************************************************************************/
/******************************************************************************
更新说明:
******************************************************************************/
/******************************************************************************
********************************* 应 用 资 料 ********************************
******************************************************************************/
/******************************************************************************
********************************* 文件引用部分 ********************************
******************************************************************************/
#include "shell.h" //包含Shell接口文件
//是否使用扩展的Shell接口
#ifdef SHELL_HAL_EXT
#include "shell_hal.h" //本地的Shell文件
#else
#include "console.h" //标准的Shell文件
#endif
/******************************************************************************
********************************* Shell.h定义 *********************************
******************************************************************************/
/*---------------------*
* Shell 收发标记
*----------------------*/
volatile uint16_t shell_rx_rdy = 0; //0:空闲,非零:忙
volatile uint8_t shell_rx_buff[SHELL_RX_MAX+1]="\0"; //接收缓冲
/******************************************************************************
********************************* 本 地 数 据 *********************************
******************************************************************************/
/*---------------------*
* Shell缓冲定义
*----------------------*/
//接收
static volatile uint16_t shell_rx_index = 0; //数据接收标记
//发送
static volatile uint8_t shell_tx_buff[SHELL_TX_MAX+1]="\0";
static volatile uint16_t shell_tx_size = 0; //0:空闲,非零:忙
static volatile uint16_t shell_tx_index = 0; //发送数据标记
/*---------------------*
* LED控制信号
*----------------------*/
static volatile uint16_t msg_led_cfg[SHELL_LED_MAX]; //配置信号
/*---------------------*
* 延时模块定义
*----------------------*/
static volatile uint64_t TimeDlyCnt = 0; //用于辅助的延时计数值
/******************************************************************************
********************************* 函 数 声 明 *********************************
******************************************************************************/
/******************************************************************************
/ 函数功能:初始化GPIO口(串口和四个LED灯配置)
/ 修改日期:none
/ 输入参数:none
/ 输出参数:none
/ 使用说明:none
******************************************************************************/
#if (6 == SHELL_LED_MAX)
void shell_GPIO_Config( uint16_t led0_cfg,uint16_t led1_cfg,
uint16_t led2_cfg,uint16_t led3_cfg,
uint16_t led4_cfg,uint16_t led5_cfg)
#elif (5 == SHELL_LED_MAX)
void shell_GPIO_Config( uint16_t led0_cfg,uint16_t led1_cfg,
uint16_t led2_cfg,uint16_t led3_cfg,
uint16_t led4_cfg)
#elif (4 == SHELL_LED_MAX)
void shell_GPIO_Config( uint16_t led0_cfg,uint16_t led1_cfg,
uint16_t led2_cfg,uint16_t led3_cfg)
#elif (3 == SHELL_LED_MAX)
void shell_GPIO_Config( uint16_t led0_cfg,uint16_t led1_cfg,
uint16_t led2_cfg)
#elif (2 == SHELL_LED_MAX)
void shell_GPIO_Config(uint16_t led0_cfg,uint16_t led1_cfg)
#elif (1 == SHELL_LED_MAX)
void shell_GPIO_Config(uint16_t led0_cfg)
#endif
{
GPIO_InitTypeDef GPIO_InitStruct;
/* 配置串口 ---------------------------------------------------------*/
// 打开在APB2上的GPIO口外设时钟
CONSOLE_GPIO_RCC_INIT(); //打开GPIO口的时钟
// 配置TX引脚
GPIO_InitStruct.GPIO_Pin = CONSOLE_TX_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(CONSOLE_TX_PORT, &GPIO_InitStruct);
// 配置RX引脚
GPIO_InitStruct.GPIO_Pin = CONSOLE_RX_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(CONSOLE_RX_PORT, &GPIO_InitStruct);
//锁定GPIO口,防止其他更改
GPIO_PinLockConfig(CONSOLE_TX_PORT,CONSOLE_TX_PIN);
GPIO_PinLockConfig(CONSOLE_RX_PORT,CONSOLE_RX_PIN);
/* 配置LEDx ---------------------------------------------------------*/
LEDx_GPIO_RCC_INIT();
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
//根据定义配置四个LED
#if (SHELL_LED_MAX > 0)
GPIO_InitStruct.GPIO_Pin = LED0_PIN;
GPIO_Init(LED0_PORT, &GPIO_InitStruct);
GPIO_PinLockConfig(LED0_PORT,LED0_PIN);
msg_led_cfg[0] = led0_cfg;
LED0_OFF();
#endif
#if (SHELL_LED_MAX > 1)
GPIO_InitStruct.GPIO_Pin = LED1_PIN;
GPIO_Init(LED1_PORT, &GPIO_InitStruct);
GPIO_PinLockConfig(LED1_PORT,LED1_PIN);
msg_led_cfg[1] = led1_cfg;
LED1_OFF();
#endif
#if (SHELL_LED_MAX > 2)
GPIO_InitStruct.GPIO_Pin = LED2_PIN;
GPIO_Init(LED2_PORT, &GPIO_InitStruct);
GPIO_PinLockConfig(LED2_PORT,LED2_PIN);
msg_led_cfg[2] = led2_cfg;
LED2_OFF();
#endif
#if (SHELL_LED_MAX > 3)
GPIO_InitStruct.GPIO_Pin = LED3_PIN;
GPIO_Init(LED3_PORT, &GPIO_InitStruct);
GPIO_PinLockConfig(LED3_PORT,LED3_PIN);
msg_led_cfg[3] = led3_cfg;
LED3_OFF();
#endif
#if (SHELL_LED_MAX > 4)
GPIO_InitStruct.GPIO_Pin = LED4_PIN;
GPIO_Init(LED4_PORT, &GPIO_InitStruct);
GPIO_PinLockConfig(LED4_PORT,LED4_PIN);
msg_led_cfg[4] = led4_cfg;
LED4_OFF();
#endif
#if (SHELL_LED_MAX > 5)
GPIO_InitStruct.GPIO_Pin = LED5_PIN;
GPIO_Init(LED5_PORT, &GPIO_InitStruct);
GPIO_PinLockConfig(LED5_PORT,LED5_PIN);
msg_led_cfg[5] = led5_cfg;
LED5_OFF();
#endif
}
/******************************************************************************
/ 函数功能:串口初始化,使用中断单字节接收数据
/ 修改日期:none
/ 输入参数:baud 波特率
/ 输出参数:none
/ 使用说明:none
******************************************************************************/
void shell_Init(uint32_t baud)
{
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_UART_Cfg; //UART中断向量
//--------------------------- 先定义好数据结构 ---------------------------
//定义好USART结构体
USART_InitStructure.USART_BaudRate = baud;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No ;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_InitStructure.USART_BaudRate = USART_InitStructure.USART_BaudRate; //防止编译报错
//定义好NVIC:UART中断
NVIC_UART_Cfg.NVIC_IRQChannel = CONSOLE_IRQn;
NVIC_UART_Cfg.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_UART_Cfg.NVIC_IRQChannelSubPriority = CONSOLE_UART_PRIO;
NVIC_UART_Cfg.NVIC_IRQChannelCmd = ENABLE;
NVIC_UART_Cfg.NVIC_IRQChannel = NVIC_UART_Cfg.NVIC_IRQChannel; //防止编译报错
//模式配置
//--------------------------- 中断方式收发数据 ----------------------------
CONSOLE_UART_RCC_INIT(); //打开USART的时钟
USART_Cmd(CONSOLE, DISABLE); //关闭UART
USART_Init(CONSOLE, &USART_InitStructure); //初始化串口
USART_ITConfig(CONSOLE, USART_IT_RXNE, ENABLE);
USART_ITConfig(CONSOLE, USART_IT_IDLE, ENABLE);
USART_Cmd(CONSOLE, ENABLE);
NVIC_Init(&NVIC_UART_Cfg); //配置好NVIC
}
/******************************************************************************
/ 函数功能:Delay延时库初始化(需要1us的计数精度,和50ms的溢出计数)
/ 修改日期:2014/5/1 21:02:58
/ 输入参数:none
/ 输出参数:none
/ 使用说明:(限STM32F40X的TIM2,TIM3,TIM4,TIM5)
******************************************************************************/
void Delay_LibInit(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//开启TIM2时钟
TIMEDly_RCC_INIT();
/* Enable the TIMx gloabal Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIMEDly_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //由于是时基,需要使用最高优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 65000;
TIM_TimeBaseStructure.TIM_Prescaler = (SystemCoreClock/1000000)-1;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIMEDly, &TIM_TimeBaseStructure);
/* TIM Interrupts enable */
TIM_ITConfig(TIMEDly,TIM_IT_Update, ENABLE);
/* TIMx enable counter */
TIM_Cmd(TIMEDly, ENABLE);
}
/******************************************************************************
/ 函数功能:等待一个us延时
/ 修改日期:2014/5/1 21:02:58
/ 输入参数:none
/ 输出参数:none
/ 使用说明:none
******************************************************************************/
void DlyTime_us(uint16_t us)
{
uint64_t this_cnt,over_cnt,tmp_val;
//得到当前的准确时间
do
{
this_cnt = TIMEDly->CNT + TimeDlyCnt;
if( (TIMEDly->SR & TIM_IT_Update) &&
(TIMEDly->SR & TIM_IT_Update) &&
(TIMEDly->SR & TIM_IT_Update) )
{
TIMEDly->SR = (uint16_t)~TIM_IT_Update;
TimeDlyCnt += 65000;
}
tmp_val = TIMEDly->CNT + TimeDlyCnt;
}
while(this_cnt != tmp_val);
over_cnt = this_cnt + us; //得到目标延时时间
//延时函数
do
{
if( (TIMEDly->SR & TIM_IT_Update) &&
(TIMEDly->SR & TIM_IT_Update) &&
(TIMEDly->SR & TIM_IT_Update) )
{
TIMEDly->SR = (uint16_t)~TIM_IT_Update;
TimeDlyCnt += 65000;
}
this_cnt = TIMEDly->CNT + TimeDlyCnt;
}
while(this_cnt < over_cnt);
}
/******************************************************************************
/ 函数功能:等待一个ms延时
/ 修改日期:2014/5/1 21:02:58
/ 输入参数:none
/ 输出参数:none
/ 使用说明:none
******************************************************************************/
void DlyTime_ms(uint16_t ms)
{
uint64_t this_cnt,over_cnt,tmp_val;
//得到当前的准确时间
do
{
this_cnt = TIMEDly->CNT + TimeDlyCnt;
if( (TIMEDly->SR & TIM_IT_Update) &&
(TIMEDly->SR & TIM_IT_Update) &&
(TIMEDly->SR & TIM_IT_Update) )
{
TIMEDly->SR = (uint16_t)~TIM_IT_Update;
TimeDlyCnt += 65000;
}
tmp_val = TIMEDly->CNT + TimeDlyCnt;
}
while(this_cnt != tmp_val);
over_cnt = this_cnt + (uint32_t)ms*1000;
//延时函数
do
{
if( (TIMEDly->SR & TIM_IT_Update) &&
(TIMEDly->SR & TIM_IT_Update) &&
(TIMEDly->SR & TIM_IT_Update) )
{
TIMEDly->SR = (uint16_t)~TIM_IT_Update;
TimeDlyCnt += 65000;
}
this_cnt = TIMEDly->CNT + TimeDlyCnt;
}
while(this_cnt < over_cnt);
}
/******************************************************************************
/ 函数功能:标记时间起点
/ 修改日期:2014/5/1 21:02:58
/ 输入参数:none
/ 输出参数:none
/ 使用说明:none
******************************************************************************/
void DlyWait_base(volatile uint64_t * ptCnt)
{
uint64_t this_cnt,tmp_val;
//得到当前的准确时间
do
{
this_cnt = TIMEDly->CNT + TimeDlyCnt;
if( (TIMEDly->SR & TIM_IT_Update) &&
(TIMEDly->SR & TIM_IT_Update) &&
(TIMEDly->SR & TIM_IT_Update) )
{
TIMEDly->SR = (uint16_t)~TIM_IT_Update;
TimeDlyCnt += 65000;
}
tmp_val = TIMEDly->CNT + TimeDlyCnt;
}
while(this_cnt != tmp_val);
*ptCnt = this_cnt;
}
/******************************************************************************
/ 函数功能:检测从起点开始已逝去的时间(最大1个小时)
/ 修改日期:2014/5/1 21:02:58
/ 输入参数:none
/ 输出参数:返回0表示时间到,返回非零表示时间未到
/ 使用说明:none
******************************************************************************/
uint32_t DlyWait_lost(volatile uint64_t * ptCnt)
{
uint64_t this_cnt,tmp_val;
//得到当前的准确时间
do
{
this_cnt = TIMEDly->CNT + TimeDlyCnt;
if( (TIMEDly->SR & TIM_IT_Update) &&
(TIMEDly->SR & TIM_IT_Update) &&
(TIMEDly->SR & TIM_IT_Update) )
{
TIMEDly->SR = (uint16_t)~TIM_IT_Update;
TimeDlyCnt += 65000;
}
tmp_val = TIMEDly->CNT + TimeDlyCnt;
}
while(this_cnt != tmp_val);
//计算已逝去的时间
if(*ptCnt <= this_cnt)
{
tmp_val = this_cnt - *ptCnt;
if(tmp_val > (65536UL*65536UL-1))
return (uint32_t)(65536UL*65536UL-1);
else return (uint32_t)tmp_val;
}
else
{
*ptCnt = this_cnt;
return 0;
}
}
/******************************************************************************
/ 函数功能:中断支持函数(限STM32F40X的TIM2,TIM3,TIM4,TIM5)
/ 修改日期:2014/5/1 21:02:58
/ 输入参数:none
/ 输出参数:none
/ 使用说明:none
******************************************************************************/
void TIMEDly_IRQHandler(void)
{
//简单写法
if( TIMEDly->SR & TIM_IT_Update )
{
TIMEDly->SR = (uint16_t)~TIM_IT_Update;
TimeDlyCnt += 65000;
//Ledx_div(3); //时基信号
}
}
/******************************************************************************
/ 函数功能:printf支持函数
/ 修改日期:none
/ 输入参数:none
/ 输出参数:none
/ 使用说明:none
******************************************************************************/
PUTCHAR_PROTOTYPE
{
Ledx_on(11);
/* Loop until the end of transmission */
while( (CONSOLE->SR & USART_FLAG_TXE) == RESET );
/* Place your implementation of fputc here */
/* e.g. write a character to the USART */
CONSOLE->DR = ch;
/* Loop until the end of transmission */
//while( (CONSOLE->SR & USART_FLAG_TC) == RESET );
Ledx_off(11);
return ch;
}
/******************************************************************************
/ 函数功能:字符串发送函数
/ 修改日期:none
/ 输入参数:none
/ 输出参数:none
/ 使用说明:none
******************************************************************************/
void shell_SendStr(void * ptAsc)
{ //中断方式
//--------------------------- 中断方式收发数据 ----------------------------
uint16_t i,size;
uint8_t *ptDst;
uint8_t const *ptSrc; //源数据只读不写
//计算字符串的长度
ptSrc = (uint8_t const *)ptAsc;
size = 0;
while(*ptSrc++){size++;}
//判断字符串是否超过缓冲
Ledx_on(11);
if(size > SHELL_TX_MAX)
{
//关闭中断发送方式
shell_tx_index = 0;
shell_tx_size = 0;
CONSOLE->CR1 &= ~USART_CR1_TXEIE; //关闭发送完毕中断
ptSrc = (uint8_t const *)ptAsc;
while(size--)
{
while( (CONSOLE->SR & USART_FLAG_TXE) == RESET );
CONSOLE->DR = *ptSrc++;
}
Ledx_off(11);
}
else if( !(CONSOLE->CR1 & USART_CR1_TXEIE) )
{
//如果未启用非空中断则,启用非空中断发送数据
//复制数据
ptDst = (uint8_t *)shell_tx_buff;
ptSrc = (uint8_t const *)ptAsc;
for(i=0; iCR1 |= USART_CR1_TXEIE; //启动发送非空中断
}
}
/******************************************************************************
/ 函数功能:发送Hex数据函数
/ 修改日期:none
/ 输入参数:none
/ 输出参数:none
/ 使用说明:none
******************************************************************************/
void shell_SendHex(void * ptHex,uint16_t size)
{ //中断方式
//--------------------------- 中断方式收发数据 ----------------------------
uint16_t i;
uint8_t *ptDst;
uint8_t const *ptSrc; //源数据只读不写
Ledx_on(11);
if(size > SHELL_TX_MAX)
{
//关闭中断发送方式
shell_tx_index = 0;
shell_tx_size = 0;
CONSOLE->CR1 &= ~USART_CR1_TXEIE; //关闭发送完毕中断
//直接发送数据
ptSrc = (uint8_t const *)ptHex;
while(size--)
{
while( (CONSOLE->SR & USART_FLAG_TXE) == RESET );
CONSOLE->DR = *ptSrc++;
}
Ledx_off(11);
}
else if( !(CONSOLE->CR1 & USART_CR1_TXEIE) )
{
//如果未启用非空中断则,启用非空中断发送数据
//复制数据
ptDst = (uint8_t *)shell_tx_buff;
ptSrc = (uint8_t const *)ptHex;
for(i=0; iCR1 |= USART_CR1_TXEIE; //启动发送非空中断
}
}
/******************************************************************************
/ 函数功能:中断服务程序
/ 修改日期:none
/ 输入参数:none
/ 输出参数:none
/ 使用说明:none
******************************************************************************/
void CONSOLE_IRQHandler(void)
{
uint8_t rxd_reg,txd_reg;
uint16_t isr_reg;
//中断配置
//--------------------------- 中断方式收发数据 ----------------------------
isr_reg = CONSOLE->SR;
//接收中断
if( (CONSOLE->CR1 & USART_CR1_RXNEIE) && (isr_reg & USART_SR_RXNE) )
{
rxd_reg = CONSOLE->DR;
Ledx_on(12);
if(shell_rx_rdy)shell_rx_index = 0; //忙模式收到字节,重置接收指针
else
{
if( shell_rx_index < SHELL_RX_MAX)
{
shell_rx_buff[shell_rx_index] = rxd_reg;
shell_rx_index++;
}
else
{
shell_rx_index = 0;
Ledx_off(12);
}
}
}
if( (CONSOLE->CR1 & USART_CR1_IDLEIE) && (isr_reg & USART_SR_IDLE) )
{
CONSOLE->SR;
CONSOLE->DR;
if(shell_rx_rdy)shell_rx_index = 0; //忙模式收到空闲,重置接收指针
else
{
if( (shell_rx_index >=2) && ('\r' == shell_rx_buff[shell_rx_index-2]) &&
('\n' == shell_rx_buff[shell_rx_index-1]) ) //以"\r\n"结尾
{
shell_rx_rdy = shell_rx_index;
shell_rx_index = 0;
Ledx_off(12);
}
else if( (shell_rx_index > 0) && ('\b' == shell_rx_buff[shell_rx_index-1]) ) //以\b结尾
{
shell_rx_index = shell_rx_index <2? 0:shell_rx_index-2;
printf(" \b"); //发送辅助删除
}
}
}
//发送非空中断
if( (CONSOLE->CR1 & USART_CR1_TXEIE) && (isr_reg & USART_SR_TXE ) )
{
if(shell_tx_size && (shell_tx_index < shell_tx_size) )
{
txd_reg = shell_tx_buff[shell_tx_index++];
CONSOLE->DR = txd_reg; //发送数据
}
else
{
//关闭非空中断
shell_tx_index = 0;
shell_tx_size = 0;
CONSOLE->CR1 &= ~USART_CR1_TXEIE; //关闭发送完毕中断
Ledx_off(11);
}
}
}
/******************************************************************************
/ 函数功能:指令(ASCII或HEX指令)未处理消息回执
/ 修改日期:2013/9/12 20:25:45
/ 输入参数:none
/ 输出参数:none
/ 使用说明:一字节一字节接收数据,拼装为指令
******************************************************************************/
void Shell_Invalid_Service(void)
{
int tx_len,i,led_id,msg_id;
uint8_t * ptSrc;
uint8_t * ptDst;
uint8_t tmp_buff[64];
//指令识别
if(2 > shell_rx_rdy)
{
shell_rx_buff[0] = 0;
return;
}
else if( ('\r' == shell_rx_buff[shell_rx_rdy-2]) && ('\n' == shell_rx_buff[shell_rx_rdy-1]) )
{
ptSrc = (uint8_t *)shell_rx_buff;
if(2 == shell_rx_rdy)
{
//填写数据
tx_len = (uint16_t)sprintf((void *)tmp_buff,"\r\nAT:OK!\r\n");
//发送数据
shell_SendHex(tmp_buff,tx_len); //发送数据
}
else if(StrComp(ptSrc,"led rd\r\n")) //显示LED的信号配置
{
//填写数据
tx_len = (uint16_t)sprintf((void *)tmp_buff,
#if (6 == SHELL_LED_MAX)
"->LED0=%d LED1=%d tLED2=%d LED3=%d LED4=%d LED5=%d\r\n",
msg_led_cfg[0],msg_led_cfg[1],msg_led_cfg[2],
msg_led_cfg[3],msg_led_cfg[4],msg_led_cfg[5]);
#elif (5 == SHELL_LED_MAX)
"->LED0=%d LED1=%d tLED2=%d LED3=%d LED4=%d\r\n",
msg_led_cfg[0],msg_led_cfg[1],msg_led_cfg[2],
msg_led_cfg[3],msg_led_cfg[4]);
#elif (4 == SHELL_LED_MAX)
"->LED0=%d LED1=%d tLED2=%d LED3=%d\r\n",
msg_led_cfg[0],msg_led_cfg[1],msg_led_cfg[2],
msg_led_cfg[3]);
#elif (3 == SHELL_LED_MAX)
"->LED0=%d LED1=%d tLED2=%d\r\n",
msg_led_cfg[0],msg_led_cfg[1],msg_led_cfg[2]);
#elif (2 == SHELL_LED_MAX)
"->LED0=%d LED1=%d\r\n",
msg_led_cfg[0],msg_led_cfg[1]);
#elif (1 == SHELL_LED_MAX)
"->LED0=%d\r\n",
msg_led_cfg[0]);
#endif
//发送数据
shell_SendHex(tmp_buff,tx_len); //发送数据
}
else if(StrComp(ptSrc,"led wr ")) //设置LED的信号配置
{
if(2 != sscanf((void *)ptSrc,"%*s%*s%d=%d",&led_id,&msg_id) )goto ERROR_LOOP;
if( (led_id>(SHELL_LED_MAX-1)) || (msg_id >65535) )goto ERROR_LOOP;
Ledx_config((uint8_t)led_id,(uint16_t)msg_id); //配置信号
//填写数据
tx_len = (uint16_t)sprintf((void *)tmp_buff,
"->LED[%d]_Msg=%d\r\n",led_id,msg_led_cfg[led_id]);
//发送数据
shell_SendHex(tmp_buff,tx_len); //发送数据
}
else goto ERROR_LOOP;
}
else
{
ERROR_LOOP:
//填写指令码
tx_len = (uint16_t)sprintf((void *)tmp_buff,"\r\nAT: Cmd Error:\t\"");
//计算地址,填写数据,填写尾部
ptDst = tmp_buff + tx_len;
ptSrc = (uint8_t *)shell_rx_buff;
if(shell_rx_rdy > 32)
{
for(i=0; i<32; i++)
{
if( (*ptSrc > 126) || (*ptSrc < 32) )
{
*ptDst++ = '?';
ptSrc++;
}
else
{
*ptDst++ = *ptSrc++;
}
}
*(ptDst-2) = '-';
*(ptDst-1) = '>';
tx_len += 32;
}
else
{
for(i=0; i 0)
if(msg_id == msg_led_cfg[0])LED0_ON();
#endif
#if (SHELL_LED_MAX > 1)
if(msg_id == msg_led_cfg[1])LED1_ON();
#endif
#if (SHELL_LED_MAX > 2)
if(msg_id == msg_led_cfg[2])LED2_ON();
#endif
#if (SHELL_LED_MAX > 3)
if(msg_id == msg_led_cfg[3])LED3_ON();
#endif
#if (SHELL_LED_MAX > 4)
if(msg_id == msg_led_cfg[4])LED4_ON();
#endif
#if (SHELL_LED_MAX > 5)
if(msg_id == msg_led_cfg[5])LED5_ON();
#endif
}
/******************************************************************************
/ 函数功能:关闭LED信号
/ 修改日期:none
/ 输入参数:none
/ 输出参数:none
/ 使用说明:none
******************************************************************************/
void Ledx_off(uint16_t msg_id)
{
#if (SHELL_LED_MAX > 0)
if(msg_id == msg_led_cfg[0])LED0_OFF();
#endif
#if (SHELL_LED_MAX > 1)
if(msg_id == msg_led_cfg[1])LED1_OFF();
#endif
#if (SHELL_LED_MAX > 2)
if(msg_id == msg_led_cfg[2])LED2_OFF();
#endif
#if (SHELL_LED_MAX > 3)
if(msg_id == msg_led_cfg[3])LED3_OFF();
#endif
#if (SHELL_LED_MAX > 4)
if(msg_id == msg_led_cfg[4])LED4_OFF();
#endif
#if (SHELL_LED_MAX > 5)
if(msg_id == msg_led_cfg[5])LED5_OFF();
#endif
}
/******************************************************************************
/ 函数功能:取反LED信号
/ 修改日期:none
/ 输入参数:none
/ 输出参数:none
/ 使用说明:none
******************************************************************************/
void Ledx_div(uint16_t msg_id)
{
#if (SHELL_LED_MAX > 0)
if(msg_id == msg_led_cfg[0])LED0_DIV();
#endif
#if (SHELL_LED_MAX > 1)
if(msg_id == msg_led_cfg[1])LED1_DIV();
#endif
#if (SHELL_LED_MAX > 2)
if(msg_id == msg_led_cfg[2])LED2_DIV();
#endif
#if (SHELL_LED_MAX > 3)
if(msg_id == msg_led_cfg[3])LED3_DIV();
#endif
#if (SHELL_LED_MAX > 4)
if(msg_id == msg_led_cfg[4])LED4_DIV();
#endif
#if (SHELL_LED_MAX > 5)
if(msg_id == msg_led_cfg[5])LED5_DIV();
#endif
}
/******************************************************************************
/ 函数功能:配置LED信号
/ 修改日期:none
/ 输入参数:none
/ 输出参数:none
/ 使用说明:none
******************************************************************************/
void Ledx_config(uint8_t led_id,uint16_t msg_id)
{
if(0 == led_id) {LED0_OFF();msg_led_cfg[0]=msg_id;}
#if(SHELL_LED_MAX > 1)
else if(1 == led_id){LED1_OFF();msg_led_cfg[1]=msg_id;}
#endif
#if(SHELL_LED_MAX > 2)
else if(2 == led_id){LED2_OFF();msg_led_cfg[2]=msg_id;}
#endif
#if(SHELL_LED_MAX > 3)
else if(3 == led_id){LED3_OFF();msg_led_cfg[3]=msg_id;}
#endif
#if(SHELL_LED_MAX > 4)
else if(4 == led_id){LED4_OFF();msg_led_cfg[4]=msg_id;}
#endif
#if(SHELL_LED_MAX > 5)
else if(5 == led_id){LED5_OFF();msg_led_cfg[5]=msg_id;}
#endif
}
/******************************************************************************
/ 函数功能:读取LED的配置信号
/ 修改日期:none
/ 输入参数:none
/ 输出参数:none
/ 使用说明:none
******************************************************************************/
uint16_t Ledx_read(uint8_t led_id)
{
if(0 == led_id) return msg_led_cfg[0];
#if(SHELL_LED_MAX > 1)
else if(1 == led_id)return msg_led_cfg[1];
#endif
#if(SHELL_LED_MAX > 2)
else if(2 == led_id)return msg_led_cfg[2];
#endif
#if(SHELL_LED_MAX > 3)
else if(3 == led_id)return msg_led_cfg[3];
#endif
#if(SHELL_LED_MAX > 4)
else if(4 == led_id)return msg_led_cfg[4];
#endif
#if(SHELL_LED_MAX > 5)
else if(5 == led_id)return msg_led_cfg[5];
#endif
else return 0;
}
/******************************************************************************
*********************************** END ************************************
******************************************************************************/
/******************************************************************************
*********************************Shell 函数声 明 ******************************
******************************************************************************/
extern void Shell_SPI_Service(void);
extern void Shell_RTC_Service(void);
extern void Shell_WIZ_Service(void);
extern void Shell_UPAN_Service(void);
extern void Shell_IAP_Service(uint8_t const this_ver);
shell_GPIO_Config(30,10,46,1); //shell接口和四个LED灯的信号配置
shell_Init(460800); //初始化shell控制台
//Shell构架的控制台服务
if(shell_rx_rdy)
{
Shell_IAP_Service(SOFT_VER); //IAP模块指令处理
Shell_SPI_Service(); //SPI_FLASH模块指令处理
Shell_WIZ_Service(); //网卡模块的指令处理
Shell_RTC_Service(); //RTC模块的指令处理
Shell_MCU_Service(); //MCU杂项功能指令处理
Shell_VLSI_Service(); //声卡模块的指令处理
Shell_UPAN_Service(); //U盘模块的指令处理
Shell_Invalid_Service(); //指令无效的缺省处理
}
这里展示一个Shell服务的文件模板写法:
/*********************************Copyright (c)*********************************
**
** FIVE工作组
**
**---------------------------------File Info------------------------------------
** File Name: rtc_shell.c
** Last modified Date: 2014/3/5 9:27:49
** Last Version: V2.0
** Description: 文件操作命令解释,需要Console Shell V2以上支持
**
**------------------------------------------------------------------------------
** Created By: wanxuncpx
** Created date: 2014/3/5 9:28:31
** Version: V2.0
** Descriptions: none
**------------------------------------------------------------------------------
** HW_CMU: ANSIC
** Libraries: NONE
** version NONE
*******************************************************************************/
/******************************************************************************
更新说明:
******************************************************************************/
/******************************************************************************
********************************* 编 译 控 制 ********************************
******************************************************************************/
#define RTC_SHELL //注释掉时屏蔽iap shell功能
/******************************************************************************
********************************* 文件引用部分 ********************************
******************************************************************************/
/*---------------------*
* 文件包含
*----------------------*/
//基础支持文件
#include "shell.h" //Shell支持文件,含bool,uint8_t..以及串口数据收发操作
#include "rtc.h" //命令控制支持文件
/*---------------------*
* Shell版本判断
*----------------------*/
#ifdef SHELL_VER
#if (SHELL_VER < 2)
#error "shell版本太低"
#endif
#else
#error "未找到Shell文件,或shell版本信息"
#endif
/******************************************************************************
********************************* 输出函数功能 ********************************
******************************************************************************/
/*---------------------*
* 输出函数功能
*----------------------*/
#ifdef RTC_SHELL
extern void Shell_RTC_Service(void);
#else
void Shell_RTC_Service(void){;}
#endif
/*---------------------*
* 输入函数
*----------------------*/
//none
/******************************************************************************
********************************* 数 据 声 明 *********************************
******************************************************************************/
#ifdef RTC_SHELL
/*---------------------*
*
*----------------------*/
//命令帮助文件
const char RTC_HelpMsg[] =
"[RTC contorls]\r\n"
" rtc help\t\t- help.\r\n"
" rtc rd info\t\t- Read RTC info.\r\n"
" rtc rd time\t\t- Read RTC date and time.\r\n"
" rtc wr time :: - Write time.\r\n"
" rtc wr date -- - Warning Week=[1..7]\r\n"
"\r\n";
/******************************************************************************
********************************* 函 数 声 明 *********************************
******************************************************************************/
/******************************************************************************
/ 函数功能:文件系统Shel指令处理
/ 修改日期:2013/9/10 19:04:15
/ 输入参数:输入当前的程序版本
/ 输出参数:none
/ 使用说明:none
******************************************************************************/
void Shell_RTC_Service(void)
{
uint8_t *ptRxd; //用于接收指令处理
//uint8_t *ptTxd; //方便用于指令发送
int i,j,k,l;
//int tx_len,drv;
//uint32_t u32_arg[4];
uint16_t retval;
uint8_t arg[32];
uint32_t tmp_time;
//指令初级过滤
//--------------------------------------------------------------------------
//格式:<->[cmd bytes] 即"-[cmd bytes]\r\n"
//指令必须以"-"开始, 以"\r\n"结束
i = shell_rx_rdy;
if( (i < 2) || ('\r' != shell_rx_buff[i-2]) || ('\n' != shell_rx_buff[i-1]))return;
//长度和前缀过滤
ptRxd = (uint8_t *)shell_rx_buff;
if( (' ' != shell_rx_buff[3]) || ('r' != shell_rx_buff[0]) || (i < 6) ||
('t' != shell_rx_buff[1]) || ('c' != shell_rx_buff[2]) ) return;
//处理指令
//--------------------------------------------------------------------------
ptRxd += 4;
if(StrComp(ptRxd,"rd time")) //按包读取指令
{
RTC_Sprintf_CurrTime((void *)arg);
printf("Time:%s\r\n",arg);
}
else if(StrComp(ptRxd,"rd info\r\n")) //读取RTC信息
{
//打印当前时间和上次复位时间
RTC_Sprintf_CurrTime((void *)arg);
printf("->Time:%s\tResetCounter:%d\r\n",arg,RESET_CNT);
RTC_Sprintf_ResetCurr((void *)arg,&tmp_time);
printf("\tCurrReset:%s\tRun: %d Days, %d hour, %d minute\r\n",
arg,tmp_time/(24*60),(tmp_time%(24*60))/60,tmp_time%60 );
RTC_Sprintf_ResetLast((void *)arg,&tmp_time);
printf("\tNextReset:%s\tRun: %d Days, %d hour, %d minute\r\n",
arg,tmp_time/(24*60),(tmp_time%(24*60))/60,tmp_time%60 );
}
else if(StrComp(ptRxd,"wr time ")) //写时间
{
retval = sscanf((void*)shell_rx_buff,"%*s%*s%*s%d:%d:%d",&i,&j,&k);
if(3 != retval)return; //没有接收到3个输入数据,直接退出
if(RTC_TimeWrite((uint8_t)i,(uint8_t)j,(uint8_t)k) )
{
RTC_Sprintf_CurrTime((void *)arg);
printf("->CurrTime:%s\r\n",arg);
}
else
{
printf("->Error Time Input!\r\n");
shell_rx_rdy = 0; //不用触发错误指令显示
return;
}
}
else if(StrComp(ptRxd,"wr date ")) //写日期
{
retval = sscanf((void*)shell_rx_buff,"%*s%*s%*s%d-%d-%d %d",&i,&j,&k,&l);
if(4 != retval)return; //没有接收到4个输入数据,直接退出
if(RTC_DateWrite((uint16_t)i,(uint8_t)j,(uint8_t)k,(uint8_t)l))
{
RTC_Sprintf_CurrTime((void *)arg);
printf("->CurrTime:%s\r\n",arg);
}
else
{
printf("->Error Date Input!\r\n");
shell_rx_rdy = 0; //shell_rx_rdy为0,表示指令已被处理完毕,否者下个Shell服务继续调用
return;
}
}
else if(StrComp(ptRxd,"help\r\n")) //指令帮助
{
shell_SendStr((void *)RTC_HelpMsg);
}
else return;
//退出处理
//--------------------------------------------------------------------------
shell_rx_rdy = 0; //shell_rx_rdy为0,表示指令已被处理完毕,否者下个Shell服务继续调用
}
/******************************************************************************
*********************************** END ************************************
******************************************************************************/
#endif