robot.c
#include "robot.h"
#include "delay.h"
/*
__________ __________ _________________
|1_____)0 4(______5|
|__| |left FRONT right| |__|
| |
| |
| |
_________ | | __________
|7_____)6 ___________ 2(______3|
|__| |__|
*/
void action(int num,int turn,int raise,u16 measure_time,bool move)
{
if(MOVE==move)
PCA_MG9XX(num+1,0,raise,1,1);//抬起
PCA_MG9XX(num,0,turn,1,1);//哪个,开始角度[默认0],结束角度,模式,速度
if(MOVE==move)
{
if(num==0)
PCA_MG9XX(num+1,0,NOR_LU_2,1,1);//放下
else if(num==6)
PCA_MG9XX(num+1,0,NOR_LD_2,1,1);
else if(num==2)
PCA_MG9XX(num+1,0,NOR_RD_2,1,1);
else
PCA_MG9XX(num+1,0,NOR_RU_2,1,1);
}
}
void home()
{
action(0,NOR_LU_1,NOR_LU_2,10,STILL);
action(2,NOR_RD_1,NOR_RD_2,10,STILL);
action(4,NOR_RU_1,NOR_RU_2,10,STILL);
action(6,NOR_LD_1,NOR_LD_2,10,STILL);
//左上脚0-90向前,90-120高度下降--0
//右下脚90-120向前,90-0高度下降--2//
//右上脚90-120向前,90-0高度下降--4
//左下脚0-90向前,90-120高度下降--6
}
void LowHome()//低姿态的原位置
{
PCA_MG9XX(0,0,NOR_LU_1,2,1);
PCA_MG9XX(2,0,NOR_RD_1,2,1);
PCA_MG9XX(4,0,NOR_RU_1,2,1);
PCA_MG9XX(6,0,NOR_LD_1,2,1);//锁定关节回归角度
delay_ms(50);
PCA_MG9XX(1,0,L_FUNUP,0,1);
PCA_MG9XX(3,0,R_FUNUP,0,1);
PCA_MG9XX(5,0,R_FUNUP,0,1);
PCA_MG9XX(7,0,L_FUNUP,0,1);
delay_ms(50);
}
void say_hello()//3,7可用
{
int i;
PCA_MG9XX(5,0,HELLO,0,0);
for(i=0;i<8;i++)
{
PCA_MG9XX(4,0,90,1,5);
delay_ms(20);
PCA_MG9XX(4,0,120,1,5);
delay_ms(20);
}
PCA_MG9XX(4,0,NOR_RU_1,0,0);
PCA_MG9XX(5,0,NOR_RU_2,0,0);
}
//蜉蝣形式
void swim()
{
action(0,WALK_F_L,L_UP,1,MOVE);
action(4,WALK_F_R4,R_UP,1,MOVE);
PCA_MG9XX(0,0,BACK_FL,1,10);//90
PCA_MG9XX(4,0,BACK_FL,1,10);
action(6,WALK_F_L4,UP_ADD,1,MOVE);
action(2,WALK_F_R,UP_DE,1,MOVE);
PCA_MG9XX(2,0,NOR_RD_1,1,10);//回归90度
PCA_MG9XX(6,0,NOR_LD_1,1,10);//回归90度
}
void DogWalk()//3---7//1--5
{
int i;
//前后腿锁定180
PCA_MG9XX(0,0,90,1,1);
PCA_MG9XX(2,0,90,1,1);
PCA_MG9XX(4,0,90,1,1);
PCA_MG9XX(6,0,90,1,1);//锁定内关节回归角度
PCA_MG9XX(1,0,90,1,1);
PCA_MG9XX(3,0,85,1,1);//弥补机械上的误差
PCA_MG9XX(5,0,90,1,1);
PCA_MG9XX(7,0,100,1,1);//锁定外关节回归角度
for(i=0;i<40;i++)
{
PCA_MG9XX(1,0,60,0,1);//1,5折叠
PCA_MG9XX(5,0,60,0,1);
delay_ms(50);
PCA_MG9XX(1,0,90,0,1);
PCA_MG9XX(5,0,90,0,1);
delay_ms(50);
PCA_MG9XX(3,0,55,0,1);//3,7
PCA_MG9XX(7,0,70,0,1);
delay_ms(50);
PCA_MG9XX(3,0,85,0,1);
PCA_MG9XX(7,0,100,0,1);
delay_ms(50);
//sportmini行走,有问题
// PCA_MG9XX(1,0,60,0,1);//1,3折叠
// PCA_MG9XX(3,0,55,0,1);
// delay_ms(50);
// PCA_MG9XX(1,0,90,0,1);
// PCA_MG9XX(3,0,85,0,1);
// delay_ms(50);
// PCA_MG9XX(5,0,60,0,1);//5,7
// PCA_MG9XX(7,0,70,0,1);
// delay_ms(50);
// PCA_MG9XX(5,0,90,0,1);
// PCA_MG9XX(7,0,100,0,1);
// delay_ms(50);
}
home();
}
void jump()//跳跃
{
//前后腿锁定180
int i;
PCA_MG9XX(0,0,90,1,1);
PCA_MG9XX(2,0,90,1,1);
PCA_MG9XX(4,0,90,1,1);
PCA_MG9XX(6,0,90,1,1);//锁定内关节回归角度
PCA_MG9XX(1,0,90,1,1);
PCA_MG9XX(3,0,85,1,1);//弥补机械上的误差
PCA_MG9XX(5,0,90,1,1);
PCA_MG9XX(7,0,100,1,1);//锁定外关节回归角度
for(i=0;i<50;i++)
{
// PCA_MG9XX(1,0,60,0,1);//1,7向内弯曲
// PCA_MG9XX(7,0,60,0,1);
// delay_ms(50);
// PCA_MG9XX(1,0,90,0,1);
// PCA_MG9XX(7,0,100,0,1);
// delay_ms(50);
// PCA_MG9XX(3,0,60,0,1);//3,5向外弯曲
// PCA_MG9XX(5,0,60,0,1);
// delay_ms(50);
// PCA_MG9XX(3,0,85,0,1);
// PCA_MG9XX(5,0,90,0,1);
// delay_ms(50);
PCA_MG9XX(1,0,60,0,1);//1,7向内弯曲
PCA_MG9XX(7,0,60,0,1);
delay_ms(50);
PCA_MG9XX(3,0,60,0,1);//3,5向外弯曲
PCA_MG9XX(5,0,60,0,1);
delay_ms(50);
PCA_MG9XX(1,0,90,0,1);
PCA_MG9XX(7,0,100,0,1);
PCA_MG9XX(3,0,85,0,1);
PCA_MG9XX(5,0,90,0,1);
delay_ms(50);
}
home();
}
void jog(int arg,bool dir)//小跑
{
if(FORWARD==dir)
{
//两脚支撑
PCA_MG9XX(1,0,L_UP,0,1);//抬脚
PCA_MG9XX(3,0,UP_DE,0,1);
delay_ms(30);
PCA_MG9XX(0,0,60-arg,0,1);//转动 WALK_F_L
PCA_MG9XX(2,0,60+arg,0,1);//WALK_F_R
delay_ms(30);
PCA_MG9XX(1,0,NOR_LU_2,0,1);//放脚
PCA_MG9XX(3,0,NOR_RD_2,0,1);
delay_ms(30);
PCA_MG9XX(0,0,NOR_LU_1,0,1);//转动20--90 BACK_FL
PCA_MG9XX(2,0,NOR_RD_1,0,1);//40//100--60
delay_ms(30);
PCA_MG9XX(5,0,R_UP,0,1);//抬脚
PCA_MG9XX(7,0,UP_ADD,0,1);
delay_ms(30);
PCA_MG9XX(4,0,120+arg,0,1);//转动WALK_F_R4 160
PCA_MG9XX(6,0,120-arg,0,1);//WALK_F_L4 80
delay_ms(30);
PCA_MG9XX(5,0,NOR_RU_2,0,1);//放脚
PCA_MG9XX(7,0,NOR_LD_2,0,1);
delay_ms(30);
PCA_MG9XX(4,0,NOR_RU_1,0,1);//转动 BACK_FL
PCA_MG9XX(6,0,NOR_LD_1,0,1);
delay_ms(30);
}else
{
//两脚支撑
PCA_MG9XX(1,0,L_UP,0,1);//抬脚
PCA_MG9XX(3,0,UP_DE,0,1);
delay_ms(30);
PCA_MG9XX(0,0,60+arg,0,1);//转动 WALK_F_L
PCA_MG9XX(2,0,60-arg,0,1);//WALK_F_R
delay_ms(30);
PCA_MG9XX(1,0,NOR_LU_2,0,1);//放脚
PCA_MG9XX(3,0,NOR_RD_2,0,1);
delay_ms(30);
PCA_MG9XX(0,0,NOR_LU_1,0,1);//转动20--90 BACK_FL
PCA_MG9XX(2,0,NOR_RD_1,0,1);//40//100--60
delay_ms(30);
PCA_MG9XX(5,0,R_UP,0,1);//抬脚
PCA_MG9XX(7,0,UP_ADD,0,1);
delay_ms(30);
PCA_MG9XX(4,0,120-arg,0,1);//转动WALK_F_R4 160
PCA_MG9XX(6,0,120+arg,0,1);//WALK_F_L4 80
delay_ms(30);
PCA_MG9XX(5,0,NOR_RU_2,0,1);//放脚
PCA_MG9XX(7,0,NOR_LD_2,0,1);
delay_ms(30);
PCA_MG9XX(4,0,NOR_RU_1,0,1);//转动 BACK_FL
PCA_MG9XX(6,0,NOR_LD_1,0,1);
delay_ms(30);
}
}
void walk(int turn,int raise,bool dir)//0--2--4--6//蜘蛛单步缓慢走
{
int i;
//左上脚60度以下向前,90-120高度下降--0
//右下脚60度以上向前,90-0高度下降--2//
//右上脚120以上向前,90-0高度下降--4
//左下脚120以下向前,90-120高度下降--6
for(i=0;i<30;i++)
{
if(FORWARD==dir)
{
action(0,WALK_F_L,L_UP,1,MOVE);//1腿迈出
PCA_MG9XX(0,0,BACK_FL,1,1);//90//1腿回来
action(2,WALK_F_R,UP_DE,1,MOVE);
PCA_MG9XX(2,0,NOR_RD_1,1,1);//回归90度
action(4,WALK_F_R4,R_UP,1,MOVE);
PCA_MG9XX(4,0,BACK_FL,1,1);
action(6,WALK_F_L4,UP_ADD,1,MOVE);
PCA_MG9XX(6,0,NOR_LD_1,1,1);//回归90度
}else
{
}
}
}
void Turn(int arg,bool dir)//0--6--2--4
{
if(LEFT==dir)
{
//测试内调---完美
PCA_MG9XX(1,0,L_UP,0,1);//抬脚
PCA_MG9XX(3,0,UP_DE,0,1);
delay_ms(30);
PCA_MG9XX(0,0,60+arg,0,1);//转动 TURN_B_L1
PCA_MG9XX(2,0,60+arg,0,1);//TURN_F_R2
delay_ms(30);
PCA_MG9XX(1,0,NOR_LU_2,0,1);//放脚
PCA_MG9XX(3,0,NOR_RD_2,0,1);
delay_ms(30);
PCA_MG9XX(5,0,R_UP,0,1);//抬脚
PCA_MG9XX(7,0,UP_ADD,0,1);
delay_ms(30);
PCA_MG9XX(4,0,120+arg,0,1);//转动 TURN_F_R1
PCA_MG9XX(6,0,120+arg,0,1);//TURN_B_L2
delay_ms(30);
PCA_MG9XX(5,0,NOR_RU_2,0,1);//放脚
PCA_MG9XX(7,0,NOR_LD_2,0,1);
delay_ms(30);
PCA_MG9XX(0,0,NOR_LU_1,0,1);//转动
PCA_MG9XX(2,0,NOR_RD_1,0,1);
PCA_MG9XX(4,0,NOR_RU_1,0,1);//转动
PCA_MG9XX(6,0,NOR_LD_1,0,1);
delay_ms(60);
}else//0--6--2--4
{
PCA_MG9XX(1,0,L_UP,0,1);//抬脚
PCA_MG9XX(3,0,UP_DE,0,1);
delay_ms(30);
PCA_MG9XX(0,0,60-arg,0,1);//转动 TURN_F_L1
PCA_MG9XX(2,0,60-arg,0,1);//TURN_B_R2
delay_ms(30);
PCA_MG9XX(1,0,NOR_LU_2,0,1);//放脚
PCA_MG9XX(3,0,NOR_RD_2,0,1);
delay_ms(30);
PCA_MG9XX(5,0,R_UP,0,1);//抬脚
PCA_MG9XX(7,0,UP_ADD,0,1);
delay_ms(30);
PCA_MG9XX(4,0,60+arg,0,1);//转动TURN_B_R1
PCA_MG9XX(6,0,60+arg,0,1);//TURN_F_L2
delay_ms(30);
PCA_MG9XX(5,0,NOR_RU_2,0,1);//放脚
PCA_MG9XX(7,0,NOR_LD_2,0,1);
delay_ms(30);
PCA_MG9XX(0,0,NOR_LU_1,0,1);//转动
PCA_MG9XX(2,0,NOR_RD_1,0,1);
PCA_MG9XX(4,0,NOR_RU_1,0,1);//转动
PCA_MG9XX(6,0,NOR_LD_1,0,1);
delay_ms(60);
}
}
void up_down()//0--6--2--4
{
int i;
PCA_MG9XX(0,0,NOR_LU_1,2,1);
PCA_MG9XX(2,0,NOR_RD_1,2,1);
PCA_MG9XX(4,0,NOR_RU_1,2,1);
PCA_MG9XX(6,0,NOR_LD_1,2,1);//锁定关节回归角度
for(i=0;i<15;i++)
{
//左上脚60度以下向前,90-120高度下降--0
//右下脚60度以上向前,90-0高度下降--2//
//右上脚120以上向前,90-0高度下降--4
//左下脚120以下向前,90-120高度下降--6
PCA_MG9XX(1,0,L_FUNUP,0,1);
PCA_MG9XX(3,0,R_FUNUP,0,1);
PCA_MG9XX(5,0,R_FUNUP,0,1);
PCA_MG9XX(7,0,L_FUNUP,0,1);//锁定关节回归角度
delay_ms(150);
PCA_MG9XX(1,0,120,0,1);
PCA_MG9XX(3,0,60,0,1);
PCA_MG9XX(5,0,60,0,1);
PCA_MG9XX(7,0,120,0,1);//锁定关节回归角度
delay_ms(150);
}
home();
}
void Akid()
{
int i;
LowHome();
//轮流上下
for(i=0;i<15;i++)
{
PCA_MG9XX(1,0,L_FUNUP,1,10);
delay_ms(50);
PCA_MG9XX(1,0,130,1,10);
delay_ms(50);
PCA_MG9XX(3,0,R_FUNUP,1,10);
delay_ms(50);
PCA_MG9XX(3,0,50,1,10);
delay_ms(50);
PCA_MG9XX(5,0,R_FUNUP,1,10);
delay_ms(50);
PCA_MG9XX(5,0,50,1,10);
delay_ms(50);
PCA_MG9XX(7,0,L_FUNUP,1,10);//锁定关节回归角度
delay_ms(50);
PCA_MG9XX(7,0,130,1,10);//锁定关节回归角度
delay_ms(50);
}
}
//void Spider::wiring()
//{
//
//}
robot.h
#ifndef __ROBOT_HPP
#define __ROBOT_HPP
#include "stm32_pca9685.h"
#include "delay.h"
#include "sys.h"
/*
__________ __________ _________________
|1_____)0 4(______5|
|__| |left FRONT right| |__|
| |
| |
| |
_________ | | __________
|7_____)6 ___________ 2(______3|
|__| |__|
*/
typedef enum _BOOL
{
false,
true
}bool;
#define NOR_LU_1 60 //左上1关节常态
#define NOR_LU_2 90//105///0
#define NOR_LD_1 120
#define NOR_LD_2 100//1086
#define NOR_RU_1 120
#define NOR_RU_2 90//72//4
#define NOR_RD_1 60
#define NOR_RD_2 85//78//2
#define BACK_FL 90
#define BACK_FR 90
//行走步距50
#define WALK_F_L 20//左向前60-15
#define WALK_F_R 100//右向前---2[原态60]
#define WALK_F_L4 80//左向前
#define WALK_F_R4 160///120+15
//转向
//左转
#define TURN_B_L1 90//左上脚向后 0
#define TURN_B_L2 150//左下脚向后 6
#define TURN_F_R2 90//右下脚向前 2
#define TURN_F_R1 150//右上脚向前 4
//右转
#define TURN_F_L1 30//左上脚向前 0
#define TURN_F_L2 90//左下脚向前 6
#define TURN_B_R1 90//右上脚向后 4
#define TURN_B_R2 30//右下脚向后 2
//抬脚放脚使用
#define L_UP 120//130//普通情况使用
#define L_DOWN 90//108//支撑
#define UP_ADD 130//直立加了10的特殊情况使用
#define DOWN_ADD 95
#define UP_DE 55//右下角使用
#define DOWN_DE 85
#define L_FUNUP 160
#define R_FUNUP 20
#define L_FUNDOWN 90
#define R_FUNDOWN 90
#define R_UP 60//50//抬起
#define R_DOWN 90//72//支撑
#define HELLO 40
#define FLY_BACK 90//关节回归角度
#define FORWARD true
#define BACK false
#define MOVE true
#define STILL false
#define LEFT true
#define RIGHT false
void home(void);//原位置
void LowHome(void);
void action(int num,int turn,int raise,u16 measure_time,bool move);//某一条腿的封装
void walk(int turn,int raise,bool dir);//前进
void Turn(int arg,bool dir);//转向
void up_down(void);//原地上下
void say_hello(void);//打招呼
void swim(void);//浮游前进
void jump(void);//跳跃
void jog(int arg,bool dir);//小跑
void stroll(void);//踱步
void DogWalk(void);//小狗形态行走
void wiring(void);//腿轮流扭动
void Akid(void);//像小孩子一样调皮
#endif
pca9685.c
#include "stm32_pca9685.h"
#include "delay.h"
#include "math.h"
void pca_write(u8 adrr,u8 data)//向PCA写数据,adrrd地址,data数据
{
IIC_Start();
IIC_Send_Byte(pca_adrr);
IIC_Wait_Ack();
IIC_Send_Byte(adrr);
IIC_Wait_Ack();
IIC_Send_Byte(data);
IIC_Wait_Ack();
IIC_Stop();
}
u8 pca_read(u8 adrr)//从PCA读数据
{
u8 data;
IIC_Start();
IIC_Send_Byte(pca_adrr);
IIC_Wait_Ack();
IIC_Send_Byte(adrr);
IIC_Wait_Ack();
IIC_Start();
IIC_Send_Byte(pca_adrr|0x01);
IIC_Wait_Ack();
data=IIC_Read_Byte(0);
IIC_Stop();
return data;
}
void pca_setfreq(float freq)//设置PWM频率
{
u8 prescale,oldmode,newmode;
double prescaleval;
freq *= 0.92;
prescaleval = 25000000;
prescaleval /= 4096;
prescaleval /= freq;
prescaleval -= 1;
prescale =floor(prescaleval + 0.5f);
oldmode = pca_read(pca_mode1);
newmode = (oldmode&0x7F) | 0x10; // sleep
pca_write(pca_mode1, newmode); // go to sleep
pca_write(pca_pre, prescale); // set the prescaler
pca_write(pca_mode1, oldmode);
delay_ms(2);
pca_write(pca_mode1, oldmode | 0xa1);
}
/*num:舵机PWM输出引脚0~15,on:PWM上升计数值0~4096,off:PWM下降计数值0~4096
一个PWM周期分成4096份,由0开始+1计数,计到on时跳变为高电平,继续计数到off时
跳变为低电平,直到计满4096重新开始。所以当on不等于0时可作延时,当on等于0时,
off/4096的值就是PWM的占空比。*/
void pca_setpwm(u8 num, u32 on, u32 off)
{
pca_write(LED0_ON_L+4*num,on);
pca_write(LED0_ON_H+4*num,on>>8);
pca_write(LED0_OFF_L+4*num,off);
pca_write(LED0_OFF_H+4*num,off>>8);
}
/*
函数作用:初始化舵机驱动板
参数:1.PWM频率
2.初始化舵机角度
*/
void PCA_MG9XX_Init(float hz,u8 angle)
{
u32 off=0;
IIC_Init();
pca_write(pca_mode1,0x0);
pca_setfreq(hz);//设置PWM频率
off=(u32)(145+angle*2.4);
pca_setpwm(0,0,off);pca_setpwm(1,0,off);pca_setpwm(2,0,off);pca_setpwm(3,0,off);
pca_setpwm(4,0,off);pca_setpwm(5,0,off);pca_setpwm(6,0,off);pca_setpwm(7,0,off);
pca_setpwm(8,0,off);pca_setpwm(9,0,off);pca_setpwm(10,0,off);pca_setpwm(11,0,off);
pca_setpwm(12,0,off);pca_setpwm(13,0,off);pca_setpwm(14,0,off);pca_setpwm(15,0,off);
delay_ms(500);
}
/*
函数作用:控制舵机转动;
参数:1.输出端口,可选0~15;
2.起始角度,可选0~180;
3.结束角度,可选0~180;
4.模式选择,0 表示函数内无延时,调用时需要在函数后另外加延时函数,且不可调速,第五个参数可填任意值;
1 表示函数内有延时,调用时不需要在函数后另外加延时函数,且不可调速,第五个参数可填任意值;
2 表示速度可调,第五个参数表示速度值;
5.速度,可填大于 0 的任意值,填 1 时速度最快,数值越大,速度越小;
注意事项:模式 0和1 的速度比模式 2 的最大速度大;
*/
void PCA_MG9XX(u8 num,u8 start_angle,u8 end_angle,u8 mode,u8 speed)
{
u8 i;
u32 off=0;
switch(mode)
{
case 0:
off=(u32)(158+end_angle*2.2);
pca_setpwm(num,0,off);
break;
case 1:
off=(u32)(158+end_angle*2.2);
pca_setpwm(num,0,off);
if(end_angle>start_angle){delay_ms((u16)((end_angle-start_angle)*2.7));}
else{delay_ms((u16)((start_angle-end_angle)*2.7));}
break;
case 2:
if(end_angle>start_angle)
{
for(i=start_angle;i<=end_angle;i++)
{
off=(u32)(158+i*2.2);
pca_setpwm(num,0,off);
delay_ms(2);
delay_us(speed*250);
}
}
else if(start_angle>end_angle)
{
for(i=start_angle;i>=end_angle;i--)
{
off=(u32)(158+i*2.2);
pca_setpwm(num,0,off);
delay_ms(2);
delay_us(speed*250);
}
}
break;
}
}
//----------------
//初始化IIC
void IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); //使能GPIOB时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_8|GPIO_Pin_9); //PB6,PB7 输出高
}
//产生IIC起始信号
void IIC_Start(void)
{
SDA_OUT(); //sda线输出
IIC_SDA=1;
IIC_SCL=1;
delay_us(4);
IIC_SDA=0;//START:when CLK is high,DATA change form high to low
delay_us(4);
IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
}
//产生IIC停止信号
void IIC_Stop(void)
{
SDA_OUT();//sda线输出
IIC_SCL=0;
IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
delay_us(4);
IIC_SCL=1;
IIC_SDA=1;//发送I2C总线结束信号
delay_us(4);
}
//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
u8 IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
SDA_IN(); //SDA设置为输入
IIC_SDA=1;delay_us(1);
IIC_SCL=1;delay_us(1);
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL=0;//时钟输出0
return 0;
}
//产生ACK应答
void IIC_Ack(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=0;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
//不产生ACK应答
void IIC_NAck(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
void IIC_Send_Byte(u8 txd)
{
u8 t;
SDA_OUT();
IIC_SCL=0;//拉低时钟开始数据传输
for(t=0;t<8;t++)
{
IIC_SDA=(txd&0x80)>>7;
txd<<=1;
delay_us(2); //对TEA5767这三个延时都是必须的
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
delay_us(2);
}
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
u8 IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
IIC_SCL=0;
delay_us(2);
IIC_SCL=1;
receive<<=1;
if(READ_SDA)receive++;
delay_us(1);
}
if (!ack)
IIC_NAck();//发送nACK
else
IIC_Ack(); //发送ACK
return receive;
}
pca9685.h
#ifndef __STM32PCA9685_H
#define __STM32PCA9685_H
#include "stm32f10x.h"
#define pca_adrr 0x80
#define pca_mode1 0x0
#define pca_pre 0xFE
#define LED0_ON_L 0x6
#define LED0_ON_H 0x7
#define LED0_OFF_L 0x8
#define LED0_OFF_H 0x9
#define jdMIN 115 // minimum
#define jdMAX 590 // maximum
#define jd000 130 //0度对应4096的脉宽计数值
#define jd180 520 //180度对应4096的脉宽计算值
//IO方向设置
#define SDA_IN() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}
#define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}
//IO操作函数
#define IIC_SCL PBout(6) //SCL
#define IIC_SDA PBout(7) //SDA
#define READ_SDA PBin(7 ) //输入SDA
void pca_write(u8 adrr,u8 data);
u8 pca_read(u8 adrr);
void PCA_MG9XX_Init(float hz,u8 angle);
void pca_setfreq(float freq);
void pca_setpwm(u8 num, u32 on, u32 off);
void PCA_MG9XX(u8 num,u8 start_angle,u8 end_angle,u8 mode,u8 speed);
//IIC所有操作函数
void IIC_Init(void); //初始化IIC的IO口
void IIC_Start(void); //发送IIC开始信号
void IIC_Stop(void); //发送IIC停止信号
void IIC_Send_Byte(u8 txd); //IIC发送一个字节
u8 IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
u8 IIC_Wait_Ack(void); //IIC等待ACK信号
void IIC_Ack(void); //IIC发送ACK信号
void IIC_NAck(void); //IIC不发送ACK信号
#endif