打印
[51单片机]

霍尔测速

[复制链接]
1605|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
蹦擦蹦擦|  楼主 | 2016-3-10 11:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
dirtwillfly| | 2016-3-10 21:29 | 只看该作者
板凳
蹦擦蹦擦|  楼主 | 2016-3-22 09:18 | 只看该作者
dirtwillfly 发表于 2016-3-10 21:29
http://wenku.baidu.com/link?url=c0eZrzSgonjcfz5kPvwr2zz0T5zgYAbZwbztoOOPYcJ9gU9ZLeNYk3g9-WZlym3UUkV4 ...

#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
typedef unsigned char uint8;              //数据类型宏定义
typedef unsigned int  uint16;
sbit  lcden=P2^5;                              //LCD1602使能端
sbit  lcdrs=P1^0;                              //LCD1602数据命令选择端
sbit  lcdrw=P1^1;                             //LCD1602读写选择端
sbit  lcdbusy=P0^7;                                 //繁忙检测位
sbit  pulse=P3^4;                       //脉冲输入端

uint i,kop,z,zhuan,num;
uint  num=0;

uchar display[]={"speed  =r/sec"};    // 定义显示参数
void delayms(uchar);                 //声明延时子函数
/*延时函数*/
void delayms(uchar xms)
{
uchar l,n;
for(l=xms;l>0;l--)
   for(n=110;n>0;n--);
}
/*繁忙检测函数*/
void wait(void)
{
         P0=0xFF;
         do
                 {
                 lcdrs=0;
                 lcdrw=1;
                 lcden=0;
                 lcden=1;
                 }
         while (lcdbusy==1);
         lcden=0;
}


/*向LCD1602写命令*/
void write_cmd(uint8 cmd)
{
        wait();
        lcden=0;
        P0=cmd;
        lcdrs=0;
        lcdrw=0;
        lcden=1;
        lcden=0;
}
/*向LCD1602写数据*/
void write_dat(uint8 dat)
{
        wait();
        lcden=0;
        P0=dat;
        lcdrs=1;
        lcdrw=0;
        lcden=1;
        lcden=0;
}
/*发送字符串到LCD1602*/
void write_string(uint8 addr_start, uint8 *p)
{
        write_cmd(addr_start);
        while (*p != '\0')
        {
                write_dat(*p++);
        }
}

/*LCD显示函数*/
void displaytolcd()
{
  write_cmd(0x80);                                  //向LCD1602写命令80H
  for (i=0;i<sizeof(display)-1;i++)                //循环要传输的字符个数次,每一次传输一个字符
  {
  write_dat(display);
  delayms(5);
}
}


/*数据处理函数*/
void disp_count()
{
display[6]=(zhuan/1000+'0');                    //转换转速的千位
display[7]=(zhuan/100%10+'0');                //转换转速的百位
display[8]=(zhuan/10%10+'0');                //转换转速的十位
display[9]=(zhuan%10+'0');                  //转换转速的个位
}


/*定时时间到,获取计数器值*/
void Timer_0(void) interrupt 3
{
TH1=(65536-50000)/256;                                                   //T1定时器装入初值,定时50ms
TL1=(65536-50000)%256;
num++;
if(num==20)                                  //50*20=1S
{
  num=0;
  kop=TH0;                                   //计数器计入脉冲,每来一个矩形脉冲计数值加1
  kop=kop<<8;
  kop=kop+TL0;
  kop=kop/5;
  zhuan=kop;
  disp_count();
  displaytolcd();
  TH0=0;
  TL0=0;                                    //计数器清零
}
}
/*初始函数*/
void LCD1602()
{
lcdrw=0;                           //只写
write_cmd(0x38);                  //设置16x2显示,5x7点阵,8位数据接口
delayms(5);
write_cmd(0x0c);                                  //设置开显示,不显示光标
delayms(5);
write_cmd(0x06);                                  //写一个字符后地址指针加1
delayms(5);
write_cmd(0x01);                                  //显示清0,数据指针清0
delayms(5);
}

/*定时器初始函数*/
void init()
{
TMOD=0x15;                                                                                   //T0为计数器,T1为定时器,都工作方式为1
TH1=(65536-50000)/256;                                //50ms定时 定时器1
TL1=(65536-50000)%256;
TH0=0x00;
TL0=0x00;                                                                                          //T0计数器初值
EA=1;                                                //开总中断
ET0=1;                                              //开计数器0中断
ET1=1;                                                                                          //开定时器1中断
TR0=1;                                              //启动计数器0
TR1=1;                                                                                          //启动定时器0
}
                                                                                                 
                                            


void main()
{
LCD1602();
init();
while(1)
  {
  disp_count();
  displaytolcd();
  }
}

使用特权

评论回复
地板
蹦擦蹦擦|  楼主 | 2016-3-22 09:20 | 只看该作者
dirtwillfly 发表于 2016-3-10 21:29
http://wenku.baidu.com/link?url=c0eZrzSgonjcfz5kPvwr2zz0T5zgYAbZwbztoOOPYcJ9gU9ZLeNYk3g9-WZlym3UUkV4 ...

您能看看下面的程序哪里出问题了吗?

使用特权

评论回复
5
dirtwillfly| | 2016-3-22 20:41 | 只看该作者
蹦擦蹦擦 发表于 2016-3-22 09:20
您能看看下面的程序哪里出问题了吗?

有什么问题?

使用特权

评论回复
6
蹦擦蹦擦|  楼主 | 2016-3-25 09:00 | 只看该作者

有人告诉我定时器定时50ms时间太长了,会导致数据不准确。而且我实际测量中转速变化的很慢

使用特权

评论回复
7
dirtwillfly| | 2016-3-25 12:16 | 只看该作者
蹦擦蹦擦 发表于 2016-3-25 09:00
有人告诉我定时器定时50ms时间太长了,会导致数据不准确。而且我实际测量中转速变化的很慢 ...

这个定时时间要看你的转速是多少。一般一个周期大约有十个或者更多的脉冲,计数就比较准

使用特权

评论回复
8
dirtwillfly| | 2016-3-25 12:20 | 只看该作者
另外,你用的什么频率的晶振,稳定性如何?

使用特权

评论回复
9
蹦擦蹦擦|  楼主 | 2016-3-31 15:50 | 只看该作者
dirtwillfly 发表于 2016-3-25 12:20
另外,你用的什么频率的晶振,稳定性如何?

我用的是51单片机的开发板,晶振是11.0592.不知道它的稳定性怎么样,但它的运算速度应该是不快

使用特权

评论回复
10
蹦擦蹦擦|  楼主 | 2016-3-31 15:52 | 只看该作者
dirtwillfly 发表于 2016-3-25 12:20
另外,你用的什么频率的晶振,稳定性如何?

我用的是51单片机的开发板,晶振是11.0592.不知道它的稳定性怎么样,但它的运算速度应该是不快

使用特权

评论回复
11
NE5532| | 2016-3-31 16:34 | 只看该作者
如果我来做,会把定时器设得超过一个周期,然后用霍尔的信号通过中断或者捕捉来算,这样定时器运行期间就不受其他因素影响了。你晶体的精度至少是10E-4级别的,做实验可以不用纠结了。

使用特权

评论回复
12
coody| | 2016-4-1 15:09 | 只看该作者
方法1:时间T内数脉冲个数,计算速度。
方法2:测量一个脉冲的周期,计算速度。

使用特权

评论回复
13
蹦擦蹦擦|  楼主 | 2016-4-5 08:59 | 只看该作者
NE5532 发表于 2016-3-31 16:34
如果我来做,会把定时器设得超过一个周期,然后用霍尔的信号通过中断或者捕捉来算,这样定时器运行期间就不 ...

您说的把定时器设的超过一个周期是指来一次脉冲的周期?也就是说把定时器定时时间设的长一些?

使用特权

评论回复
14
蹦擦蹦擦|  楼主 | 2016-4-5 09:02 | 只看该作者
coody 发表于 2016-4-1 15:09
方法1:时间T内数脉冲个数,计算速度。
方法2:测量一个脉冲的周期,计算速度。 ...

嗯是的。我现在用的是方法1,测量T时间内的脉冲个数来计算速度

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

26

帖子

0

粉丝