模吧

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

[单片机课堂] 第十四课:制作舵机测试仪

  [复制链接]
Now 该用户已被删除
发表于 2017-1-14 12:25:03 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 1 反对 0

使用道具 举报

发表于 2017-2-14 12:12:37 | 显示全部楼层
本帖最后由 世界大战 于 2017-2-14 12:16 编辑

红外和电压表的零件还没有到,先做一个舵机测试仪解解渴。
回复 支持 0 反对 1

使用道具 举报

发表于 2017-2-14 12:18:48 | 显示全部楼层
世界大战 发表于 2017-2-14 12:12
红外和电压表的零件还没有到,先做一个舵机测试仪解解渴。

上视频,交作业。
回复 支持 0 反对 1

使用道具 举报

发表于 2017-2-16 18:48:25 | 显示全部楼层
问下萝莉大神 我在测试时舵机一直发出嘟嘟声,但是舵机确没转动。这是为什么?
  1. #include <reg51.h>
  2. #include <intrins.h>
  3. #define  U16 unsigned int
  4. #define  U8 unsigned char
  5. //sbit servo1=P1^6;
  6. sfr P5=0xC8;
  7. sbit servo1=P1^5;
  8. sbit servo3=P1^4;
  9. U16 L;


  10. void De_n_Delay10us(U16 delaytime);
  11. void Delay10us();                //@12.000MHz

  12. void main()
  13. {
  14.   
  15.   L=150;
  16.    while(1)
  17.    {
  18.      servo1=1;
  19.          De_n_Delay10us(L);
  20.          servo1=0;
  21.          De_n_Delay10us(1900);

  22.          L=L+10;
  23.          if(L>200);
  24.          {
  25.            L=100;
  26.          }
  27.          
  28.    }

  29. }

  30. void Delay10us()                //@12.000MHz
  31. {
  32.         unsigned char i;

  33.         _nop_();
  34.         _nop_();
  35.         i = 24;
  36.         while (--i);
  37. }
  38. void De_n_Delay10us(U16 delaytime)
  39. {

  40.       while(delaytime>0)
  41.       {
  42.            Delay10us();
  43.            delaytime--;
  44.           }
  45. }
复制代码
回复 支持 0 反对 1

使用道具 举报

发表于 2017-3-11 23:34:35 | 显示全部楼层
好帖,好帖,顶一个
回复 支持 0 反对 1

使用道具 举报

发表于 2017-4-8 06:39:49 | 显示全部楼层
不错不错 为你顶帖 很赞
回复 支持 0 反对 1

使用道具 举报

发表于 2017-5-19 10:18:55 | 显示全部楼层
这个是个好东西。
回复 支持 0 反对 1

使用道具 举报

发表于 2017-6-13 15:54:02 | 显示全部楼层
开始看不懂了  
回复 支持 1 反对 0

使用道具 举报

发表于 2017-6-14 14:15:56 | 显示全部楼层
谢谢分享,楼主辛苦了
回复 支持 1 反对 0

使用道具 举报

发表于 2017-8-10 14:20:16 | 显示全部楼层
技术贴
回复 支持 1 反对 0

使用道具 举报

发表于 2017-12-18 10:14:30 | 显示全部楼层
这样的帖子应该置顶。
回复 支持 1 反对 0

使用道具 举报

发表于 2018-1-19 23:54:10 | 显示全部楼层
๑•́₃•̀2伐开心6666
回复 支持 0 反对 1

使用道具 举报

发表于 2018-2-5 22:44:02 | 显示全部楼层
这个有点难,我得研究一下。买的东西还没到
回复 支持 1 反对 0

使用道具 举报

发表于 2018-5-22 21:13:10 | 显示全部楼层
顶起
回复 支持 1 反对 0

使用道具 举报

发表于 2018-6-18 16:19:39 | 显示全部楼层
#include<reg51.h>
unsigned char count; //记录0.5ms次数用的变量
sbit pwm=P3^7;
回复 支持 0 反对 1

使用道具 举报

发表于 2018-7-11 09:02:08 | 显示全部楼层
这个程序和源码哪里有?
回复 支持 1 反对 0

使用道具 举报

发表于 2018-7-30 20:35:50 | 显示全部楼层
请教大神
为什么用定时器延时计数 定时器中断里t0++        用t0=0;while(t0<1000);延时显示数码管会闪烁  用t0=0;while(t0!=1000);就不会闪烁



  1. #include<reg51.h>

  2. #define uchar unsigned char
  3. #define uint unsigned int

  4. sfr P5=0xc8;                //声明P5端口地址
  5. sfr P2M0=0x96;                //声明P2引脚模式寄存器
  6. sfr P3M0=0xb2;                //声明P3引脚模式寄存器

  7. sfr AUXR=0x8e;                //声明辅助寄存器

  8. sfr ADC_RES=0xBD;        //声明转换结果寄存器
  9. sfr ADC_RESL=0xBE;        //声明转换结果寄存器低2位

  10. sfr P1ASF=0x9D;    //声明P1口模拟功能寄存器 模拟功能开关
  11. sfr ADC_CONTR=0xBC;//声明数模转换寄存器

  12. sbit DA=P2^4;                        //数码管位选
  13. sbit DB=P3^2;
  14. sbit DC=P3^6;
  15. sbit DD=P2^0;
  16. sbit DE=P2^1;
  17. sbit DF=P2^3;
  18. sbit DG=P3^5;
  19. sbit DP=P3^7;

  20. sbit B1=P2^5;                        //数码管段选
  21. sbit B2=P2^2;
  22. sbit B3=P3^3;
  23. sbit B4=P3^4;

  24. sbit CS=P3^1;                                                //片选端,CS为低时启动串行接口
  25. sbit SCK=P3^0;                                                //串行时钟输出到max6675
  26. sbit SO=P5^5;                                                //串行数据输入到单片机

  27. sbit keyx1=P2^6;                                        //定义键盘键位
  28. sbit keyx2=P2^7;
  29. sbit keyx3=P1^0;
  30. sbit keyx4=P1^1;
  31. sbit keyy1=P1^2;
  32. sbit keyy2=P1^3;
  33. sbit keyy3=P1^4;
  34. sbit keyy4=P1^5;
  35. sbit keyy5=P1^6;

  36. sbit S1=P5^4;                                                //定义pwm信号接口

  37. uchar count,count2,Flag_temp,Flag_key,keynow[20],keyold[20],mode,key;                                        //定义计数,热电偶就绪

  38. uint temp,value,t0;                                        //定义温度,按键值,定时器0计数

  39. uchar code duan[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6,0xee,0x3e,0x9c,0x7a,0x9e,0x8e,0xcf};        //定义常量数组数码管段选 code 0-15 p.
  40. uchar code wei[]={0xf7,0xfb,0xfd,0xfe};                                                                                                                                                //数码管位选

  41. uchar x,OP1,OP2,DOP2;        //定义运算符 + - * / = c
  42. uint tOP2,value1,value2;

  43. long uint adc;                                //定义长整数,不然出错

  44. void disduan(uchar dd)
  45. {
  46.         DA=dd>>7;DB=dd>>6&1;DC=dd>>5&1;DD=dd>>4&1;DE=dd>>3&1;DF=dd>>2&1;DG=dd>>1&1;DP=dd&1;
  47. }

  48. void diswei(uchar dw)
  49. {
  50.         B1=dw>>3&1;B2=dw>>2&1;B3=dw>>1&1;B4=dw&1;
  51. }

  52. void Delay1ms()                //@12.000MHz
  53. {
  54.     uchar i, j;

  55.     i = 12;
  56.     j = 169;
  57.     do
  58.     {
  59.         while (--j);
  60.     } while (--i);
  61. }

  62. void Delay50us()                //@12.000MHz
  63. {
  64.         unsigned char i, j;

  65.         i = 1;
  66.         j = 146;
  67.         do
  68.         {
  69.                 while (--j);
  70.         } while (--i);
  71. }

  72. void init()
  73. {
  74.     P2M0=0x1B;                        //P2强推挽0001 1011
  75.     P3M0=0xE4;                        //P3强推挽1110 0100
  76.         P1ASF=0x80;                        //开启P1^7引脚模拟功能
  77.        
  78.         key=255;
  79.         S1=0;                                //pwm引脚置零
  80.        
  81.         EA=1;                                //中断总开关
  82.         ET0=1;                                //定时器0开关
  83.         AUXR |= 0x80;                //定时器时钟1T模式
  84.         TMOD &= 0xF0;                //设置定时器模式
  85.         TL0 = 0x88;                        //设置定时初值                10us
  86.         TH0 = 0xFF;                        //设置定时初值
  87.         TR0 = 1;                        //定时器0开始计时
  88. }

  89. uint MAX6675_ReadReg(void)                //返回dat 0-65535 包含状态 温度值
  90. {
  91.         uchar i;   
  92.         uint dat; //     1111 1111 1111 1111
  93.          
  94.         i   = 0;   
  95.         dat = 0;   
  96.        
  97.         CS  = 0;                         //片选端,CS为低时、启动串行接口
  98.         SCK = 0;                     //串行时钟输出  6675收到低电平发送数据
  99.        
  100.         for(i=0; i<16; i++)                //get D15-D0 from 6675  从最高位开始接收16位数据
  101.         {      
  102.                 SCK = 1;                                //重置时钟
  103.                 dat = dat<<1;                        //dat左移一位,1111 1111 1111 1110
  104.                 if( SO==1 )          
  105.                         dat = dat|0x01;                //收到高电平,个位改为1
  106.                 SCK = 0;                                //发送时钟信号,准备接收下一位数据
  107.         }
  108.         CS = 1;   
  109.           
  110.         return dat;   //
  111. }

  112. void gettemp()
  113. {
  114.         if(count2==8)                                //256周期测一次温度,电压
  115.         {
  116.                 temp=MAX6675_ReadReg();                //读取状态数据0-65535     1111 1111 1111 1111 fedc ba98 7654 3210
  117.                 Flag_temp=(temp&4)>>2;        //读出数据的D2位是热电偶掉线标志位,该位为1表示掉线,该位为0表示连接 0000 0000 0000 0100
  118.                
  119.                 temp=((temp<<1)>>4)*5/2;        //读出来的数据的D3~D14是温度值 左移1位,右移4位 乘5/2 10倍温度值
  120.         }
  121. }

  122. void  getadc()
  123. {
  124.         if(count2==8)
  125.         {
  126.                 ADC_CONTR=0x8f;                                //开始ad转换 1000 1111
  127.                 Delay50us();                                //延时50us,等待转换
  128.                 adc=ADC_RES*4+ADC_RESL;                //读取转换结果 10位精度 0-1023
  129.         }
  130. }

  131. void getpwm()
  132. {
  133.         ADC_CONTR=0x8f;                                //开始ad转换 1000 1111
  134.         Delay50us();                                //延时50us,等待转换
  135.         adc=ADC_RES*4+ADC_RESL;                //读取转换结果 10位精度 0-1023
  136.        
  137.         adc=adc/10+100;                                        //100-202
  138.         if(adc>200)                                                //100-200
  139.                 adc=200;
  140. }

  141. void getkey()
  142. {
  143.         uchar i;
  144.        
  145.         if(count2%16==0)                                                //16ms检测一次mode键
  146.         {
  147.                 keyy1=0;                                                        //keyy1置零
  148.                 keynow[0]=keyx1;                                        //keynow状态等于keyx1
  149.                 keyy1=1;
  150.                 if(keynow[0]==0&&keyold[0]==1)
  151.                         key=0;
  152.                 keyold[0]=keynow[0];
  153.         }
  154.        
  155.         if(count2%16==0&&mode==1)                        //模式1时,16ms检测一次按键
  156.         {
  157.                 keyy1=0;
  158.                 keynow[0]=keyx1;
  159.                 keynow[1]=keyx2;
  160.                 keynow[2]=keyx3;
  161.                 keynow[3]=keyx4;
  162.                
  163.                 keyy1=1;keyy2=0;
  164.                 keynow[4]=keyx1;
  165.                 keynow[5]=keyx2;
  166.                 keynow[6]=keyx3;
  167.                 keynow[7]=keyx4;

  168.                 keyy2=1;keyy3=0;
  169.                 keynow[8]=keyx1;
  170.                 keynow[9]=keyx2;
  171.                 keynow[10]=keyx3;
  172.                 keynow[11]=keyx4;

  173.                 keyy3=1;keyy4=0;
  174.                 keynow[12]=keyx1;
  175.                 keynow[13]=keyx2;
  176.                 keynow[14]=keyx3;
  177.                 keynow[15]=keyx4;


  178.                 keyy4=1;keyy5=0;
  179.                 keynow[16]=keyx1;
  180.                 keynow[17]=keyx2;
  181.                 keynow[18]=keyx3;
  182.                 keynow[19]=keyx4;
  183.                 keyy5=1;
  184.                
  185.                 for(i=0;i<20;i++)
  186.                 {
  187.                         if(keynow[i]==0&&keyold[i]==1)
  188.                                 key=i;
  189.                        
  190.                         keyold[i]=keynow[i];
  191.                 }
  192.         }
  193. }

  194. void operation()
  195. {
  196.         if(count2%16==0)
  197.         {
  198.                 switch(key)
  199.                 {
  200.                         case 0:        key=255;mode++;if(mode==4){mode=0;S1=0;}break;//3个模式
  201.                         case 1:                break;
  202.                         case 2:                break;
  203.                         case 3:                break;
  204.                         case 4:        key=255;x=1;        break;
  205.                         case 5:        key=255;x=2;        break;
  206.                         case 6:        key=255;x=3;        break;
  207.                         case 7:        key=255;OP1=1;        break;        // +
  208.                         case 8:        key=255;x=4;        break;
  209.                         case 9:        key=255;x=5;        break;
  210.                         case 10:key=255;x=6;        break;
  211.                         case 11:key=255;OP1=2;        break;        // -
  212.                         case 12:key=255;x=7;        break;
  213.                         case 13:key=255;x=8;        break;
  214.                         case 14:key=255;x=9;        break;
  215.                         case 15:key=255;OP1=3;        break;        // *
  216.                         case 16:key=255;x=0;        break;
  217.                         case 17:key=255;OP2=1;        break;        // =
  218.                         case 18:key=255;OP2=2;        break;        // c
  219.                         case 19:key=255;OP1=4;        break;        // /
  220.                        
  221.                         default:        break;
  222.                 }
  223.                
  224.                 if(OP1==0&&x!=255)
  225.                 {
  226.                         value1=value1*10+x;
  227.                         x=255;
  228.                         value=value1;
  229.                 }
  230.                
  231.                 if(OP1!=0&&x!=255)
  232.                 {
  233.                         value2=value2*10+x;
  234.                         x=255;
  235.                         value=value2;
  236.                 }

  237.                 if(OP2==1)                                                        //输入 =
  238.                 {
  239.                         OP2=0;
  240.                        
  241.                         switch(OP1)
  242.                         {
  243.                                 case 1:        value=value1+value2;                break;
  244.                                 case 2:        value=value1-value2;                break;
  245.                                 case 3:        value=value1*value2;                break;
  246.                                 case 4:        value=value1/value2;                break;
  247.                                
  248.                                 default:        break;
  249.                         }
  250.                         OP1=OP2=DOP2=tOP2=value1=value2=0;
  251.                 }
  252.                
  253.                 if(DOP2==1)
  254.                         tOP2++;
  255.                 if(tOP2==30)
  256.                         DOP2=0;
  257.                 if(OP2==2&&DOP2==1)                                                //双击C清空所有数据
  258.                         OP1=OP2=DOP2=tOP2=value1=value2=value=0;
  259.                
  260.                 if(OP2==2)                                                                //单击C清除数据
  261.                 {
  262.                         OP2=0;
  263.                         DOP2=1;tOP2=0;
  264.                         if(OP1==0)
  265.                                 value=value1=0;
  266.                         else
  267.                                 value=value2=0;
  268.                 }
  269.         }
  270. }

  271. void display()
  272. {
  273.         if(mode==0)
  274.         {
  275.                 gettemp();
  276.                
  277.                 switch(count)                                        //显示温度
  278.                 {
  279.                         case 0:B4=1;disduan(duan[temp/1000]);        diswei(wei[count]);if(temp/1000==0) B1=1;break;                        //显示第1管 为0不显示
  280.                         case 1:B1=1;disduan(duan[temp/100%10]);        diswei(wei[count]);break;                                                                //显示第2管
  281.                         case 2:B2=1;disduan(duan[temp/10%10]);        diswei(wei[count]);DP=1;break;                                                        //显示第3管 带小数点
  282.                         case 3:B3=1;disduan(duan[temp%10]);                diswei(wei[count]);break;                                                                //显示第4管
  283.                        
  284.                         default: break;
  285.                 }
  286.         }
  287.        
  288.         if(mode==1)
  289.         {
  290.                 switch(count)                                        //显示按键
  291.                 {
  292.                         case 0:B4=1;if(value/1000==0) {B1=1;break;}        disduan(duan[value/1000]);                diswei(wei[count]);break;                        //显示第1管
  293.                         case 1:B1=1;if(value/100==0) {B2=1;break;}        disduan(duan[value/100%10]);        diswei(wei[count]);break;                        //显示第2管
  294.                         case 2:B2=1;if(value/10==0) {B3=1;break;}        disduan(duan[value/10%10]);                diswei(wei[count]);break;                        //显示第3管
  295.                         case 3:B3=1;                                                                disduan(duan[value%10]);                diswei(wei[count]);break;                        //显示第4管
  296.                        
  297.                         default: break;
  298.                 }
  299.         }
  300.        
  301.         if(mode==2)
  302.         {
  303.                 if(count2==8)
  304.                 {
  305.                         getadc();
  306.                         adc=adc*5000/1023;                        //1000倍电压值 adc*5v/1023*1000
  307.                 }
  308.                
  309.                 switch(count)                                        //显示电压
  310.                 {
  311.                         case 0:B4=1;disduan(duan[adc/1000]);        diswei(wei[count]);DP=1;break;                //显示第1管 带小数点
  312.                         case 1:B1=1;disduan(duan[adc/100%10]);        diswei(wei[count]);break;                        //显示第2管
  313.                         case 2:B2=1;disduan(duan[adc/10%10]);        diswei(wei[count]);break;                        //显示第3管       
  314.                         case 3:B3=1;disduan(duan[adc%10]);                diswei(wei[count]);break;                        //显示第4管       
  315.                        
  316.                         default: break;
  317.                 }
  318.         }
  319.        
  320.         while(mode==3)                                                                //模式3 pwm循环
  321.         {
  322.                 t0=0;
  323.                 S1=1;
  324.                 B4=1;disduan(duan[16]);diswei(wei[0]);//显示数码管1
  325.                 getpwm();                                                                //获取adc
  326.                
  327.                 while(t0!=adc);
  328.                 S1=0;
  329.                
  330.                 while(t0!=500);
  331.                 B1=1;disduan(duan[adc/100%10]);        diswei(wei[1]);//显示数码管2

  332.                
  333.                 while(t0!=1000);
  334.                 B2=1;disduan(duan[adc/10%10]);        diswei(wei[2]);//显示数码管3
  335.                
  336.                 while(t0!=1500);
  337.                 B3=1;disduan(duan[adc%10]);        diswei(wei[3]);//显示数码管4
  338.                
  339.                 while(t0!=1700);                                                        //检测mode按键
  340.                 keyy1=0;                                                        //keyy1置零
  341.                 keynow[0]=keyx1;                                        //keynow状态等于keyx1
  342.                 keyy1=1;
  343.                 if(keynow[0]==0&&keyold[0]==1)
  344.                         mode=0;                                                        //符合条件mode回零,跳出pwm模式循环
  345.                 keyold[0]=keynow[0];
  346.                
  347.                 while(t0!=2000);                                        //20ms一个周期
  348.         }
  349. }

  350. main()
  351. {
  352.         init();
  353.        
  354.     while(1)//
  355.     {
  356.                 Delay1ms();                                //系统周期1毫秒

  357.         count++;
  358.         if(count>3)
  359.             count=0;

  360.                 count2++;                                //0-255

  361.                 getkey();                                //运行一次80us  16ms运行一次
  362.                
  363.                 operation();

  364.                 display();
  365.     }
  366. }

  367. void Timert0() interrupt 1
  368. {
  369.                 t0++;                                //10us
  370. }
复制代码

数码管.zip

5.84 KB, 下载次数: 7, 下载积分: 牛币 -10

回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2018-7-31 21:00:19 | 显示全部楼层
coolbgo 发表于 2018-7-30 20:35
请教大神
为什么用定时器延时计数 定时器中断里t0++        用t0=0;while(t0

while(T0<1000) 当然不包括t0大于1000的情况
回复 支持 1 反对 1

使用道具 举报

发表于 2018-8-1 23:28:13 | 显示全部楼层
大师,单片机没有P5引脚接线的时候怎么办
回复 支持 1 反对 0

使用道具 举报

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

本版积分规则

QQ|关于模吧|APP下载|广告报价|小黑屋|手机版|企业会员|商城入驻|联系我们|模吧 ( 冀公网安备13080502000084号 )

© 2013-2020 Moz8.com 模吧,玩出精彩!