开发设备来测量距离,骑自行车时。 磁铁和磁传感器(邻近效应)接触被用来检测车轮转动。 项目包括摩托罗拉68HC908QY4来自簧开关的脉冲信号计数的微控制器。 数据显示,在1个16液晶显示模块。
原理很简单,可以重建容易普及的董事会。 软件是用ICC08编译器,可以轻松修改。 主要的修改将调整车轮的直径。
程序:
- /*
- lcd.c firmware for Distant Meter V1.0
- the sensor is simple reed switch with magnet tied
- to bycycle wheel. Optional 8-bit analog display for
- user sensor.
-
- MC908QY4CP 16-pin MCU
- compiled with icc08
-
- Copyright (c) 2004 Wichit Sirichote
- */
-
- #include <io908QY4.H>
- #define one_revolution 157 // 2PIr, radius is 25cm
- #define p 1 // scale of ADC reading
- char temp,k;
- unsigned int PV,temp16;
- char i,n,timer1,timer2;
- unsigned char sec;
- char x1,x2,x3;
- long average,length, count;
- char diff,old, now;
- char *title = "DISTANCE METER 1";
- char buffer[10];
- /* signal for lcd interface
- E PTB1
- RS PTB0
-
- D4 PTB4
- D5 PTB5
- D6 PTB6
- D7 PTB7
-
- D0-D3 and R/W# are tied to GND
- */
-
- void delay(int j)
- {
- unsigned int i;
- for (i = 0; i < j; i++)
- COPCTL = 0; // clear COP otherwise the cpu itself will be reset
- }
- void pulseE()
- {
- PTB |= 2;
- delay(10);
- PTB &= ~2;
- }
- void LCDWI(char c) /* write instruction to instruction register */
- {
- temp = c;
- PTB &= ~3; // clear RS and E
- PTB &= 0x0f; // clear high nibbel to low
- c &= 0xf0; // prepare only high nibble
- PTB |= c;
- pulseE();
- c = temp;
- c <<=4;
- PTB &= 0x0f;
- PTB |= c;
- pulseE();
- delay(50);
- }
- void
- LCDWD(char c) /* write data to data register */
- {
- temp = c;
- PTB |= 1; // set bit RS
- PTB &= ~2; // clear bit E
- PTB &= 0x0f; // clear high nibbel to low
- c &= 0xf0; // prepare only high nibble
- PTB |= c; // mearge high nibble first
- pulseE();
- c = temp;
- c <<=4;
- PTB &= 0x0f;
- PTB |= c;
- pulseE();
- delay(50);
- }
- void i_LCD() /* initialize LCD in accordance with Hitachi 44780 4-bit
- mode */
- {
- PTB &= ~3; // clear RS and E
- PTB |= 0x30;
- pulseE();
- delay(200);
- pulseE();
- delay(50);
- pulseE();
- delay(50);
- PTB &= 0x0f;
- PTB |= 0x20;
- pulseE();
- pulseE();
- pulseE();
- LCDWI(0x28); // set 4-bit bus, 1/16 line, 5*7 dots
- LCDWI(0x0c); // display on/off on display,off cursor, no blink
- LCDWI(0x06); // entry mode DDRAM auto address increment
- LCDWI(1); // clear display
- delay(50);
- }
- // print LCD text >8
- // the 16x1 line LCD has two blocks start address!
- void print_lcds(char *s)
- {
- char i;
- LCDWI(1); // clear display
- LCDWI(0x80); // start at left most position
- for(i=0; i<8; i++)
- LCDWD(*s++);
- LCDWI(0xc0); // new address for position 9
- for(i=0; i<8; i++)
- LCDWD(*s++);
- }
- char read_ADC()
- {
- ADSCR = 0; // read channel 0 one time
- while(!(ADSCR&0x80))
- ;
- return ADR;
- }
- // 3-point moving average (digital filtering)
- long read_ADC_filter(){
- PV = read_ADC();
- x3 = x2;
- x2 = x1;
- x1 = PV;
- PV = (x1+x2+x3)/3;
- return PV;
- }
- int read_adc_scale(){
- long k;
- k = read_ADC_filter()*p;
- return k;
- }
- void print_dec(char d,unsigned int n)
- {
- buffer[0] = n/10000+48;
- temp16 = n%10000;
- buffer[1] = temp16/1000+48;
- temp16 %=1000;
- buffer[2] = temp16/100+48;
- temp16 %=100;
- buffer[3] = temp16/10+48;
- buffer[4] = temp16%10+48;
- LCDWI(d);
- for(i=0; i<5; i++)
- LCDWD(buffer[i]);
- }
-
- void print_distant()
- {
- if(++timer1>10)
- {
- timer1 = 0;
- PTA ^= 2; // toggle PA1
- // count++; // test auto increment
- length = count*one_revolution; // one revolution = 157cm
- print_dec(0x80,length/100); // 100cm = 1m
- LCDWD(' ');
- LCDWD('m');
- print_dec(0xc0,read_adc_scale());
- }
- }
- void task_led()
- {
- if(++timer2>50)
- {
- timer2 =0;
- LCDWI(0xc7);
- k^=1;
- if (k) LCDWD('-');
- else LCDWD('_');
- }
- }
- // PTA2 input bit for reed swicth sensor
- // detect rising edge
- void detect_pulse_input()
- {
- now = PTA&4; // read only PTA2
- diff = old-now;
- if(diff>4) count++;
- old = now;
- }
- void print_average()
- {
- average += count;
- average /= 2;
- print_dec(0xc0,average);
- }
- void main()
- {
- // OCSTRIM = 0x81; // trim internal oscillator
- delay(1000); // powerup delay for LCD
- n = k=0;
- count = 0;
- average = 0;
-
- TMODH = 0x01;
- TMODL = 0xf4;
- TSC = 0x06; // run timer
- DDRA = ~0x1; // PA0 is ADC input
- DDRB = 0xff; // port B is output port
- PTB = 0; // clear port B
- PTAPUE = ~0x81; // osc2 pin is PTA4 I/O
- ADCLK = 0x40; // ADC clock= fbus/4
- i_LCD();
- print_lcds(title);
- delay(60000);
- now = old = PTA&4;
- LCDWI(1); // clear lcd
- //asm(" cli"); //enable irq interrupt
-
- for(;;)
- {
- while(!(TSC&0x80))
- ;
- TSC &= ~0x80; // clear TOF
- // PTA ^= 2; // task running ~60Hz so the loop running is 120Hz or 1/120Hz
- task_led();
- print_distant();
- detect_pulse_input();
- COPCTL = 0; // clear COP
- }
- }
复制代码
下载:
原理图.pdf
(28.94 KB, 下载次数: 33)
WWW.SYYYD.COM-C程序.zip
(2.13 KB, 下载次数: 23)
|