单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 203|回复: 0
收起左侧

51单片机控制PCA9685源程序

[复制链接]
LYC0512 发表于 2019-8-19 19:58 | 显示全部楼层 |阅读模式
51控制PCA9685,使用软件模拟IIC,都在代码里了。
目的是为了控制16X舵机,50HZ
单片机源程序如下:
  1. /*        PCA9685驱动程序        */
  2. /*        使用IO口模拟通信        */
  3. /*        16路PWM输出                        */
  4. #include<reg52.h>           
  5. #include<intrins.h>

  6. sbit SCL=P1^0;                //定义时钟引脚
  7. sbit SDA=P1^1;                //定义数据引脚

  8. #define PCA9685_adrr 0x80//1+A5+A4+A3+A2+A1+A0+w/r
  9. #define PCA9685_SUBADR1 0x2
  10. #define PCA9685_SUBADR2 0x3
  11. #define PCA9685_SUBADR3 0x4
  12. #define PCA9685_MODE1 0x0
  13. #define PCA9685_MODE2 0x1
  14. #define PCA9685_PRESCALE 0xFE
  15. #define pwm0_ON_L 0x6
  16. #define pwm0_ON_H 0x7
  17. #define pwm0_OFF_L 0x8
  18. #define pwm0_OFF_H 0x9
  19. #define ALLpwm_ON_L 0xFA
  20. #define ALLpwm_ON_H 0xFB
  21. #define ALLpwm_OFF_L 0xFC
  22. #define ALLpwm_OFF_H 0xFD

  23. void iic_delay()//延时5us
  24. {
  25.         _nop_();
  26.         _nop_();
  27.         _nop_();
  28.         _nop_();
  29.         _nop_();
  30. }
  31. void iic_start()//scl高电平区间,sda一个下降沿启动信号
  32. {
  33.         SDA=1;
  34.         iic_delay();
  35.         SCL=1;
  36.         iic_delay();
  37.         SDA=0;
  38.         iic_delay();
  39.         SCL=0;
  40.         iic_delay();
  41. }
  42. void iic_stop()//scl在高电平区间,sda一个上升沿信号
  43. {
  44.         SDA=0;
  45.         iic_delay();
  46.         SCL=1;
  47.         iic_delay();
  48.         SDA=1;
  49.         iic_delay();
  50. }
  51. void iic_wait_ack()//在scl高位时,从机拉低sda引脚表示应答
  52. {
  53.         unsigned char i=0;
  54.         SCL=1;
  55.         iic_delay();
  56.         while((SDA==1)&&(i<255))
  57.         {
  58.                 i++;
  59.         }
  60.         SCL=0;
  61.         iic_delay();
  62. }
  63. void iic_init()//初始化IIC通讯引脚
  64. {
  65.         SCL=1;
  66.         iic_delay();
  67.         SDA=1;
  68.         iic_delay();
  69. }
  70. void iic_send_ack(bit iic_ack)//接受完成之后,发送应答位,0应答继续发送,1不应答停止发送
  71. {
  72.         SDA=iic_ack;
  73.         SCL=1;
  74.         iic_delay();
  75.         SCL=0;
  76.         iic_delay();
  77. }
  78. void iic_write_byte(unsigned char iic_byte)
  79. {
  80.         unsigned char i=0;
  81.         for(i=0;i<8;i++)
  82.         {
  83.                 SCL=0;
  84.                 iic_delay();
  85.                 SDA=iic_byte&0X80;
  86.                 iic_byte=iic_byte<<1;
  87.                 iic_delay();
  88.                 SCL=1;
  89.                 iic_delay();
  90.         }
  91.         SCL=0;
  92.         iic_delay();
  93.         SDA=1;
  94.         iic_wait_ack();
  95. }
  96. void iic_write(unsigned char slave_addr,unsigned char iic_addr,unsigned char iic_byte)
  97. {
  98.         iic_init();
  99.         iic_start();
  100.         iic_write_byte(slave_addr);
  101.         iic_write_byte(iic_addr);
  102.         iic_write_byte(iic_byte);
  103.         iic_stop();
  104. }
  105. unsigned char iic_read_byte()//读字节,先读高位,左移
  106. {
  107.         unsigned char i=0;
  108.         unsigned char iic_byte=0;
  109.         SCL=0;
  110.         iic_delay();
  111.         SDA=1;                                                                                        //确保主机释放SDA
  112.         iic_delay();
  113.         for(;i<8;i++)
  114.         {
  115.                 iic_delay();
  116.                 SCL=1;
  117.                 iic_delay();
  118.                 iic_byte=(iic_byte<<1)|SDA;
  119.                 SCL=0;
  120.         }
  121.         iic_delay();
  122.         return iic_byte;
  123. }
  124. unsigned char iic_read(unsigned char slave_addr,unsigned char iic_addr)
  125. {
  126.         unsigned char iic_byte;
  127.         iic_init();
  128.         iic_start();
  129.         iic_write_byte(slave_addr);
  130.         iic_write_byte(iic_addr);
  131.         iic_start();
  132.         iic_write_byte(slave_addr|0x01);//发送设备地址+读信号
  133.         iic_byte=iic_read_byte();
  134.         iic_send_ack(1);//发送非应答信号
  135.         iic_stop();
  136.         return iic_byte;
  137. }
  138. void pca_set_freq()//频率设置为50hz(20ms)
  139. {
  140.         unsigned char prescale=132,oldmode,newmode;
  141.         iic_write(0x80,0x00,0x0);
  142.         oldmode=iic_read(0x80,0x00);
  143.         newmode=(oldmode&0x7F)|0x10;
  144.         iic_write(0x80,0x00,newmode);//进入sleep
  145.                                                                                                                          //设置频率时pca9685应该进入睡眠状态
  146.         iic_write(0x80,0xFE,prescale);
  147.         iic_write(0x80,0x00,oldmode);//退出sleep
  148.         iic_write(0x80,0x00,oldmode|0xA1);//立即重启
  149. }
  150. void pca_set_pwm(unsigned char channel,unsigned char angle)
  151. {
  152.         unsigned int off=102+(angle*2.27);
  153.         iic_write(0x80,0x06+4*channel,0);
  154.         iic_write(0x80,0x07+4*channel,0);
  155.         iic_write(0x80,0x08+4*channel,off);
  156.         iic_write(0x80,0x09+4*channel,off>>8);
  157. }
  158. void delay(unsigned char delay_a)                //@11.0592MHz
  159. {
  160.         while(delay_a)
  161.         {
  162.                 unsigned char delay_b=255;
  163.                 while(delay_b)
  164.                 {
  165.                         iic_delay();
  166.                         iic_delay();
  167.                         delay_b--;
  168.                 }
  169.                 delay_a--;
  170.         }
  171. }
  172. int main()
  173. {
  174.         pca_set_freq();
  175.         delay(155);
  176.         pca_set_pwm(0,40);
  177.         pca_set_pwm(1,40);
  178.         delay(155);
  179.         pca_set_pwm(0,140);
  180.         pca_set_pwm(1,140);
  181.         delay(155);
  182.         pca_set_pwm(1,150);
  183.         delay(155);
  184.         pca_set_pwm(1,47);
  185.         delay(155);
  186.         pca_set_pwm(0,70);
  187.         while(1);
  188. }
复制代码

51_pca9685_iic.rar (1.33 KB, 下载次数: 3)
回复

使用道具 举报

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

本版积分规则

QQ|手机版|小黑屋|单片机论坛 |51Hei单片机16群 联系QQ:125739409;技术交流QQ群7344883

Powered by 单片机教程网

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