找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3112|回复: 3
打印 上一主题 下一主题
收起左侧

基于51单片机定时器0计时计数器1计数的霍尔传感器精确测速LCD1602显示测速的项目工程

[复制链接]
跳转到指定楼层
楼主
本帖最后由 51黑电子会员 于 2020-4-7 21:22 编辑
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int     
  5. sbit RW=P2^6;//定义LCD1602液晶显示器读写端         
  6. sbit RS=P2^5;//定义LCD1602液晶显示器数据命令端
  7. sbit EN=P2^7;//定义LCD1602液晶显示器使能端
  8. sbit qiting=P3^0;//定义启停按键
  9. uchar qitingnum;//定义启停次数变量
  10. uint count;//定时器0定时中断次数变量
  11. unsigned long speed=0;//定义速度变量
  12. uchar code tab1[]={"RPM:"};//显示转速的固定大写字符
  13. uchar code tab2[]={"rpm/sec"};//显示转速的固定小写字符
  14. /**ms级延时子程序**/
  15.   void delay(uint x)
  16. {
  17.    uint i,j;                       
  18.    for(i=0;i<x;i++)     
  19.     for(j=0;j<110;j++);
  20.   }
  21. /********液晶写入指令函数与写入数据函数**************/
  22.   void write_1602com(uchar com)//****液晶写入指令函数****
  23. {
  24.    RS=0;//数据/指令选择置为指令
  25.    P0=com;//送入数据
  26.    delay(1);
  27.    EN=1;//拉高使能端,为制造有效的下降沿做准备。
  28.    delay(1);
  29.    EN=0;//en由高变低,产生下降沿,液晶执行命令。
  30.   }
  31.   void write_1602dat(uchar dat)//液晶写入数据函数
  32. {
  33.    RS=1;//数据/指令选择置为数据
  34.    P0=dat;//送入数据
  35.    delay(1);
  36.    EN=1; //en置高电平,为制造下降沿做准备。
  37.    delay(1);
  38.    EN=0; //en由高变低,产生下降沿,液晶执行命。
  39.   }
  40.   void lcd1602_init()//液晶初始化函数
  41. {
  42.    uchar a;
  43.    RW=0;
  44.    write_1602com(0x38);//设置液晶工作模式,意思:16*2行显示,5*7点阵,8位数据。
  45.    write_1602com(0x0c);//开显示不显示光标
  46.    write_1602com(0x06);//整屏不移动,光标自动右移。
  47.    write_1602com(0x01);//清显示        
  48.    write_1602com(0x80);//显示固定符号从第一行第0个(从第0个开始数)位置开始显示
  49.    for(a=0;a<4;a++)
  50. {
  51.     write_1602dat(tab1[a]);//向液晶屏写固定符号部分
  52.    }
  53.    write_1602com(0x80+9);//显示固定符号写入位置,从第一行第9个(从第0个开始数)位置开始显示。
  54.    for(a=0;a<8;a++)
  55. {
  56.     write_1602dat(tab2[a]);//写显示固定符号
  57.    }
  58. }
  59. /*************转速显示函数**********/  
  60.   void display(unsigned long speed)//转速显示函数
  61. {
  62.    if(speed<=99999)
  63. {
  64.     uchar wan,qian,bai,shi,ge;//定义拆字变量
  65.     wan=speed/10000;//转速/10000得到万位
  66.     qian=speed%10000/1000;//转速/10000的余数/1000得到千位
  67.     bai=speed%1000/100;//取得百位
  68.     shi=speed%100/10;//取得十位数字
  69.     ge=speed%10;//取得个位数字
  70.     write_1602com(0x80+4);//从第一行第4个(从第0个开始数)位置开始显示
  71.     if(wan==0)//万位为0时
  72.   {
  73.      write_1602dat(' ');//显示空格
  74.     }
  75.     else//万位不为0时
  76.   {
  77.      write_1602dat(0x30+wan);//显示万位的数据,+0x30是因为在液晶的字库中,0的地址是0x30,1的地址是0x31,以此类推。
  78.     }
  79.     if((wan+qian)==0)//万位和千位都为0时
  80.   {
  81.      write_1602dat(' ');//千位显示空格
  82.     }
  83.     else//万位和千位不都为0时
  84.   {
  85.      write_1602dat(0x30+qian);//显示千位数据
  86.     }

  87.     if((wan+qian+bai)==0)//万位、千位和百位都是0时
  88.   {
  89.      write_1602dat(' ');//显示空格
  90.     }
  91.     else//万位、千位和百位不都为0时
  92.   {
  93.      write_1602dat(0x30+bai);//显示百位数据
  94.     }
  95.     if((wan+qian+bai+shi)==0)//万位、千位、百位和十位都为0时
  96.   {
  97.      write_1602dat(' ');//显示空格
  98.     }
  99.     else//万位、千位、百位和十位不都为0时
  100.   {
  101.      write_1602dat(0x30+shi);//显示十位数据
  102.     }               
  103.     write_1602dat(0x30+ge);//显示个位数据,数字+0x30得到该数字的LCD1602显示码。
  104.   }
  105. }
  106. /**************按键扫描函数*****************/  
  107.   void keyscan()//按键扫描函数
  108. {
  109.    if(qiting==0)//判断启停键是否按下
  110. {
  111.     delay(5);
  112.     if(qiting==0)//判断启停键是否再次按下
  113.   {
  114.      qitingnum++;//启停次数变量加加
  115.      lcd1602_init();//LCD1602液晶显示器初始化函数
  116.      while(!qiting);//等待启停键松开
  117.    }
  118.   }
  119.    if(qitingnum==1)//判断启停次数变量是否为1
  120. {
  121.     display(speed);//显示速度函数
  122.   }
  123.    if(qitingnum==2)//判断启停次数变量是否为2
  124. {
  125.     write_1602com(0x08);//关LCD1602液晶显示器显示
  126.     qitingnum=0;//启停次数变量置0
  127.    }
  128. }
  129. /**********定时器0、计数器1初始化子程序*********/
  130.   void Time0_Time1_init()
  131. {
  132.    TMOD=0X51;//模式选定时器0、计数器1,工作方式选定时器0定时模式1、计数器1计数模式1。
  133.    TH0=(65536-50000)/256;//定时器0高8位定时50毫秒
  134.    TL0=(65536-50000)%256;//定时器0低8位定时50毫秒
  135.    TH1=0;//计数器1高8位计数初值为0
  136.    TL1=0;//计数器1低8位计数初值为0
  137.    EA=1;//打开总中断
  138.    ET0=1;//打开定时器0的中断
  139.    TR0=1;//打开定时器0
  140.    ET1=1;//打开计数器1的中断
  141.    TR1=1;//打开计数器1
  142. }
  143. /************主函数***************/  
  144.   void main()//主函数
  145. {
  146.    Time0_Time1_init();//定时器0与外部中断0初始化子程序
  147.    while(1)//固定循环
  148. {  
  149.     keyscan();
  150.   }
  151. }
  152. /**定时器0中断服务子程序**/                                      
  153.   void Timer0() interrupt 1
  154. {
  155.    TH0=(65536-50000)/256;//重装定时器0高8位定时50毫秒
  156.    TL0=(65536-50000)%256;//重装定时器0低8位定时50毫秒
  157.    count++;//定时器0定时中断次数变量加加
  158.    if(count==20)//判断定时器0定时中断次数变量是否等于20,即1秒钟。
  159. {
  160.     count=0;//定时器0定时中断次数变量清0
  161.     TR1=0;//关计数器1,开始统计1秒钟内,霍尔元件发送的脉冲个数。
  162.     speed=TH1*256+TL1;//表示计数器1计数霍尔元件发送的脉冲个数,即转速:转/秒。
  163.     TH1=0;//计数器1高8位计数清0,为了下一次计数。
  164.     TL1=0;//计数器1低8位计数0,为了下一次计数。
  165.     TR1=1;//开计数器1,为了下一次统计1秒钟内,霍尔元件发送的脉冲个数。
  166.    }
  167. }
复制代码


图片11.png (79.45 KB, 下载次数: 41)

图片11.png
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏5 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:763540 发表于 2020-6-20 19:14 | 只看该作者
P0口我需要改为P1口使用,程序上怎么改呀?我只改了 P2=com;//送入数据, P0=dat;//送入数据;不行啊,不会显示,初学,请指教,谢谢!!
回复

使用道具 举报

板凳
ID:815648 发表于 2020-9-1 12:54 | 只看该作者
要是能把程序文件和仿真文件发出来就好了
回复

使用道具 举报

地板
ID:800952 发表于 2020-9-10 16:15 来自手机 | 只看该作者
我是定义1000循环1000次,理论1秒实际半秒不到,难道我的硬件问题?
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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