规格功能说明:
该电子里程仪有两种计量方式,所以,设计时需要预留两种测量接口,客户可以根据自己的需要使用任何一种测量方式。
两种测量方式都需要完成如下功能:
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?可否说一下?() |
/* 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[b]);//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 ();
}
}