数据规律化是优算逻辑的充分条件,程控前,尽量让你的被控数据单元按照简易且清晰、统筹化的逻辑来进行规律化。tip: 数值控制中的common集和common非集,尽量使整体控制落在这两个集合内,然后开始解耦和颗粒化操作步骤。
Demo: 迪文串口屏应用-实现cursor移动+图标同步显示
typedef struct CLcdCtrlCursorIdx
{
/* data */
uint8_t chanel:2;/* max chanel number is 4*/
uint8_t cur_pos:6; /*posation ns moving from 0 - 9,next channel start this agin from 0.*/
}tCLcdCtlCursorIdx_t;
/*需要映射的时候,不要吝啬内存,他能减少很多逻辑复杂粒度,增强程控健壮性*/
static tCLcdCtlCursorIdx_t mCursorIdx = {0};
static const int8_t mCursorMap[] = {0x00, 0x0D, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
static const int8_t mCursorPicId[] = {0, 1, 1, 0, 2, 2, 2, 2, 1, 1};
uint16_t LcdGetCurItemAddr(void)
{
return mCursorIdx.chanel * 0x20 + 0x1000 + mCursorMap[mCursorIdx.cur_pos];
}
static inline uint16_t LcdGetCursorAddr(void)
{
return ADDR_CURSOR_START + mCursorIdx.cur_pos + mCursorIdx.chanel * (sizeof(mCursorMap));
}
static inline void LcdCursorForward(void)
{
mCursorIdx.cur_pos ++;
if (mCursorIdx.cur_pos == sizeof(mCursorMap))
{
mCursorIdx.cur_pos = 0;
mCursorIdx.chanel = !mCursorIdx.chanel; /*0 or 1*/
}
}
static inline void LcdCursorBackward(void)
{
if (mCursorIdx.cur_pos == 0)
{
mCursorIdx.cur_pos = sizeof(mCursorMap) - 1;
mCursorIdx.chanel = !mCursorIdx.chanel; /*0 or 1*/
}else{
mCursorIdx.cur_pos--;
}
}
/*程控逻辑总有共性的逻辑,try to find the common point*/
void LcdDisCursorMove(const uint8_t forward)
{
int16_t _addr_item, _addr_cursor = 0;
int16_t _addr_item_new, _addr_cursor_new = 0;
int16_t _gap = 0, _start_addr = 0;
uint8_t _pBuff[20] = {0};
_addr_item = LcdGetCurItemAddr();
_addr_cursor = LcdGetCursorAddr();
JBF_DEBUG_PRINTF_LOG("current item addr %04x, cursor addr is %04x, channel is %d, idx is %d \r\n",
_addr_item, _addr_cursor, mCursorIdx.chanel, mCursorIdx.cur_pos);
if (forward)
LcdCursorForward();
else
LcdCursorBackward();
_addr_item_new = LcdGetCurItemAddr();
_addr_cursor_new = LcdGetCursorAddr();
JBF_DEBUG_PRINTF_LOG("current item new %04x, cursor new is %04x, channel is %d, idx is %d \r\n",
_addr_item_new, _addr_cursor_new, mCursorIdx.chanel, mCursorIdx.cur_pos);
_gap = _addr_cursor_new > _addr_cursor ? (_addr_cursor_new - _addr_cursor) : (_addr_cursor - _addr_cursor_new);
_start_addr =_addr_cursor_new < _addr_cursor ? (_addr_cursor_new) : (_addr_cursor);
#if 1
/*相邻的两个地址,则只需要两个地址即可*/
if (_gap == 1)
{
JBF_DEBUG_PRINTF_LOG("_gap:%d _start:%04x \r\n", _gap, _start_addr);
_pBuff[1] = (VALUE_CURSOR_DISABLE * forward) + mCursorPicId[mCursorIdx.cur_pos] * (!forward);
_pBuff[3] = (VALUE_CURSOR_DISABLE * (!forward)) + mCursorPicId[mCursorIdx.cur_pos] * forward;
LcdUpdtByAddr(_start_addr, _pBuff, 4);
}
/*地址跨度较大,则需要改动多个地址*/
else{
JBF_DEBUG_PRINTF_LOG("_gap:%d _start:%04x \r\n", _gap, _start_addr);
_pBuff[1] = (VALUE_CURSOR_DISABLE * (!forward)) + mCursorPicId[mCursorIdx.cur_pos] * (forward);
_pBuff[3] = (VALUE_CURSOR_DISABLE * forward + mCursorPicId[mCursorIdx.cur_pos] * (!forward));
//LcdUpdtByAddr(_start_addr, _pBuff, 20);
LcdUpdtByAddr(_addr_cursor, _pBuff, 2);
JBF_MCU_DELAY_MS(20);
LcdUpdtByAddr(_addr_cursor_new, &_pBuff[2], 2);
}
#endif
#if 0
_addr = LcdGetCurItemAddr();
JBF_DEBUG_PRINTF_LOG("current cursor addr is %04x, channel is %d, idx is %d \r\n", _addr, mCursorIdx.chanel, mCursorIdx.cur_pos);
#endif
}