|
51控制PCA9685,使用軟件模擬IIC,都在代碼里了。
目的是為了控制16X舵機(jī),50HZ
單片機(jī)源程序如下:
- /* PCA9685驅(qū)動(dòng)程序 */
- /* 使用IO口模擬通信 */
- /* 16路PWM輸出 */
- #include<reg52.h>
- #include<intrins.h>
- sbit SCL=P1^0; //定義時(shí)鐘引腳
- sbit SDA=P1^1; //定義數(shù)據(jù)引腳
- #define PCA9685_adrr 0x80//1+A5+A4+A3+A2+A1+A0+w/r
- #define PCA9685_SUBADR1 0x2
- #define PCA9685_SUBADR2 0x3
- #define PCA9685_SUBADR3 0x4
- #define PCA9685_MODE1 0x0
- #define PCA9685_MODE2 0x1
- #define PCA9685_PRESCALE 0xFE
- #define pwm0_ON_L 0x6
- #define pwm0_ON_H 0x7
- #define pwm0_OFF_L 0x8
- #define pwm0_OFF_H 0x9
- #define ALLpwm_ON_L 0xFA
- #define ALLpwm_ON_H 0xFB
- #define ALLpwm_OFF_L 0xFC
- #define ALLpwm_OFF_H 0xFD
- void iic_delay()//延時(shí)5us
- {
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- }
- void iic_start()//scl高電平區(qū)間,sda一個(gè)下降沿啟動(dòng)信號(hào)
- {
- SDA=1;
- iic_delay();
- SCL=1;
- iic_delay();
- SDA=0;
- iic_delay();
- SCL=0;
- iic_delay();
- }
- void iic_stop()//scl在高電平區(qū)間,sda一個(gè)上升沿信號(hào)
- {
- SDA=0;
- iic_delay();
- SCL=1;
- iic_delay();
- SDA=1;
- iic_delay();
- }
- void iic_wait_ack()//在scl高位時(shí),從機(jī)拉低sda引腳表示應(yīng)答
- {
- unsigned char i=0;
- SCL=1;
- iic_delay();
- while((SDA==1)&&(i<255))
- {
- i++;
- }
- SCL=0;
- iic_delay();
- }
- void iic_init()//初始化IIC通訊引腳
- {
- SCL=1;
- iic_delay();
- SDA=1;
- iic_delay();
- }
- void iic_send_ack(bit iic_ack)//接受完成之后,發(fā)送應(yīng)答位,0應(yīng)答繼續(xù)發(fā)送,1不應(yīng)答停止發(fā)送
- {
- SDA=iic_ack;
- SCL=1;
- iic_delay();
- SCL=0;
- iic_delay();
- }
- void iic_write_byte(unsigned char iic_byte)
- {
- unsigned char i=0;
- for(i=0;i<8;i++)
- {
- SCL=0;
- iic_delay();
- SDA=iic_byte&0X80;
- iic_byte=iic_byte<<1;
- iic_delay();
- SCL=1;
- iic_delay();
- }
- SCL=0;
- iic_delay();
- SDA=1;
- iic_wait_ack();
- }
- void iic_write(unsigned char slave_addr,unsigned char iic_addr,unsigned char iic_byte)
- {
- iic_init();
- iic_start();
- iic_write_byte(slave_addr);
- iic_write_byte(iic_addr);
- iic_write_byte(iic_byte);
- iic_stop();
- }
- unsigned char iic_read_byte()//讀字節(jié),先讀高位,左移
- {
- unsigned char i=0;
- unsigned char iic_byte=0;
- SCL=0;
- iic_delay();
- SDA=1; //確保主機(jī)釋放SDA
- iic_delay();
- for(;i<8;i++)
- {
- iic_delay();
- SCL=1;
- iic_delay();
- iic_byte=(iic_byte<<1)|SDA;
- SCL=0;
- }
- iic_delay();
- return iic_byte;
- }
- unsigned char iic_read(unsigned char slave_addr,unsigned char iic_addr)
- {
- unsigned char iic_byte;
- iic_init();
- iic_start();
- iic_write_byte(slave_addr);
- iic_write_byte(iic_addr);
- iic_start();
- iic_write_byte(slave_addr|0x01);//發(fā)送設(shè)備地址+讀信號(hào)
- iic_byte=iic_read_byte();
- iic_send_ack(1);//發(fā)送非應(yīng)答信號(hào)
- iic_stop();
- return iic_byte;
- }
- void pca_set_freq()//頻率設(shè)置為50hz(20ms)
- {
- unsigned char prescale=132,oldmode,newmode;
- iic_write(0x80,0x00,0x0);
- oldmode=iic_read(0x80,0x00);
- newmode=(oldmode&0x7F)|0x10;
- iic_write(0x80,0x00,newmode);//進(jìn)入sleep
- //設(shè)置頻率時(shí)pca9685應(yīng)該進(jìn)入睡眠狀態(tài)
- iic_write(0x80,0xFE,prescale);
- iic_write(0x80,0x00,oldmode);//退出sleep
- iic_write(0x80,0x00,oldmode|0xA1);//立即重啟
- }
- void pca_set_pwm(unsigned char channel,unsigned char angle)
- {
- unsigned int off=102+(angle*2.27);
- iic_write(0x80,0x06+4*channel,0);
- iic_write(0x80,0x07+4*channel,0);
- iic_write(0x80,0x08+4*channel,off);
- iic_write(0x80,0x09+4*channel,off>>8);
- }
- void delay(unsigned char delay_a) //@11.0592MHz
- {
- while(delay_a)
- {
- unsigned char delay_b=255;
- while(delay_b)
- {
- iic_delay();
- iic_delay();
- delay_b--;
- }
- delay_a--;
- }
- }
- int main()
- {
- pca_set_freq();
- delay(155);
- pca_set_pwm(0,40);
- pca_set_pwm(1,40);
- delay(155);
- pca_set_pwm(0,140);
- pca_set_pwm(1,140);
- delay(155);
- pca_set_pwm(1,150);
- delay(155);
- pca_set_pwm(1,47);
- delay(155);
- pca_set_pwm(0,70);
- while(1);
- }
復(fù)制代碼
51_pca9685_iic.rar
(1.33 KB, 下載次數(shù): 63)
2019-8-19 19:57 上傳
點(diǎn)擊文件名下載附件
|
|