找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3015|回复: 8
收起左侧

这里面哪个单片机代码是获取霍尔元件的数据啊?

[复制链接]
ID:913176 发表于 2021-5-16 19:30 | 显示全部楼层 |阅读模式
51hei截图20210516192927.png
单片机源程序如下:
  1. #include <reg52.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. void displaym();
  5. sbit en=P2^5;                //1602  6管脚
  6. sbit rs=P2^7;         //1602端口        4管脚
  7. sbit rw=P2^6;//lcd1602控制端口 5管脚
  8. sbit num1=P1^0;                                                //占空比加1
  9. sbit num2=P1^1;                                                                   //占空比减一
  10. sbit num3=P1^2;                                                                                           //正传
  11. sbit num4=P1^3;                                                                                                         //反转
  12. sbit num5=P1^4;                                                                                                                   //开始停止切换
  13. sbit num6=P2^3;

  14. sbit out=P3^4;                                                         //PWM输出用于正传
  15. sbit out1=P3^7;                        //PWM输出用于反转

  16. uint zhuansu,flag,z1,z2,m,flag_1,zheng,fan,kai,buzzer,zs;




  17. void delay(uint z)//延时1ms函数
  18. {

  19. uint x,y;
  20. for(x=0;x<z;x++)
  21.      for(y=0;y<110;y++);
  22. }



  23. void write_com(uchar com)//向1602写一字节(控制指令)
  24. {
  25.   rs=0;
  26.   P0=com;
  27.   delay(5);
  28.   en=0;
  29.   delay(10);
  30.   en=1;
  31. }
  32. void write_data(uchar date)//向1602写一字节(数据)
  33. {
  34.   rs=1;
  35.   P0=date;
  36.   delay(5);
  37.   en=0;
  38.   delay(5);
  39.   en=1;
  40. }
  41. void init()//初始化函数
  42. {
  43.   en=0;
  44.   rw=0;
  45.   write_com(0x01);         //lcd初始化
  46.   write_com(0x38);                                           //5X7显示
  47.   write_com(0x0c);                         //关闭光标
  48.   TMOD=0x01;               //定时器方式1   
  49.         
  50.   TH0=0xdc;
  51.   TL0=0x00;                //定时器装入初值
  52.   EA=1;                    //开总中断
  53.   ET0=1;                   //定时器0开中断
  54.         
  55.   TR0=1;
  56.   EX1=1;
  57. IT1=1;                 //定时器启动  
  58. TH1=0xfc;
  59.   TL1=0x66;//定时100us
  60.   ET1=1;                   //定时器1开中断
  61.   TR1=1;
  62.         
  63.         
  64.   write_com(0x80);
  65.   write_data('V');
  66.   write_data(':');
  67.   write_com(0x87);                 //第一行显示转速
  68.   write_data('r');
  69.   write_data('p');
  70.   write_data('m');
  71.   write_com(0xc0);
  72.   write_data('z');
  73.   write_data('h');
  74.   write_data('a');
  75.   write_data('n');
  76.   write_data('k');
  77.   write_data('o');
  78.   write_data('n');
  79.   write_data('g');
  80.   write_data('b');
  81.   write_data('i');          //在第二行显示zhankongbi:
  82.   write_data(':');
  83.   displaym();
  84. }
  85. void keyscan()  //键盘扫描函数
  86. {
  87.   if(num1==0)     
  88.   {
  89.     delay(5);      //消除抖动
  90.          if(num1==0)
  91.          {
  92.                 if(m<=199)
  93.                  m++;
  94.                         displaym();                                                                  //设定占空比加一
  95.      }
  96.   }
  97.   if(num2==0)
  98.   {
  99.     delay(5);
  100.          if(num2==0)
  101.          {
  102.                   if(m>=1)
  103.                 m--;
  104.                         displaym();                                        //设定占空比减一
  105.         
  106.          }
  107.   }
  108.     if(num3==0)
  109.   {
  110.     delay(5);
  111.          if(num3==0)
  112.          {
  113.           zheng=1;                //正传标志置1
  114.           fan=0;          // 反转标志置0
  115.         
  116.          }
  117.   }
  118.       if(num4==0)
  119.   {
  120.     delay(5);
  121.          if(num4==0)
  122.          {
  123.           zheng=0;                 //正传标志置0
  124.           fan=1;          // 反转标志置1
  125.         
  126.          }
  127.   }
  128.       if(num5==0)
  129.   {
  130.     delay(5);
  131.          if(num5==0)
  132.          {
  133.          while(num5==0)         ;
  134.           kai=1-kai;
  135.          }
  136.   }
  137. }
  138. void display()
  139. {
  140.   write_com(0x82);
  141.   zhuansu=zhuansu*10;          //将两秒内的计数乘以30得到转每分

  142.   if(zhuansu/10000!=0)
  143.    write_data(zhuansu/10000+0x30);                                                  //如果转速的万位不为0        正常显示否则显示空格
  144.    else
  145.    write_data(' ');

  146.   if(zhuansu/1000==0)
  147.   write_data(' ');
  148.   else
  149.   write_data(zhuansu%10000/1000+0x30);                                                                //如果转速小于1000 千位为空格 否则正常显示

  150.   if(zhuansu/100==0)
  151.   write_data(' ');
  152.   else
  153.   write_data(zhuansu%10000%1000/100+0x30);                                           //如果转速小于100 百位为空格 否则正常显示

  154.     if(zhuansu/10==0)
  155.   write_data(' ');
  156.   else
  157.   write_data(zhuansu%10000%1000%100/10+0x30);                                  //如果转速小于10 十位为空格 否则正常显示

  158.   write_data(zhuansu%10000%1000%100%10+0x30);
  159.   write_com(0xd0);                          //如果没有这句,当中断内的显示函数执行完,就会在转速的位置显示占空比数据,导致乱码
  160. }
  161. void displaym()
  162. {
  163.    write_com(0xcd);
  164.          write_data(m/2/100+0x30);
  165.         
  166.          write_com(0xce);
  167.          write_data(m/2%100/10+0x30);        

  168.         write_com(0xcf);
  169.          write_data(m/2%10+0x30);               
  170.         
  171.         
  172.         
  173.         
  174.         
  175.    if(m/200%10!=0)
  176.   write_data(m/200%10+0x30);                           //如果占空比百位不为0则显示百位否则显示空格
  177.   else
  178.   write_data(' ');

  179.   if(m/200%10==0&&m/20%10==0)
  180.   write_data(' ');
  181.   else
  182.   write_data(m/20%10+0x30);                                 //如果占空比小于10 十位正常显示  否则显示空格

  183.   write_data(m/2%10+0x30);                                 //显示个位
  184. }
  185. typedef unsigned int u16;
  186. void delayb(u16 i)
  187. {
  188. while(i--);
  189. }
  190. void warning()
  191. {   
  192.           if (buzzer ==1)
  193.         {
  194.     num6=~num6 ;
  195.     delayb(5) ;
  196.         }
  197.         else
  198.         {
  199.         num6=0;
  200.         delayb(5);
  201.         }
  202. }
  203. void main()
  204. {
  205.     flag_1=0;
  206.         m=100;                                                         //占空比为100
  207.         zhuansu=0;                                           //转速初值0
  208.         flag=0;
  209.         zheng=1;                                  //初始化电机正转动
  210.         fan=0;

  211.     init();              //初始化

  212.         while(1)
  213.         {
  214.         keyscan();                                //键盘扫描程序
  215.         zs=write_(0x82);
  216.                                       



  217.                         
  218.         if        (zs>)
  219.         {
  220.            buzzer=1;
  221.           if(buzzer==1)
  222.         {
  223.       num6=~num6 ;
  224.        delayb(5) ;
  225.         }
  226.         }
  227.         }

  228. }
  229. void int1()interrupt 2                                //外部中断1脉冲技术记录电机的转速 电机转一圈zhuansu加一
  230. {
  231.   zhuansu++;
  232. }
  233. void int2()interrupt 1                                  //定时器0显示转速
  234. {

  235.   TH0=0xdc;
  236.   TL0=0x00;//定时10ms
  237.   flag++;
  238.          
  239.   if(flag==200)                                   //计时到达2s
  240.     {


  241.         display();                                        //显示转速
  242.         zhuansu=0;                                          //转速置0
  243.         flag=0;

  244.         }
  245. }
  246. void int3()interrupt 3                                         //产生PWM
  247. {

  248.   TH1=0xfc;
  249.   TL1=0x66;//定时100us

  250.           flag_1++;
  251.         if(flag_1>199)
  252.         flag_1=1;
  253.         if(kai==1)                  //如果kai==1电机启动
  254.         {
  255.         if(zheng==1)                                //电机正转
  256.         {
  257.         if(flag_1<m)                                          //小于占空比m输出PWM=0输出电压为1
  258.      {out=0;
  259.          out1=1;}
  260.          else
  261.          {
  262.            out=1;
  263.            out1=1;
  264.          }
  265.          }
  266.                  if(fan==1)                           //电机反转
  267.         {
  268.         if(flag_1<m)                                //小于占空比m输出PWM=0输出电压为1
  269.           {
  270.             out=1;
  271.                 out1=0;
  272.           }
  273.          else                                                                         //大于m输出PWM=1输出电压为0
  274.           {
  275.             out=1;
  276.                 out1=1;
  277.           }
  278.          }
  279.          }
  280.          if(kai==0)                          //kai=0电机停止转动
  281.          {
  282.            out=1;
  283.            out1=1;
  284.          
  285.          }
  286. }
复制代码
回复

使用道具 举报

ID:390416 发表于 2021-5-16 19:52 | 显示全部楼层
霍尔传感器 是中断输入,中断号是2,建议观看 人人学会单片机的视频教程 彻底学好STC单片机中断
回复

使用道具 举报

ID:88256 发表于 2021-5-16 20:20 | 显示全部楼层
基础太差,电路图显示霍尔接在P3.3引脚,而P3.3是INT1,对应的就是第253行的void int1()interrupt 2                //外部中断1脉冲技术记录电机的转速 电机转一圈zhuansu加一    的整段程序
回复

使用道具 举报

ID:342822 发表于 2021-5-16 20:46 | 显示全部楼层
懒惰不看程序。程序已注明:外部中断1脉冲计数记录电机的转速 电机转一圈zhuansu加1
回复

使用道具 举报

ID:913176 发表于 2021-5-16 20:48 | 显示全部楼层
hhdsdy 发表于 2021-5-16 20:20
基础太差,电路图显示霍尔接在P3.3引脚,而P3.3是INT1,对应的就是第253行的void int1()interrupt 2        ...

那我如果想要在主函数的while循环中调用zhuansu该怎么调用啊,我直接在里面用zhaunsu表示不行
回复

使用道具 举报

ID:236035 发表于 2021-5-17 08:44 | 显示全部楼层
suit8515 发表于 2021-5-16 20:48
那我如果想要在主函数的while循环中调用zhuansu该怎么调用啊,我直接在里面用zhaunsu表示不行

这是全局变量,在哪都可以调用。多学习下,否则到哪都是问题,都要问人,次数多了,人家就不愿意了。
回复

使用道具 举报

ID:844772 发表于 2021-5-17 09:00 | 显示全部楼层
suit8515 发表于 2021-5-16 20:48
那我如果想要在主函数的while循环中调用zhuansu该怎么调用啊,我直接在里面用zhaunsu表示不行

zhuansu这个变量保存的仅仅是计数,不能直接知道转数,要计算一段时间的zhuansu变量的差值,推算转数,
回复

使用道具 举报

ID:824490 发表于 2021-5-17 09:46 | 显示全部楼层
glinfei 发表于 2021-5-17 09:00
zhuansu这个变量保存的仅仅是计数,不能直接知道转数,要计算一段时间的zhuansu变量的差值,推算转数,

按你的电路图和代码,zhuansu这个变量是计数轮子转了多少圈,这个值*6.28*轮子半径就近似小车移动的距离
回复

使用道具 举报

ID:824490 发表于 2021-5-17 10:35 | 显示全部楼层
本帖最后由 名字不是重点 于 2021-5-17 10:39 编辑

1:
zheng=1;                                  //初始化电机正转动
fan=0;
这2 个互斥,可以只设一个就行了。
2:
write_data(zhuansu%10000%1000%100%10+0x30);
这个可以优化为:
write_data(zhuansu%10+0x30);
相同的还有 write_data(zhuansu%10000%1000%100/10+0x30)==>write_data(zhuansu%100/10+0x30)

等等
连续取模的,可只取最后一个。
3:
void int2()interrupt 1 中不要做display(); 建议做法是if(flag==200)插入一个标志update,在main()的while(1)中判断update,再决定是否刷显转速。
4:
按键扫描都是P1口,建议一次读入P1的值,再用switch来做分支处理。

认真找找,应该还有很多地方能做优化的。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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