原创 AVR mega48 电动车电子里程仪

2009-11-16 08:26 3903 3 11 分类: 汽车电子
      AVR mega48电动车电子里程仪

点击开大图


规格功能说明:
该电子里程仪有两种计量方式,所以,设计时需要预留两种测量接口,客户可以根据自己的需要使用任何一种测量方式。

两种测量方式都需要完成如下功能:
1、累计里程精度为0.1公里,所行驶里程通过5段“8”字数码管显示,包括一位小数。所累计里程需要保存,掉电不允许丢失(初步计划使用E2来存储);每次计量到达9999.9公里时,显示屏清零,重新从零累计显示,但E2中需要保存电动车所有行驶里程,包括超过9999.9的里程;存储累积里程精度为10米。

2、该电路需要预留出通讯接口,外部手持设备可随时读取里程仪E2中的累计里程。(此项功能可以在产品完成后再行设计,但需要预留通讯接口。)


两种计量方式描述如下:

1、脉冲计量
里程仪电路检测脉冲接口处电平变化(高还是低有效???),每接受到28830个脉冲,即认为是电动车行驶了1公里。
2、电压计量
经过测量得到速度V和电压U的关系为:V(千米/小时)=U * 0.8,
通过   距离=速度*时间   公式来完成电动车行程的累计。

 



请问你要设计的里程表是用于无刷电机吗??只有无刷电机才有脉冲输出的。但是,不同轮径的电机,它的脉冲频率是不同的,还有就,不同品牌的电机,它的每周信号也是不一样的。因为这些差数是不统一的。所以你的里程表就不一定准确了吧。



我的回复:
软件可以根据轮子的半径加以修改,参数很好设定,目前已经应用在电动车中,是很准确的

 



 





你说的很对,我这是这样认为的。你用什么芯片做的?用的是什么样的E2PROM?可否说一下?()




mega48做的,考虑成本,内置的EEPROM

由于该设计已经应用在某公司,需要软硬件设计资料的,请留下邮箱,写明用途,我会把完整资料发给你

参考代码如下:

/*******************************************************************************************/
/* instrument         :motor instrument 2008.3.10             */
/* Designer           :Li Xiang Feng            */
/* Chip               :MEG48+two 74hc595+five Digital control(show distance)      */
/*                    +nine led(show speed)+ five led (show voltage)+Transistor      */
/* Crystal            :meg48  8.0000Mhz                     */
/* Digital control    :pc0-pc4 is control ports,QH~QA of 74hc595(u1) is date ports     */
/* nine led           :pd0 QH~QA of 74hc595(u1) and pd0  is  9 bits date port      */
/* five led           :pd3~pd7 control bits
/* 74hc595(u1)control :Serial Port is mosi ,Clock port is sck,latch port control is pb2    */
/* 74hc595(u1)control :Serial Port is mosi ,Clock port is sck,latch port control is pd0    */
/* speed impluse input:Transistor,Anti-admission, PSA,then input int0(pd2);        */
/* voltage sampleinput :adc5(pd5)                       */

/* instrumentboard    :48 input board "DP";which is  sourse Indicator;speed impluse     */ 

/*                    input"SP";right Indicator input is "DR";right Indicator input is     */   

/*                    "DR"; BIG light Indicator  input is"DD";("XXO" is their output port) */
/*******************************************************************************************/
#include <iom48v.h>
#include <macros.h>
#include <eeprom.h>
#define address 0x6f      
#define uchar unsigned char
unsigned long speed,speed1;//Variables counts speed and shows speed
unsigned long count;       //Variables counts distance
unsigned long distance;    //Variables shows distance
unsigned char voltage;    //Variables shows voltage
unsigned char eep_flag;   //flag of write diatance to eeprom
unsigned char num[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //0-9
unsigned char num_p[] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; //0.-9.
unsigned char show_flagc=0; 
unsigned char show_flagd=0;    
void Delay(unsigned int num)//delay times
{    
 while( num-- ) WDR();
   
}       
void spi_send(uchar dd)
    {
      SPDR="dd";
      while(0==(SPSR&0X80));
   SPSR&=0X7f;
   WDR ();
    }

void eeprom_write(unsigned long i )//eeprom write
{
 EEPROM_WRITE(address,i);
  WDR();
  SEI();
}
unsigned long eeprom_read()
{
unsigned long i;

EEPROM_READ(address,i);          //eepromread
WDR();
return i;
 }

//external interupt on INT0
#pragma interrupt_handler int0_isr:iv_INT0
void int0_isr(void)
{
speed++;
if(count<=2089)//0.1KM Refreshs 改变2989数值可以改变里程数
  {count++; eep_flag=0;
 }
 else
 {
 count=0;eep_flag=1;
 distance++; //Digital control show add
 }
}

//TIMER1 initialize - prescale:256
// WGM: 0) Normal, TOP="0xFFFF"
// desired value: 1Hz
// actual value:  1.000Hz (0.0%)
void timer1_init(void)
{
 TCCR1B = 0x00; //stop
 TCNT1H = 0x85; //setup
 TCNT1L = 0xEE;
 OCR1AH = 0x7A;
 OCR1AL = 0x12;
 OCR1BH = 0x7A;
 OCR1BL = 0x12;
 ICR1H  = 0x7A;
 ICR1L  = 0x12;
 TCCR1A = 0x00;
 TCCR1B = 0x04; //start Timer
}
#pragma interrupt_handler timer1_ovf_isr:iv_TIM1_OVF
void timer1_ovf_isr(void)
{
           //TIMER1 has overflowed
 TCNT1H = 0x85; //reload counter high value
 TCNT1L = 0xEE; //reload counter low value
 speed1=speed;
 speed=0;
 }
 
//port initialize
void port_init(void)
{
 DDRB=0xff;
 PORTB=0X00;
 DDRC=0x5f;
 PORTC=0Xff;
 PORTD = 0xff;
 DDRD  = 0xFB;
}

//Watchdog initialize
// prescale: 2K
void watchdog_init(void)
{
 WDR (); //this prevents a timeout on enabling
 WDTCSR |= (1<<WDCE) | (1<<WDE); // 30-Oct-2006 Umesh 
 WDTCSR = 0x08; //WATCHDOG ENABLED - dont forget to issue WDRs
}

//spi initialize
void spi_init(void)
{
 SPCR = 0x53; //setup SPI
 SPSR = 0x00; //setup SPI
}

//ADC initialize
// Conversion time: 416uS
void adc_init(void)
{
 ADCSRA = 0x00; //disable adc
 ADMUX = 0xE5;  //select adc input 0
 ACSR  = 0x80;
 ADCSRB = 0x00;
}

void init_devices(void)
{
 CLI();
 port_init();
 spi_init();
 watchdog_init();
 adc_init();
 timer1_init();
 MCUCR = 0x00;
 EICRA = 0x03; //extended ext ints
 EIMSK = 0x01;
 
 TIMSK0 = 0x00; //timer 0 interrupt sources
 TIMSK1 = 0x01; //timer 1 interrupt sources
 TIMSK2 = 0x00; //timer 2 interrupt sources
 
 PCMSK0 = 0x00; //pin change mask 0
 PCMSK1 = 0x00; //pin change mask 1
 PCMSK2 = 0x00; //pin change mask 2
 PCICR = 0x00; //pin change enable
 PRR = 0x00; //power controller
 SEI(); //re-enable interrupts
 }

 //five Digital control refeshes
void dig_refresh(void)
{
  unsigned char a,b,c,d,e;
  unsigned long i,j,k,l,m;
  i="distance"%10;
  j="distance"%100;
  k="distance"%1000;
  l="distance"%10000;
  m="distance"%100000;//date change
  a="i";
  b=(j-a)/10;
  c=(k-j)/100;
  d=(l-k)/1000;
  e=(m-l)/10000;
   if((e==0)&&(d==0)&&(c==0))
 show_flagc=1;
 else show_flagc=0;
if((e==0)&&(d==0))
show_flagd=1;
else show_flagd=0;
 //show digtal control
    spi_send(num[a]);//refreshes 1 bit
    PORTB&=0Xfb;
 PORTB|=0X04;
 PORTC|=0X01;
 PORTC&=0X01;
 if(show_flagc==1)
 Delay(4400);
 else if (show_flagd==1)
 Delay(3500);
 else if(e==0)
 Delay(2800);
 else
 Delay(2285);
 PORTC=0X00;

 //condition write eeprom
 if(eep_flag=1)
  {
    eeprom_write(distance);
  }
 
 spi_send(num_p);//refreshes 2 bit
    PORTB&=0Xfb;
 PORTB|=0X04;
 PORTC|=0X02;
 PORTC&=0X02;
 if(show_flagc==1)
 Delay(4400);
 else if (show_flagd==1)
 Delay(3500);
 else if(e==0)
 Delay(2800);
 else
 Delay(2285);//调节数码管亮度,改小则变暗
 PORTC=0X00;
 
 if(show_flagc==0)
 {
 spi_send(num[c]);//refreshes 3 bit
    PORTB&=0Xfb;
 PORTB|=0X04;
 PORTC|=0X04;
 PORTC&=0X04;
 if(show_flagc==1)
 Delay(4400);
 else if (show_flagd==1)
 Delay(3500);
 else if(e==0)
 Delay(2800);
 else
 Delay(2285);
 PORTC=0X00;
 }
 
 if(show_flagd==0)
 {
 spi_send(num[d]);//refreshes 4 bit
    PORTB&=0Xfb;
 PORTB|=0X04;
 PORTC|=0X08;
 PORTC&=0X08;
 if(show_flagc==1)
 Delay(4400);
 else if (show_flagd==1)
 Delay(3500);
 else if(e==0)
 Delay(2800);
 else
 Delay(2285);
 PORTC=0X00;
 }
 if(e!=0)
 {
 spi_send(num[e]);////refreshes 5 bit
    PORTB&=0Xfb;
 PORTB|=0X04;
 PORTC|=0X10;
 PORTC&=0X10;
 if(show_flagc==1)
 Delay(4400);
 else if (show_flagd==1)
 Delay(3500);
 else if(e==0)
 Delay(2800);
 else
 Delay(2285);
 PORTC=0X00;
 }
}
//  speed shows
void speed_show(void)//速度区间段,改变区间值可以调节速度,改小显示速度快
{
    if(speed1>173)          {PORTD|=0X02;spi_send(0Xff);}  //all light
    else if(speed1>=153)    {PORTD&=0X02;spi_send(0X7F);} 
    else if(speed1>=128)    {PORTD&=0X02;spi_send(0X3F);}
    else if(speed1>=106)    {PORTD&=0X02;spi_send(0X1F);}
    else if(speed1>=81)     {PORTD&=0X02;spi_send(0X0F);}
    else if(speed1>=58)     {PORTD&=0X02;spi_send(0X07);}
    else if(speed1>=36)     {PORTD&=0X02;spi_send(0X03);}
    else if(speed1>=13)     {PORTD&=0X02;spi_send(0X01);}
    else                    {PORTD&=0X02;spi_send(0X00);} //the last light
    PORTD&=0XfE;PORTD|=0X01;
}

//voltage show
void voltage_show()
{
  ADCSRA = 0xC7;
 while((ADCSRA&0x40)==0x40); //改变大于等于数值,改变电压值,一般改变一个数值
  voltage="ADCH";
  if(voltage>=0xDE)              {PORTD|=0XF0;PORTD&=0XF7;}  //48v upper充电满
  else if(voltage>=0xD8)         {PORTD|=0X70;PORTD&=0X77;} 
  else if(voltage>=0xD1)         {PORTD|=0X30;PORTD&=0X37;}
  else if(voltage>=0xC7)         {PORTD|=0X10;PORTD&=0X17;}
  else                           {PORTD&=0X0F;PORTD|=0X08;} //Undervoltage欠压改变
 
 
 
  ADCSRA = 0x00;
}
 
void main(void)
{
 unsigned char i;
 for(i=2;i>0;i--)
 {
 WDTCSR = 0x00;
 Delay(65535);//delay wait voltege stable上电延迟时间,改大,延迟时间加长
 WDTCSR = 0x08;
 }
 init_devices();

 CLI();
 distance=eeprom_read();//read  distance
 SEI();
 while(1)
 {
 WDR ();
 dig_refresh();
 speed_show();
 voltage_show(); 
 WDR ();
 }
}

 

文章评论8条评论)

登录后参与讨论

用户435992 2012-10-14 15:00

623599392@qq.com 能给资料么 刚毕业在厂里做销售的,对电子单片机比较有兴趣,希望您能提供完整资料参考学习, 谢谢。

用户377235 2012-10-14 14:50

623599392@qq.com 能给资料么 学生用于毕业设计 谢谢

用户422219 2012-4-27 11:34

501824021@qq.com 能给资料么 学生用于毕业设计 谢谢

用户1462906 2010-11-29 10:28

我想学习下,邮箱:zjsxhwl@126.com

用户286248 2010-6-11 09:22

你好。我刚开始学习AVR,现在也是用的MEG48单片机。 想用MEG48测量电阻(双积分方法实现)然后用6个74LS595驱动6个数码管。前四个显示阻值,后两个显示倍率(正常阻值除以改变环境后的阻值) 硬件电路图我已经设计完了,但是编程还很有困难。想请您帮忙分析一下。我的邮箱mfdxh@126.com

用户236759 2009-11-14 10:26

你好,我是电子学院的学生,准备做毕业设计了,能给我一份资料参考一下吗?非常感谢!d2767@tom.com

用户109153 2009-4-20 21:59

我在做毕业设计,石油大学的学生,能给个资料么?我的邮箱chenrongjn@163.com

用户192585 2009-4-14 17:10

可以给我一份软硬件资料学习吗?125096005@qq.com
相关推荐阅读
用户198065 2010-07-18 10:52
51 avr 下载板 最小系统 转接板
51 /AVR 双用最小系统 空板 DIY 提供转接板功能:(1)AT89S5X,stc89CXX系列最小系统板,烧写板      (2)ATMEGA8515/ATmega16/ATmega32最小系...
用户198065 2010-07-18 10:50
USB下载器
usb 下载器 空板提供制作方法,原理图,PCB,保证新手也能会制作自己的烧写器。  提供监控程序和制作方法,只要焊接没问题,100%可制作 选择我们精英电子团队的作品,就等于选择了专业,因为我们有自...
用户198065 2009-03-09 15:50
FC-1脉冲发生器 程序 技术指标
  //ICC-AVR application builder : 2008-6-29 16:23:43// Target : M16// Crystal: 10.0000Mhz#include &l...
用户198065 2009-02-27 22:11
基于51单片机超声波测距器设计 倒车雷达
超声波倒车控制器的技术要求(暂定)1:在现有样品只能显示测试距离功能的基础上增加继电器用来控制电机断电(串励系统)或者启动它励(它励系统)同时有声光报警。数位显示可以保留作为选装件。2:控制器应在离障...
用户198065 2009-02-27 21:44
51 单片机 开发板 图片
    ...
我要评论
8
3
关闭 站长推荐上一条 /2 下一条