注册|登录 网站首页 论坛帮助
123...1112下一页

论坛客户端: iPhone|Android

[SX4]自动巡航DIY设计改装过程贴(工程暂停中。。。) 

[点击:/回复:] | 只看楼主 | 收藏本帖 | 刷新本帖

[SX4]自动巡航DIY设计改装过程贴(工程暂停中。。。)

 

注1:现在这个帖子中描述的自动巡航模块还没有实现完成,贴子目前为止只是记录设计思想和实施过程,希望懂行或感兴趣的TX们多提意见和建议,也希望我这一贴可以抛砖引玉,汽车论坛多讨论讨论技术应该是好事。

 

注2:本帖不具有任何商业意义,纯粹个人业余兴趣使然,帖子内容如有任何其他可利用价值,其成果可被随意转载,但由于汽车改装存在风险,作者不对此贴所涵盖的任何内容之可靠性做任何担保,引用者需自担风险。

 

这里感谢一下在这一贴中出谋划策的所有热心朋友!!

 

比较早以前(刚买SX4的时候),在网上无意搜索到SX4 Service Manual, 虽然是匈牙利语的,但这让我意识到,找到英文版的应不是难事,如果找到,那对实现我一个不大不小的愿望来说是非常有价值的

 

不久,在北美sx4论坛搜到了英文全版本的Service Manual, 如获至宝,打印了一份,足有1500, 两大厚本(双面打700多张纸), 放在车上, 没事就翻翻

 

在这个"学习"的过程中,暗自庆幸自己入手的是全球同步车型, 不管从外观内部结构零配件等等的描述到原理图, 都与找到的这本Service Manual非常一致, 不知道那些做了深入本地化的其他车型是不是也能够这么幸运了. 由于"理论""实际"的相似度之高,让我有理由相信, 实现那点愿望应该没什么大问题了!

 

其实我的这个愿望很简单, 就是让我的SX4有自动巡航的能力, 在驾驶我姐姐的一部新车时, 对这个功能产生了极大的好感和兴趣, 可惜后来迷上SX4, 国内版本又没有自动巡航, 当时很是郁闷, 但其实看到仪表盘上有Auto Cruise的指示灯, 这说明, SX4一定有带此功能的版本, 看到英文Service Manual后也证实了这一点, 在海外SX4 2.0排量的版本上, 确实有自动巡航的可选配置, 于是心升"邪念"…

 

要是能"破解"了他就好了! 最初的想法, 按照SM上的电路图, 从线束中找到那些没有连接的"线头", 接上几个开关就好了吧? 但实际往往都是事与愿违, 尤其是"好事"... 在经历了一番折腾后发现, ECM中根本就没有引出那几根和Auto Cruise相关的线, 连那些线在总线束插头的位置都被封上了, 想引出只能拆ECM! ECM是密封胶密封的, 拆开估计也可以, 但有损坏电路的风险, 还有之后的防潮, 且是否ECM固件上保留了这个功能都不得而知, 这个风险着实有点大



看着上面电路图, 好像都已经能摸到但又实现不了, 心里真是难受, 但也没什么办法… "破解"不成只能改造了. 决心自己实现一个自动巡航! 不过这一个决心就是两年多

 

在这期间,主要是做技术准备工作.

 

自动巡航控制模块的准备工作, 排除之前对SX4电路原理进行了解的时间以外, 就要算是技术实现上的准备工作了, 这里主要是要确定一个思路 ---- 要用什么方式来实现. 基本上有两个方案, 一个是模拟+简单数字逻辑电路, 另一个是单片机+辅助设备, 最后还是决定使用单片机, 其在扩展性能上的优势是毋庸置疑的. 主要是之前没搞过单片机, 但我心里还是有底的, 无非就是可编程的电路嘛, 编程我是在行的, 模拟/数字电路也应该可以同时搞定.

下面就是单片机选型, 现在最成熟的应该是51和AVR系列, 也是CISC vs RISC, 显然RISC性能要好很多, 但很无奈, 也许是我方法不对, 从网上买的实验板写入AVR程序不顺利. 经过简单测算估计, 51的性能也应该可以满足自动巡航的要求, 日后也具有一定的扩展能力, 程序上其实和AVR区别也不大, 那就先搞个51吧, 日后需要再升级AVR.

 

实验板到手以后, 很惭愧, 压了一年多才开始真正写程序, 其实也就是从上个月(2010/12)开始, 软件方面有了质的飞跃, 自动巡航程序和配套电路已经可以工作了. 从实际上验证了设计思路的可行性.

 

这次设计改造宗旨是:

(1)尽量不该动原车主要构造, 不拆核心配件, 不在整体结构上打洞;

(2)操作方便, 使用原车多功能方向盘(音响用的开关我基本不用);

(3)保证安全性和可靠性;

上面第(1)(2)条其实是相关的, 为了尽量不该动原车结构, 才使用平时不怎么用的多功能方向盘上的音响控制按键. 这样做可以不改动原车任何结构,不用单独安装控制开关, 应该说是最方便和安全的.

 

[2011/1/09]
昨天意外加班后, 去西四电子市场踩了一下点儿, 主要是看线束接口插头/座, 还有离合器开关是不是有合适的, 这个现在看, 是实现这个"系统"的难点, 因为不可能有和原车设计完全配套的配件, 只能是找代用品, 离合器开关还要考虑人工施工的可行性. 因为是意外加班, 没有开车去直接比对, 所以只是踩了个点儿, 对大致情况作了一个了解就回来了.

另外, 电路的设计上也遇到一点小困难, 单片机使用的是+5v单电源供电, ADC/DAC也是, 从SX4电原理图看, 加速踏板传感器参考电压也是+5v, 这样就带来一个问题, 由于DAC输出的限制, 最大不可能输出满5v, 如果直接输出, 有可能造成地板油不充分, 即油门"踩"不到底, 如果用运放放大缓冲输出, 由于是单电源, 又可能造成无法实现0输出, 所以考虑设计一个单独的双电源供电解决这个问题. 不知道有没有这方面有经验的TX能有更好的简单实现办法, 能给个意见

 

[2011/1/10]
刚刚发布了第一版电路图和单片机程序,电路图中的一些元件参数还没有仔细标定,程序中对速度进行司服控制的部分还很粗糙,希望能有朋友可以提出意见或自己的想法

现在有几个想法,这个东西做出来以后,可以加入下面几个功能:


(1)定速巡航
(2)通过方向盘上的按钮手动控制车速(类似打游戏)
(3)高精度计时器(精确到0.1秒)
(4)高精度里程表(相对于原车),计划精确到米或十米
(5)平均时速(这个SX4天生缺失)
(6)0-100加速计时
(7)400米加速用时


[2011/1/12]
今天修改了电路, 去掉了运放, 这主要是因为负电压生成的问题, 本想用运放作为输入和输出的缓冲级, 但由于简单实现一个负电源比较麻烦, 所以去掉了运放部分.

昨天看到softegg的回复, 似乎又让直接破解多了一点希望, 等周末有时间好好看一下车子ECM总线束的插头, 希望可以把E01的68那几根神秘引脚引出来, 阿门...

 

[2011/1/24]

前两天又去“侦察”了一下与改造相关的几个插头,不太顺利,油门的插头位置原因,极难拆下,大冬天里的手又不方便,郁闷。其他几个插头都是“特型”插头,很难陪到一样的,看来如果要加装,只能把线断开增加插头/插座了。另外,marco8874去研究了一下ECM的插头,看看有没有“破解”原车巡航的希望。天气原因,咱又没车库,估计要想真正实施改装,得天气暖和一点了。。这期间,要尽量完善电路。。

 

(待续。。。)

[ 本帖最后由 direct3d 于 2012-01-20 16:31 编辑 ]
【没谱儿青年村】村长
章: 汽车之家三周年庆典徽章

这一楼为了完整再现准备过程,使用OneNote截图


 













[ 本帖最后由 direct3d 于 2011-01-08 14:27 编辑 ]
【没谱儿青年村】村长
章: 汽车之家三周年庆典徽章

这楼先留着


[ 本帖最后由 direct3d 于 2011-01-13 20:09 编辑 ]
【没谱儿青年村】村长
章: 汽车之家三周年庆典徽章

 



这一层是电路图设计, 现在是电路还没有最终定稿, 一定还有一些问题, 很多元件参数还没有仔细标定, 希望懂行的朋友能给点意见, 谢谢:



(图1)当成品完成时, 在车上将按照该图施工




(图2)下面是自动巡航控制主机的电路图, 已经取消了模拟输入输出端的运放缓冲, 不知道行不行...


现在速度检测还少一个1/N分频,准备加上。。





[ 本帖最后由 direct3d 于 2011-01-21 15:25 编辑 ]
【没谱儿青年村】村长
章: 汽车之家三周年庆典徽章

单片机程序之宏/常量/函数定义和声明



(由于论坛版式的限制, 程序发上来格式就乱了, 很无奈)



 



#include "at89x52.h"
#include < intrins.h >
 
/**
1602 display:




Line/Col 0 1 2 3 4 5 6 7 8 9 A B C D E F
 1'A' A0A1 A2 'K' 'm' '/' 'h' ' ' 'A' 'D' 'C' C0 C1 C2 ' '
 2'P' B0 B1 B2 'K' 'm' '/' 'h' ' ' 'D' 'A' 'C' D0 D1 D2 ' '
 
A: Actual speed
B: Planed speed
C: acceleration pedal value
D: output acceleration value to ECM




Keys:
静音 --->Clear
V+ --->Select Up
V- --->Select Down
P+ --->Increase
P- --->Decrease
Mode --->Set
 
*/




#define P_DISPLAYP0




sbit SIN_SPEED= P1^0;
sbit SIN_KEYS= P1^1;
sbit SIN_ADC= P3^4; //P1^2
sbit SIN_CLUTCH= P1^2;
sbit SIN_BREAK= P1^3;
sbit DI_ADC = P3^4;
sbit DO_DAC = P3^3;
sbit NCS1 = P3^6;
sbit S_CLK = P3^7;




sbit LCD_RS = P3^0 ;
sbit LCD_RW = P3^1 ;
sbit LCD_EN = P3^2 ;




#define LCDISBUSYPRE LCD_RS = 0; LCD_EN = LCD_RW = 1




#define LCDISBUSY (P0&0x80)




#define LCDWRITECMDPRE LCD_RS = LCD_RW = LCD_EN = 0




#define LCDWRITEDTAPRE LCD_RS = 1; LCD_RW = LCD_EN = 0



typedef struct _tagKEYINPUT
{
 unsigned char cKey : 7;
 unsigned char bLangPress : 1;
} KEYINPUT;


#define KEYINPUTSTRUCT(c) ((KEYINPUT *)(&c)) 



typedef union _tagBCD4
{
 long l;
 struct
 {
char reserved;
struct
{
 char d3:4;
 char d2:4;
 char d1:4;
 char d0:4;
} bcd;
char n;
 } s;
} BCD4;




unsigned char g_speedReadLoops; // 车速计数器计数周期(暂以循环次数计)
unsigned int g_speedCount; // 车速计数器
bit g_speedState; // 车速传感器状态
bit g_adcChannel; // 车速传感器状态
unsigned char g_speedData; // 车速计数结果
unsigned char g_keysData; // 按键确认状态
unsigned char g_adcData; // ADC确认数据
//unsigned char g_keysBuf; // 按键串行读取缓冲 use same chip with g_adcBuf
unsigned char g_adcBuf;// ADC串行读取缓冲
unsigned char g_readStep; // 数据读取步骤




#define IS_CRUISE'C'
#define IS_BRAKE'B'
#define IS_DISABLED'D'
#define IS_BYPASS'P'
#define DAC_MAX_VALUE 200
#define SPEED_MAX150
#define SPEED_MIN5
unsigned char g_inputState; // 当前输入状态 IS_CRUISE/IS_DISABLED/IS_BYPASS
unsigned char g_cruiseSpeed; // 当前巡航速度
unsigned char g_dacData; // DAC数据
unsigned char g_dacBuf; // DAC数据输出缓冲
unsigned char g_dSpeedPeriod; // 加速度测量周期
unsigned char g_dSpeedLastSample; // 最后一个速度采样点,用于计算加速度
char g_dSpeed; // 加速度
unsigned char g_displayStep = 0; // 显示输出步骤
unsigned char g_displayIdx = 0; // 显示缓存当前索引




unsigned char g_tickCount = 0;
unsigned long g_milesCount = 0;
unsigned char g_timerD = 0;
unsigned char g_timerS = 0;
unsigned char g_timerM = 0;
unsigned char g_timerH = 0;
unsigned char g_avgSpeed = 0;




#define KEY_NOTHING0
#define KEY_CLEAR1
#define KEY_UP 2
#define KEY_DOWN3
#define KEY_SET 4
#define KEY_INC 5
#define KEY_DEC 6




unsigned char g_lastKey = KEY_NOTHING;
unsigned char g_lastKeyDelays = 0;
unsigned char g_loopDelays = 0;




char g_displayPageIndex = 0;




#define STR_SPEED 0
#define STR_CRUISE 1
#define STR_MILES 2
#define STR_TIMER 3
#define STR_AVG4
#define STR_APPI 5
#define STR_APPO 6
#define STR_0_100 7
#define STR_400M 8//======>> 由此往上同时为显示页索引
#define STR_AUTO 9
#define STR_MANUAL 10
#define STR_BREAK 11
#define STR_CLUTCH 12
#define STR_KMPS 13
#define STR_KM14
#define POS_PGIDX 0x0A




#define STATE_MIN STR_SPEED
#define STATE_MAX STR_400M




/*Line/Col 0 1 2 3 4 5 6 7 8 9 A B C D E F
 1'A' A0A1 A2 'K' 'm' '/' 'h' ' ' 'I' ':' ' ' C0 C1 C2 '0'
 2'P' B0 B1 B2 'K' 'm' '/' 'h' ' ' 'O' ':' ' ' D0 D1 D2 ' '
*/
char g_displayRam[32];
char* code g_vStrList[] = {" Speed", "Cruise", " Miles", " Timer", "Avg.", " APP-I", " APP-O", " 0-100", "400m"
 , "Auto", "Manual", "Brake", "Clutch", "Km/s", "Km"
};




void initEnv();
void inputAndOutput();
void handlePedalsInput();
void handleKeyInput();
void handleAdcInput();
void handleSpeedInput();
void handleDacOutput();
void handleDisplayOutput();
void c2str(unsigned char c, unsigned char* p);
void chrcpy(char* dest, char* src);
void displayTimer();




void resolveDacValue();




void lcd_wcmd(char cmd);
void lcd_init();




void delay1(int ms);




 


[ 本帖最后由 direct3d 于 2011-01-10 00:29 编辑 ]
【没谱儿青年村】村长
章: 汽车之家三周年庆典徽章

单片机程序之实现部分(一)


 


void main(void)
{
 // init envirment
 initEnv();


 // app clock loop
 while(1)
 {
  S_CLK = 0;
  //read serial 8bit data from P1(include clutch and break signal)
  inputAndOutput();


  // INPUT processes
  // handle clutch and break signal
  handlePedalsInput();


  // handle key data
  handleKeyInput();


  // handle ADC data
  handleAdcInput();


  // handle speed data
  handleSpeedInput();


  // OUTPUT processes
  // handle DAC data
  handleDacOutput();


  if (12 < ++g_readStep)
   g_readStep = 0;


  S_CLK = 1;


  // handle display data
  handleDisplayOutput();
 }
}


void initEnv()
{
 char n = 32;
 NCS1 = 1;
 DO_DAC = 0x0;
 g_speedReadLoops = 0;
 g_speedCount = 0;
 g_speedState = 0;
 g_speedData = 0;
 g_dSpeedPeriod = 0;
 g_dSpeedLastSample = 0;
 g_keysData = 0;
 g_adcData = 0;
// g_keysBuf = 0;
 g_adcBuf = 0;
 g_readStep = 0;
 g_dacData = 0;
 g_dacBuf = 0;
 g_inputState = IS_DISABLED;


 g_tickCount = 0;
 g_milesCount = 0;
 g_adcChannel = 0;
 g_displayPageIndex = 0;


 g_lastKey = KEY_NOTHING;
 g_lastKeyDelays = 0;
 g_loopDelays = 0;
 g_timerD = 0;
 g_timerS = 0;
 g_timerM = 0;
 g_timerH = 0;
 g_avgSpeed = 0;


 while (n) g_displayRam[--n] = ' ';


 chrcpy(g_displayRam + POS_PGIDX, g_vStrList[g_displayPageIndex]);


 //P0 = 0x01;
    lcd_init() ;                //初始化LCD


 // 初始化中断
 TMOD = 0x01;
 RCAP2H = 0x3C;
 RCAP2L = 0xAF;
 TR2 = 1;
 ET2 = 1;
 EA = 1;
}


void sysTimer() interrupt 5
{
 P3_3 = 0;
 TF2 = 0;
 if (++g_speedReadLoops == 4)
 {
  resolveDacValue();


  ++g_tickCount;


  if (g_tickCount & 0x08)
  {
   if (' ' == g_displayRam[0x00])
   {
    char* pState = g_vStrList[STR_MANUAL];
    switch(g_inputState)
    {
     case IS_CRUISE: pState = g_vStrList[STR_AUTO]; break;
     case IS_BRAKE: pState = g_vStrList[STR_BREAK]; break;
     case IS_BYPASS: pState = g_vStrList[STR_CLUTCH]; break;
    }


    chrcpy(g_displayRam + 0x00, pState);
   }
  }
  else
  {
   if (' ' != g_displayRam[0x00])
   {
    chrcpy(g_displayRam + 0x00, "      ");
   }
  }


  if (10 == ++g_timerD)
  {
   g_timerD = 0;
   if (60 == ++g_timerS)
   {
    g_timerS = 0;
    if (60 == ++g_timerM)
    {
     g_timerM = 0;
     ++g_timerH;
    }


    g_avgSpeed = g_milesCount * (0.00002777778f * 60) / (g_timerH * 60 + g_timerM);
   }
  }


  if (STR_TIMER == g_displayPageIndex)
  {
   displayTimer();
  }
  else if (STR_AVG == g_displayPageIndex)
  {
   c2str(g_avgSpeed, g_displayRam + 0x1d);
  }
 }
 P3_3 = 0;
}


void displayTimer()
{
 g_displayRam[0x1F] = g_timerD + '0';
 g_displayRam[0x1E] = 's';
 c2str(g_timerS, g_displayRam + 0x1B);
 g_displayRam[0x1B] = 'm';
 c2str(g_timerM, g_displayRam + 0x18);
 g_displayRam[0x18] = 'h';
 c2str(g_timerH, g_displayRam + 0x15);
}


[ 本帖最后由 direct3d 于 2011-01-10 00:12 编辑 ]
【没谱儿青年村】村长
章: 汽车之家三周年庆典徽章

单片机程序实现之(三)



 



void inputAndOutput()
{
 // speed counter
 if (g_speedState ^ SIN_SPEED)
 {
  g_speedState = SIN_SPEED;
  ++g_speedCount;
 }
 
 // ADC/DAC serial port in/out
 switch(g_readStep)
 {
  case 0: // START BIT
   g_adcBuf = 0;
   g_dacBuf = g_dacData;
   DI_ADC = 1;
   NCS1 = 0;
   break;
  case 1: // SGL/_DIF
   DI_ADC = 1;
   break;
  case 2: // ODD/SIGN
   DI_ADC = (g_adcChannel ^= 1); // channel
   break;
  case 3: // MUX SETTING
   DI_ADC = 1;
   break;
  default: //4, 5, 6, 7, 8, 9, 10, 11
   g_adcBuf <<= 1;
   g_adcBuf |= SIN_ADC;
   break;
  case 12:
   NCS1 = 1;
   if (g_adcChannel)
   {
    g_adcData = g_adcBuf;
    //c2str(g_adcData, g_displayRam + 0x11);
   }
   else
   {
    g_keysData = g_adcBuf;
    //c2str(g_keysData, g_displayRam + 0x11);
   }
   break;
 }



 DO_DAC = (bit)(0x80 & g_dacBuf);
 g_dacBuf <<= 1; 
}



void handlePedalsInput()
{
 if (!SIN_BREAK)
 {
  g_inputState = IS_BRAKE;
  g_dacData = g_adcData; // pass directly at once
 }
 else if (IS_BRAKE == g_inputState)
 {
  g_inputState = IS_DISABLED;
 }



 if (!SIN_CLUTCH)
 {
  if (IS_CRUISE == g_inputState)
  {
   g_inputState = IS_BYPASS;
   g_dacData = g_adcData; // pass directly at once
  }
 }
 else if (IS_BYPASS == g_inputState)
 {
  g_inputState = IS_CRUISE;
 }
}



unsigned char getKeyInput()
{
 unsigned char k = KEY_NOTHING;
 if (149 > g_keysData)
  k = KEY_CLEAR;
 else if (181 > g_keysData)
  k = KEY_UP;
 else if (198 > g_keysData)
  k = KEY_DOWN;
 else if (209 > g_keysData)
  k = KEY_SET;
 else if (216 > g_keysData)
  k = KEY_INC;
 else if (222 > g_keysData)
  k = KEY_DEC;



 if (KEY_NOTHING != k && k == g_lastKey)
 {
  if (0 == g_loopDelays)
  {
   if (0x80 == ++g_lastKeyDelays)
   {
    g_lastKeyDelays = 0;
    ++g_loopDelays;
    return 0x80 | k;
   }
  }
  else if (!(++g_lastKeyDelays))
  {
   if (0x30 == ++g_loopDelays)
   {
    g_loopDelays = 0x20;
    return k;
   }
  }
 }
 else
 {
  g_lastKey = k;
  g_lastKeyDelays = 0;
  g_loopDelays = 0;
 }



 return KEY_NOTHING;
}


[ 本帖最后由 direct3d 于 2011-01-10 00:20 编辑 ]
【没谱儿青年村】村长
章: 汽车之家三周年庆典徽章

单片机程序实现之(四)


void handleKeyInput()
{
// c2str(g_adcData, g_displayRam + 0x0c);
// c2hex(g_keysData, g_displayRam + 0x19);
 unsigned char key = getKeyInput();
 switch(KEYINPUTSTRUCT(key)->cKey)
 {
  case KEY_CLEAR:
   if (IS_BRAKE != g_inputState)
    g_inputState = IS_DISABLED;
   break;
  case KEY_UP:
   if (STATE_MAX < ++g_displayPageIndex)
    g_displayPageIndex = STATE_MIN;


   clearDisplayBuff();
  chrcpy(g_displayRam + POS_PGIDX, g_vStrList[g_displayPageIndex]);
   break;
  case KEY_DOWN:
   if (STATE_MIN > --g_displayPageIndex)
    g_displayPageIndex = STATE_MAX;


   clearDisplayBuff();
  chrcpy(g_displayRam + POS_PGIDX, g_vStrList[g_displayPageIndex]);
   break;
  case KEY_INC:
   if (SPEED_MAX > g_cruiseSpeed)
    ++g_cruiseSpeed;
   break;
  case KEY_DEC:
   if (SPEED_MIN < g_cruiseSpeed)
    --g_cruiseSpeed;
   break;
  case KEY_SET: // 在不同显示状态下,SET键含义不同
   switch(g_displayPageIndex)
   {
    case STR_CRUISE:
    case STR_SPEED:
     // 只有当速度在允许的范围内才可以定速
     if (SPEED_MIN <= g_speedData && SPEED_MAX >= g_speedData)
     {
      if (IS_DISABLED == g_inputState)
       g_inputState = IS_CRUISE;
  
      if (IS_CRUISE == g_inputState)
       g_cruiseSpeed = g_speedData;
     }
     break;
    case STR_MILES: // set is reset
     g_milesCount = 0;
     break;
    case STR_TIMER: // restart
    case STR_AVG: // restart
     g_timerD = 0;
     g_timerS = 0;
     g_timerM = 0;
     g_timerH = 0;
     g_avgSpeed = 0;
     break;
   }
   break;
  default:
   break;
 }
}


void resolveDacValue()
{
 g_speedData = g_speedCount;
 g_speedCount = 0;
 g_speedReadLoops = 0;
 g_milesCount += g_speedData;


 if (5 == ++g_dSpeedPeriod)
 {
  g_dSpeed = g_speedData - g_dSpeedLastSample;
  g_dSpeedPeriod = 0;
 
  if (IS_CRUISE == g_inputState)
  {
   int d = g_cruiseSpeed - g_speedData;
   if (2 < d) // too slow
   {
    g_dacData = DAC_MAX_VALUE;
   }
   else if (0 < d) // slower
   {
    if (g_dSpeed <= 0)
     if (DAC_MAX_VALUE < (g_dacData += 10))
      g_dacData = DAC_MAX_VALUE;
   } 
   else if (-2 > d) // too fast
   {
    g_dacData = 0;
   }
   else if (0 > d) // faster
   {
    if (g_dSpeed >= 0)
     g_dacData = (g_dacData > 10 ? g_dacData -= 10 : 0);
   }
   else // cruise speed
   {
    if (g_dSpeed > 0)
     g_dacData >>= 1;
    else if (g_dSpeed < 0)
     g_dacData += 20;
   }
  }
 }


 if (IS_CRUISE != g_inputState)
  g_dacData = g_adcData; // pass directly


 if (STR_CRUISE == g_displayPageIndex)
  c2str(g_cruiseSpeed, g_displayRam + 0x1d);


 if (STR_APPO == g_displayPageIndex)
  c2str(g_dacData, g_displayRam + 0x1d);


 g_displayRam[0x10] = g_inputState;


 c2str(g_dacData, g_displayRam + 0x11);
}


[ 本帖最后由 direct3d 于 2011-01-10 00:25 编辑 ]
【没谱儿青年村】村长
章: 汽车之家三周年庆典徽章

单片机程序实现之(五)


 


void handleDisplayOutput()
{
 switch(g_displayStep)
 {
  case 0: // set pos busy query prepare
  {
      LCDISBUSYPRE;
   ++g_displayStep;
  }
  case 1: // is busy?
  {
   if (LCDISBUSY)
   {
    --g_displayStep;
    break;
   }


   LCD_EN = 0;
   ++g_displayStep;
  }
  case 2: // set pos prepare
  {
   LCDWRITECMDPRE;
   ++g_displayStep;
   break;
  }
  case 3: // set pos cmd
  {
   if (0x10 & g_displayIdx)
    P0 = 0xC0 | (0x0f & g_displayIdx); // 1,0;
   else
    P0 = 0x80 | (0x0f & g_displayIdx); // 0,0;


   ++g_displayStep;
   break;
  }
  case 4:
  {
   LCD_EN = 1;
   ++g_displayStep;
   break;
  }
  case 5: // enable pos data
  {
   LCD_EN = 0;
   ++g_displayStep;
   break;
  }
  case 6: // write data busy query prepare
  {
      LCDISBUSYPRE;
   ++g_displayStep;
  }
  case 7: // is busy?
  {
   if (LCDISBUSY)
   {
    --g_displayStep;
    break;
   }


   LCD_EN = 0;
   ++g_displayStep;
  }
  case 8: // write data prepare
  {
   LCDWRITEDTAPRE;
   P0 = g_displayRam[0x1f & g_displayIdx++];
   ++g_displayStep;
   break;
  }
  case 9: // enable data
  {
   LCD_EN = 1;
   ++g_displayStep;
   break;
  }
  case 10: // end
  {
   LCD_EN = 0;
   g_displayStep = 0;
   break;
  }
 }
}


void c2str(unsigned char c, unsigned char* p)
{
 char n = c / 100;
 p[0] = n ? n + '0' : ' ';
 n = (c -= n * 100) / 10;
 p[1] = (!n && ' ' == p[0] ? ' ' : n + '0');
 c -= n * 10;
 p[2] = c + '0';
}
void handleAdcInput()
{
 //g_adcData = 100;
 if (STR_APPI == g_displayPageIndex)
  c2str(g_adcData, g_displayRam + 0x1d);
}


void handleSpeedInput()
{
 if (STR_SPEED == g_displayPageIndex)
  c2str(g_speedData, g_displayRam + 0x1d);


 // disable auto cruise when speed too low
 if (IS_BRAKE != g_inputState && SPEED_MIN > g_speedData)
  g_inputState = IS_DISABLED;
}
void chrcpy(char* dest, char* src)
{
 while(*src) *(dest++) = *(src++);
}
void clearDisplayBuff()
{
 int i = 32;
 while(i)
 {
  g_displayRam[--i] = ' ';
 }
}


[ 本帖最后由 direct3d 于 2011-01-10 00:28 编辑 ]
【没谱儿青年村】村长
章: 汽车之家三周年庆典徽章
占楼,别加塞9
【没谱儿青年村】村长
章: 汽车之家三周年庆典徽章
占楼成功
[ 本帖最后由 direct3d 于 2011-01-08 22:42 编辑 ]
【没谱儿青年村】村长
章: 汽车之家三周年庆典徽章
我温柔的插一下!!只为留名~~~,老崇拜LZ了.连程序都分享了,太感动了
[ 本帖最后由 bulusi77 于 2011-01-10 09:08 编辑 ]

既然前面有人插了,我忍了半天也插了

 

时间已过20分钟了嘛

 

版主出品,必然精品

爱天语,爱生活

插一下


 


为楼主无私奉献源码的精神鼓掌


[ 本帖最后由 egkk 于 2011-01-10 12:56 编辑 ]

 期待啊,先顶下

喜欢以车交友
看不太明白, 还是顶版主一下。

定速巡航已经在部分小S车友的车上实现了..

我QQ群里有车友正在使用..手动档改装的..

有一张聊天图片..再具体的我是新手也说不清楚..但如果有需要我可以代问车主..



楼上这种外挂型的 价格跟楼主比一个天上一个地下

123...1112下一页

返回顶部