找回密码
 立即注册

QQ登录

只需一步,快速开始

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

STC89C52RC单片机+串口+红外控制16路舵机程序

[复制链接]
跳转到指定楼层
楼主
有程友给我留言说需要一个红外控制舵机的程序
但我没有直接控制舵机的,只有控制16路舵机的程序,现在发上来提供参考

舵机可以通过串口控制,也可以用红外控制(具体使用请看程序内备注)



单片机源程序如下:
  1. #include "PCA9685_TJ.h"
  2. #include <stdio.h>
  3. #include <math.h>

  4. /*使用说明:
  5.         在main主程序
  6.                 PCA9685_init();
  7.         在main主程序的while加入
  8.                 PCA9685_main();                        //注: 必需放在UART1_main();的前面
  9. */

  10. #define PCA9685_adrr 0x80//  1+A5+A4+A3+A2+A1+A0+w/r

  11. #define PCA9685_SUBADR1 0x2
  12. #define PCA9685_SUBADR2 0x3
  13. #define PCA9685_SUBADR3 0x4

  14. #define PCA9685_MODE1 0x0
  15. #define PCA9685_PRESCALE 0xFE

  16. #define LED0_ON_L 0x6
  17. #define LED0_ON_H 0x7
  18. #define LED0_OFF_L 0x8
  19. #define LED0_OFF_H 0x9

  20. #define ALLLED_ON_L 0xFA
  21. #define ALLLED_ON_H 0xFB
  22. #define ALLLED_OFF_L 0xFC
  23. #define ALLLED_OFF_H 0xFD
  24.   
  25. uchar mm,nn;
  26. uint SERV0;                //存储值

  27. /*---------------------------------------------------------------
  28.                  IIC初始化         
  29. ----------------------------------------------------------------*/
  30. void init()
  31. {
  32.         sda=1;                //sda scl使用前被拉高
  33.         delay100us(1);
  34.         scl=1;
  35.         delay100us(1);
  36. }

  37. /*---------------------------------------------------------------
  38.                  IIC启动
  39. ----------------------------------------------------------------*/
  40. void start()
  41. {
  42.         sda=1;
  43.         delay100us(1);
  44.         scl=1;       //scl高 sda拉低 IIC启动
  45.         delay100us(1);
  46.         sda=0;
  47.         delay100us(1);
  48.         scl=0;
  49.         delay100us(1);
  50. }
  51. /*---------------------------------------------------------------
  52.                  IIC停止
  53. ----------------------------------------------------------------*/
  54. void stop()
  55. {
  56.     sda=0;
  57.     delay100us(1);
  58.     scl=1;
  59.     delay100us(1);
  60.     sda=1;                  
  61.     delay100us(1);
  62. }
  63. /*---------------------------------------------------------------
  64.                  IIC应答
  65. ----------------------------------------------------------------*/
  66. void ACK()
  67. {
  68.         uchar i;
  69.         scl=1;
  70.         delay100us(1);
  71.         while((sda=1)&&(i<255)) {         
  72.                 i++;                     
  73.         }                  
  74.         scl=0;                                 
  75.         delay100us(1);
  76. }
  77. /*---------------------------------------------------------------
  78.               写字节
  79. ----------------------------------------------------------------*/
  80. void write_byte(uchar byte)
  81. {
  82.         uchar i,temp;
  83.         temp=byte;
  84.         for(i=0;i<8;i++)
  85.         {
  86.                 temp=temp<<1;  
  87.                 scl=0;                  
  88.                 delay100us(1);
  89.                 sda=CY;                 
  90.                 delay100us(1);
  91.                 scl=1;           
  92.                 delay100us(1);
  93.         }
  94.         scl=0;                  
  95.         delay100us(1);
  96.         sda=1;                 
  97.         delay100us(1);
  98. }
  99. /*---------------------------------------------------------------
  100.               读字节
  101. ----------------------------------------------------------------*/
  102. uchar read_byte()
  103. {
  104.         uchar i,j,k;
  105.         scl=0;
  106.         delay100us(1);
  107.         sda=1;
  108.         delay100us(1);
  109.         for(i=0;i<8;i++)        
  110.         {
  111.                 delay100us(1);
  112.                 scl=1;
  113.                 delay100us(1);
  114.                 if(sda==1)
  115.                 {
  116.                         j=1;
  117.                 }
  118.                 else j=0;
  119.                 k=(k<< 1)|j;  
  120.                 scl=0;            
  121.         }
  122.         delay100us(1);
  123.         return k;
  124. }
  125. /*---------------------------------------------------------------
  126.                 PCA9685
  127. ----------------------------------------------------------------*/
  128. /*---------------------------------------------------------------
  129.                写数据到PCA9685
  130. ----------------------------------------------------------------*/
  131. void PCA9685_write(uchar address,uchar date)
  132. {
  133.         start();
  134.         write_byte(PCA9685_adrr);
  135.         ACK();                          
  136.         write_byte(address);
  137.         ACK();
  138.         write_byte(date);
  139.         ACK();
  140.         stop();
  141. }
  142. /*---------------------------------------------------------------
  143.             从PCA9685读数据有返回值
  144. ----------------------------------------------------------------*/
  145. uchar PCA9685_read(uchar address)
  146. {
  147.         uchar date;
  148.         start();
  149.         write_byte(PCA9685_adrr);
  150.         ACK();
  151.         write_byte(address);
  152.         ACK();
  153.         start();
  154.         write_byte(PCA9685_adrr|0x01);
  155.         ACK();
  156.         date=read_byte();
  157.         stop();
  158.         return date;
  159. }
  160. /*---------------------------------------------------------------
  161.                         PCA9685复位
  162. ----------------------------------------------------------------*/
  163. void reset(void)
  164. {
  165.         PCA9685_write(PCA9685_MODE1,0x0);
  166. }


  167. void begin(void)
  168. {
  169.         reset();
  170. }
  171. /*---------------------------------------------------------------
  172.                  PCA9685修改频率
  173. ----------------------------------------------------------------*/
  174. void setPWMFreq(float freq)
  175. {
  176.         uint prescale,oldmode,newmode;
  177.         float prescaleval;
  178.         freq *= 0.92;  // Correct for overshoot in the frequency setting
  179.         prescaleval = 25000000;
  180.         prescaleval /= 4096;
  181.         prescaleval /= freq;
  182.         prescaleval -= 1;
  183.         prescale = floor(prescaleval + 0.5);
  184.         
  185.         oldmode = PCA9685_read(PCA9685_MODE1);
  186.         newmode = (oldmode&0x7F) | 0x10; // sleep
  187.         PCA9685_write(PCA9685_MODE1, newmode); // go to sleep
  188.         PCA9685_write(PCA9685_PRESCALE, prescale); // set the prescaler
  189.         PCA9685_write(PCA9685_MODE1, oldmode);
  190.         delay1ms(10);
  191.         PCA9685_write(PCA9685_MODE1, oldmode | 0xa1);
  192. }

  193. void setPWM(uint num, uint on, uint off)
  194. {
  195.         PCA9685_write(LED0_ON_L+4*num,on);
  196.         PCA9685_write(LED0_ON_H+4*num,on>>8);
  197.         PCA9685_write(LED0_OFF_L+4*num,off);
  198.         PCA9685_write(LED0_OFF_H+4*num,off>>8);
  199. }

  200. void PCA9685_init() {
  201.         init();                                //初始化
  202.         begin();                        //初始化
  203.         setPWMFreq(50);    //设置50hz

  204.         for(nn=0;nn<16;nn++) { //初始化
  205.                 setPWM(nn, 0, SERVOMAX);
  206.         }
  207. }

  208. void PCA9685_main() {
  209.         if(buf1[0]!=0x00 && cmd1==1){
  210.                 switch(buf1[0])
  211.                 {
  212.                         case 0x31:                        //串口输入1~
  213.                                 mm=0;break;      
  214.                         case 0x32:                        //串口输入2~
  215.                                 mm=1;break;
  216.                         case 0x33:                        //串口输入3~
  217.                                 mm=2;break;
  218.                         case 0x34:                        //串口输入4~
  219.                                 mm=3;break;
  220.                         case 0x35:                        //串口输入5~
  221.                                 mm=4;break;
  222.                         case 0x36:                        //串口输入6~
  223.                                 mm=5;break;
  224.                         case 0x37:                        //串口输入7~
  225.                                 mm=6;break;
  226.                         case 0x38:                        //串口输入8~
  227.                                 mm=7;break;
  228.                         case 0x39:                        //串口输入9~
  229.                                 mm=8;break;
  230.                         case 0x41:                        //串口输入A~
  231.                                 mm=9;break;
  232.                         case 0x42:                        //串口输入B~
  233.                                 mm=10;break;
  234.                         case 0x43:                        //串口输入C~
  235.                                 mm=11;break;
  236.                         case 0x44:                        //串口输入D~
  237.                                 mm=12;break;
  238.                         case 0x45:                        //串口输入E~
  239.                                 mm=13;break;
  240.                         case 0x46:                        //串口输入F~
  241.                                 mm=14;break;
  242.                         case 0x47:                        //串口输入G~
  243.                                 mm=15;break;                                
  244.                         default:break;  //接受到其它数据,蜂鸣器响         
  245.                 }
  246.                 if(SERV0==SERVO110){ SERV0=SERVOMAX; } else { SERV0=SERVO110; }
  247.                 setPWM(mm, 0, SERV0);
  248.                 mm=999;
  249.         }
  250. }
复制代码
全部资料51hei下载地址:
STC89C52RC+串口+红外控制16路舵机.zip (70.37 KB, 下载次数: 65)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:632112 发表于 2020-1-19 15:00 | 只看该作者
好东西,谢谢楼主分享
回复

使用道具 举报

板凳
ID:99114 发表于 2020-4-4 10:13 | 只看该作者
可以,我正好需要
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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