圣源电子制作

标题: 利用,红外-霍尔传感测速,4位数码管显示测速-89C51-含C语言及汇编 程序-制作 DIY [打印本页]

作者: sydz    时间: 2011-9-25 22:51
标题: 利用,红外-霍尔传感测速,4位数码管显示测速-89C51-含C语言及汇编 程序-制作 DIY
转载自互联网!!!
(, 下载次数: 74)
输入 高低点平即可。
  10个脉冲 记一圈, 4位数码管显示
可以更改程序,改成1个脉冲,一圈,或者2个脉冲一圈 等等
  1. #include <REG52.H>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. #define ulong unsigned long
  5. #define LED_DAT P0
  6. sbit LED_SEG0 = P2^7;
  7. sbit LED_SEG1 = P2^6;
  8. sbit LED_SEG2 = P2^5;
  9. sbit LED_SEG3 = P2^4;
  10. #define TIME_CYLC 100 //12M晶振,定时器10ms 中断一次 我们1秒计算一次转速 // 1000ms/10ms = 100
  11. #define PLUS_PER 10 //码盘的齿数 ,这里假定码盘上有10个齿,即传感器检测到10个脉冲,认为1圈
  12. #define K       1.65   //校准系数



  13. unsigned char code  table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
  14. uchar data Disbuf[4];// 显示缓冲区
  15. uint Tcounter = 0;   //时间计数器
  16. bit Flag_Fresh = 0; // 刷新标志
  17. bit Flag_clac = 0; //计算转速标志
  18. bit Flag_Err = 0; //超量程标志

  19. void DisplayFresh();//在数码管上显示一个四位数

  20. void ClacSpeed();//计算转速,并把结果放入数码管缓冲区

  21. void init_timer();//初始化定时器T0\T1

  22. void Delay(uint ms);//延时函数

  23. void it_timer0() interrupt 1 /* interrupt address is 0x000b */
  24. {
  25. TF0 = 0;       //定时器 T0用于数码管的动态刷新
  26. TH0 = 0xC0;   
  27. TL0 = 0x00;
  28. Flag_Fresh = 1;
  29. Tcounter++;
  30. if(Tcounter>TIME_CYLC)
  31. { Flag_clac = 1;//周期到,该重新计算转速了
  32. }
  33. }
  34. void it_timer1() interrupt 3 /* interrupt address is 0x001b */
  35. {
  36. TF1 = 0;   //定时器T1用于单位时间内收到的脉冲数
  37.            //要速度不是很快,T1永远不会益处
  38. Flag_Err = 1;   //如果速度很高,我们应考虑另外一种测速方法:T测速法
  39.      
  40. }
  41. void main(void)
  42. {
  43. Disbuf[0] = 0; //开机时,初始化为0000
  44. Disbuf[1] = 0;
  45. Disbuf[2] = 0;
  46. Disbuf[3] = 0;
  47. init_timer();
  48. while(1)
  49. {  
  50. if(Flag_Fresh)
  51.    { Flag_Fresh = 0;
  52.     DisplayFresh();    // 定时刷新数码管显示
  53.    }
  54.    if(Flag_clac)
  55.    { Flag_clac = 0;
  56.     ClacSpeed(); //计算转速,并把结果放入数码管缓冲区  
  57.     Tcounter = 0;//周期定时 清零
  58.     TH1=TL1 = 0x00;//脉冲计数清零
  59.    
  60.    }
  61.   if(Flag_Err)        //超量程处理
  62.   {
  63.     Disbuf[0] = 0x9e; //开机时,初始化为0000
  64.     Disbuf[1] = 0x9e;
  65.     Disbuf[2] = 0x9e;
  66.     Disbuf[3] = 0x9e;
  67.    while(1)
  68.     { DisplayFresh();//不再测速 等待复位i
  69.     }
  70.   }

  71. }
  72. }

  73. //在数码管上显示一个四位数
  74. void DisplayFresh()
  75. {
  76. P2 |= 0xF0;
  77. LED_SEG0 = 0;
  78. LED_DAT = table[Disbuf[0]];
  79. Delay(1);
  80. P2 |= 0xF0;
  81. LED_SEG1 = 0;
  82. LED_DAT = table[Disbuf[1]];
  83. Delay(1);
  84. P2 |= 0xF0;
  85. LED_SEG2 = 0;
  86. LED_DAT = table[Disbuf[2]];
  87. Delay(1);
  88. P2 |= 0xF0;
  89. LED_SEG3 = 0;
  90. LED_DAT = table[Disbuf[3]];
  91. Delay(1);
  92. P2 |= 0xF0;

  93. }
  94. //计算转速,并把结果放入数码管缓冲区
  95. void ClacSpeed()
  96. {
  97. uint speed ;
  98. uint PlusCounter;

  99. PlusCounter = TH1*256 + TL1;
  100. speed =6*PlusCounter/K;      //K是校准系数,如速度不准,调节K的大小
  101. Disbuf[3] = (speed/1000)%10;  
  102. Disbuf[2] = (speed/100)%10;
  103. Disbuf[1] = (speed/10)%10;
  104. Disbuf[0] = speed%10;
  105. }
  106.          
  107. void init_timer()//初始化定时器T0\T1
  108. {
  109. TMOD=0x51; //定时器0工作于定时方式1,定时器1工作于计数方式
  110. TH0=(65536-10000)/256;
  111. TL0=(65536-10000)%256; //TO定时时间为10000个周期即10毫秒
  112. TH1=0x00;
  113. TL1=0x00;
  114. ET0=1;                     /* enable timer0 interrupt */
  115. EA=1;                /* enable interrupts */
  116. TR0=1;               /* timer0 run */
  117. ET1=1;                     /* enable timer1 interrupt */
  118. EA=1;                /* enable interrupts */
  119. TR1=1;   

  120. }
  121. //延时函数
  122. void Delay(uint ms)
  123. {
  124. uchar i;
  125. while(ms--)
  126.    for(i=0;i<100;i++);
  127. }

复制代码



包含C,汇编程序,HEX
(, 下载次数: 129)






欢迎光临 圣源电子制作 (https://sydz.syyyd.com/) Powered by Discuz! X3.4