圣源电子制作

 找回密码
 立即注册
查看: 11079|回复: 0
打印 上一主题 下一主题

霍尔磁测速-自行车测距仪-MC68HC908QY4-1601LCD显示-C语言程序-电路图-转载自国外网站

[复制链接]
跳转到指定楼层
楼主
发表于 2011-12-4 15:08:04 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
开发设备来测量距离,骑自行车时。 磁铁和磁传感器(邻近效应)接触被用来检测车轮转动。 项目包括摩托罗拉68HC908QY4来自簧开关的脉冲信号计数的微控制器。 数据显示,在1个16液晶显示模块。





原理很简单,可以重建容易普及的董事会。 软件是用ICC08编译器,可以轻松修改。 主要的修改将调整车轮的直径。


程序:
  1. /*

  2.   lcd.c firmware for Distant Meter V1.0
  3.   the sensor is simple reed switch with magnet tied
  4.   to bycycle wheel. Optional 8-bit analog display for
  5.   user sensor.
  6.    
  7.   MC908QY4CP 16-pin MCU
  8.   compiled with icc08
  9.      
  10.   Copyright (c) 2004 Wichit Sirichote

  11. */


  12. #include <io908QY4.H>

  13. #define one_revolution 157 // 2PIr, radius is 25cm
  14. #define p 1 // scale of ADC reading


  15. char temp,k;
  16. unsigned int PV,temp16;
  17. char i,n,timer1,timer2;
  18. unsigned char sec;
  19. char x1,x2,x3;

  20. long average,length, count;

  21. char diff,old, now;

  22. char *title = "DISTANCE METER 1";
  23. char buffer[10];

  24. /*   signal for lcd interface
  25.    E       PTB1
  26.    RS      PTB0

  27.    D4      PTB4
  28.    D5      PTB5
  29.    D6      PTB6
  30.    D7      PTB7
  31.    
  32.    D0-D3 and R/W# are tied to GND
  33. */

  34.         
  35. void delay(int j)
  36. {
  37.    unsigned int i;
  38.    for (i = 0; i < j; i++)
  39.    COPCTL = 0;   // clear COP otherwise the cpu itself will be reset           
  40. }

  41. void pulseE()
  42. {
  43.     PTB |= 2;
  44.     delay(10);
  45.         PTB &= ~2;   
  46. }
  47. void LCDWI(char c)     /* write instruction to instruction register */
  48. {
  49.      temp = c;
  50.          PTB &= ~3;   // clear RS and E
  51.          PTB &= 0x0f; // clear high nibbel to low
  52.          c &= 0xf0; // prepare only high nibble
  53.          PTB |= c;
  54.          pulseE();
  55.          c = temp;
  56.          c <<=4;
  57.          PTB &= 0x0f;
  58.          PTB |= c;
  59.          pulseE();
  60.          delay(50);
  61. }         

  62. void
  63. LCDWD(char c)    /* write data to data register */
  64. {
  65.     temp = c;
  66.         PTB |= 1; // set bit RS
  67.         PTB &= ~2; // clear bit E
  68.     PTB &= 0x0f; // clear high nibbel to low
  69.         c &= 0xf0; // prepare only high nibble
  70.         PTB |= c; // mearge high nibble first
  71.         pulseE();
  72.         c = temp;
  73.         c <<=4;
  74.         PTB &= 0x0f;
  75.         PTB |= c;
  76.         pulseE();
  77.         delay(50);
  78. }        

  79. void i_LCD() /* initialize LCD in accordance with Hitachi 44780 4-bit
  80. mode */
  81. {
  82.     PTB &= ~3;        // clear RS and E
  83.         PTB |= 0x30;
  84.         pulseE();
  85.     delay(200);
  86.     pulseE();
  87.     delay(50);
  88.     pulseE();
  89.     delay(50);
  90.     PTB &= 0x0f;
  91.         PTB |= 0x20;
  92.         pulseE();
  93.     pulseE();
  94.     pulseE();
  95.     LCDWI(0x28); // set 4-bit bus, 1/16 line, 5*7 dots  
  96.     LCDWI(0x0c); // display on/off on display,off cursor, no blink
  97.     LCDWI(0x06); // entry mode DDRAM auto address increment
  98.     LCDWI(1);    // clear display  
  99.     delay(50);
  100. }

  101. // print LCD text >8
  102. // the 16x1 line LCD has two blocks start address!
  103. void print_lcds(char *s)
  104. {
  105.     char i;
  106.         LCDWI(1); // clear display
  107.         LCDWI(0x80); // start at left most position
  108.         for(i=0; i<8; i++)
  109.           LCDWD(*s++);
  110.           LCDWI(0xc0); // new address for position 9
  111.            for(i=0; i<8; i++)
  112.               LCDWD(*s++);
  113. }               

  114. char read_ADC()
  115. {
  116.           ADSCR = 0; // read channel 0 one time
  117.          while(!(ADSCR&0x80))
  118.          ;
  119.          return ADR;
  120. }
  121. // 3-point moving average (digital filtering)

  122. long read_ADC_filter(){
  123.    PV = read_ADC();
  124.    x3 = x2;
  125.    x2 = x1;
  126.    x1 = PV;
  127.    PV = (x1+x2+x3)/3;
  128.    return PV;
  129. }                                                         

  130. int read_adc_scale(){
  131.   long k;
  132.   k = read_ADC_filter()*p;
  133.   return k;
  134. }


  135. void print_dec(char d,unsigned int n)
  136. {
  137.    buffer[0] = n/10000+48;
  138.    temp16 = n%10000;
  139.    buffer[1] = temp16/1000+48;
  140.    temp16 %=1000;
  141.    buffer[2] = temp16/100+48;
  142.    temp16 %=100;
  143.    buffer[3] = temp16/10+48;
  144.    buffer[4] = temp16%10+48;
  145.    LCDWI(d);
  146.    for(i=0; i<5; i++)
  147.      LCDWD(buffer[i]);
  148. }   
  149.          
  150. void print_distant()
  151. {
  152.           if(++timer1>10)
  153.          {
  154.          timer1 = 0;
  155.          PTA ^= 2; // toggle PA1
  156.         // count++; // test auto increment
  157.          length = count*one_revolution; // one revolution = 157cm
  158.          print_dec(0x80,length/100); // 100cm = 1m
  159.          LCDWD(' ');
  160.          LCDWD('m');
  161.          print_dec(0xc0,read_adc_scale());
  162.          }
  163. }         

  164. void task_led()
  165. {
  166.     if(++timer2>50)
  167.         {
  168.          timer2 =0;
  169.      LCDWI(0xc7);
  170.          k^=1;
  171.          if (k) LCDWD('-');
  172.          else LCDWD('_');
  173.          }
  174. }

  175. // PTA2 input bit for reed swicth sensor
  176. // detect rising edge
  177. void detect_pulse_input()
  178. {  
  179.      now = PTA&4; // read only PTA2
  180.          diff = old-now;
  181.          if(diff>4) count++;
  182.           old = now;
  183. }         

  184. void print_average()
  185. {   
  186.     average += count;
  187.         average /= 2;
  188.     print_dec(0xc0,average);
  189. }        

  190. void main()
  191. {
  192.          // OCSTRIM = 0x81; // trim internal oscillator
  193.           delay(1000); // powerup delay for LCD
  194.          n = k=0;
  195.           count = 0;
  196.          average = 0;
  197.          
  198.          TMODH = 0x01;
  199.          TMODL = 0xf4;
  200.          TSC = 0x06; // run timer
  201.          DDRA = ~0x1; // PA0 is ADC input
  202.          DDRB = 0xff; // port B is output port
  203.          PTB = 0; // clear port B
  204.          PTAPUE = ~0x81; // osc2 pin is PTA4 I/O
  205.          ADCLK = 0x40; // ADC clock= fbus/4
  206.          i_LCD();
  207.          print_lcds(title);
  208.          delay(60000);
  209.          now = old = PTA&4;
  210.          LCDWI(1); // clear lcd
  211.          //asm(" cli"); //enable irq interrupt
  212.                   
  213.         for(;;)
  214.         {
  215.          while(!(TSC&0x80))
  216.          ;
  217.          TSC &= ~0x80; // clear TOF
  218.         // PTA ^= 2; // task running ~60Hz so the loop running is 120Hz or 1/120Hz
  219.          task_led();
  220.          print_distant();
  221.          detect_pulse_input();
  222.          COPCTL = 0; // clear COP         
  223.          }
  224. }         
复制代码

下载:
原理图.pdf (28.94 KB, 下载次数: 33)
WWW.SYYYD.COM-C程序.zip (2.13 KB, 下载次数: 23)

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|联系我们|闽公网安备 35012102000020号|闽ICP备11020110号-1|圣源电子

GMT+8, 2024-11-3 21:23 , Processed in 0.042946 second(s), 21 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表