IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 单片机智能小车 -> 正文阅读

[嵌入式]单片机智能小车

单片机智能小车

项目完整效果:

自制超强功能单片机智能小车

mc6c遥控器控制

/*
I/O -> P3^2(INT0)
*/

#include<reg52.h>
#include<intrins.h>
#define SIGNAL_THRESHOLD 1382	//1382
#define ERROR_RANGE 10	//184

sbit signal=P3^2;
sbit IN1=P1^0;
sbit IN2=P1^1;
sbit IN3=P1^2;
sbit IN4=P1^3;

unsigned int signal_time;

void init_Timer0(void);
void Timer0_process(void);
void init_Interrupt0(void);
void Interrupt0_process(void);
void forward(void);
void backward(void);
void stop(void);

void main(void)
{	
	init_Timer0();
	init_Interrupt0();
	while(1)
	{
			if(signal==0)
				TR0=1;
			if((signal_time<SIGNAL_THRESHOLD+ERROR_RANGE)&&(signal_time>SIGNAL_THRESHOLD-ERROR_RANGE))
			{
				stop();
			}
			else
			{
				signal_time>SIGNAL_THRESHOLD+ERROR_RANGE?	forward() : backward();
			}
	}
}

void init_Timer0(void)
{
	TMOD=0x09;
	TH0=0x00;
	TL0=0x00;
	ET0=1;
	//TR0=1;
}

void init_Interrupt0(void)
{
	EA=1;
	EX0=1;
	IT0=1;// 2?è·?¨
}

void Timer0_process(void)	interrupt 1
{
	TH0=0x00;
	TL0=0x00;
	//TR0=1;
}

void Interrupt0_process(void)	interrupt 0
{
	signal_time=0;
	signal_time|=TH0;
	signal_time<<=8;
	signal_time|=TL0;
	TH0=0x00;
	TL0=0x00;
}

void forward(void)
{
	IN1=0;
	IN2=1;
	IN3=0;
	IN4=0;
}

void backward(void)
{
	IN1=1;
	IN2=0;
	IN3=0;
	IN4=1;
}

void stop(void)
{
	IN1=1;
	IN2=1;
	IN3=1;
	IN4=1;
}

红外协议控制

#include<reg52.h>
#include<intrins.h>

sbit IN1=P1^0;
sbit IN2=P1^1;
sbit IN3=P1^2;
sbit IN4=P1^3;

sbit servo_port=P2^7;									
#define INITIAL_angle 15							
#define BIAS_ANGLE 2									
#define LEFT_ANGLE INITIAL_angle-BIAS_ANGLE
#define RIGHT_ANGLE INITIAL_angle+BIAS_ANGLE

unsigned char status_flag;//0x00=forward,0x01=backward,0x02=left,0x03=right,0x04=brake

unsigned char irtime;
bit irpro_ok,ir_ok;
unsigned char IRcode[4],IRdata[33];

void servo(unsigned char t);	//5<=t<=25  %200
void delay_servo(unsigned char _100us_count);   //error=-0.173611111111us
void delay(void);   //error = -0.000000000018us
void backward(void);
void forward(void);
void left(void);
void right(void);
void brake(void);
void TIME0init(void);
void EX0init();
void TIME0_interrupt(void); 
void EX0_interrupt(void);
void Ir_work(void);
void Ircodepro(void);
void initial_status_test(void);



void main(void)
{
	EX0init();
	TIME0init();
	initial_status_test();
	while(1)
	{
		if(ir_ok)
		{
			Ircodepro();
			ir_ok=0;
		}

		if(irpro_ok)
		{
		 	Ir_work();
			irpro_ok=0;
		}
	}
}

void initial_status_test(void)
{
	servo(INITIAL_angle);	//???ú1é??
	servo(INITIAL_angle);	//???ú1é??
	forward();
	delay();
	delay();
	brake();
	backward();
	delay();
	delay();
	brake();	
}

void TIME0init(void)
{
	TMOD=0x02;
	TH0=0x00;
	TL0=0x00;
	ET0=1;
	TR0=1;	
}

void EX0init()
{
 	IT0=1;
	EX0=1;
	EA=1;
}

void TIME0_interrupt(void) interrupt 1 using 1
{
	irtime++;
}

void EX0_interrupt(void) interrupt 0
{
 	static unsigned char i;		  
	static bit startflag;		

	if(startflag)
	{
		if(irtime>40&&irtime<60)
		 	i=0;
		IRdata[i]=irtime;
		irtime=0;
		i++;
		if(i==33)
		{
		 	ir_ok=1;
			startflag=0;
		}	
	}
	else
	{
	 	irtime=0;
		startflag=1;
	}
}  

void Ir_work(void)
{
	if (IRcode[0]==0x00&&IRcode[1]==0xFF)
	{
		   		switch(IRcode[2])//0x00FF
		{
			//up
			case 0x18:
			{
				switch (status_flag)
				{
					case 0x01:brake();forward();break;
					case 0x04:forward();break;
					default:servo(INITIAL_angle);forward();
				}
				break;
			}
			
			//<-
			case 0x08:
			{
				switch (status_flag)
				{
					case 0x00:left();forward();break;
					case 0x01:left();backward();break;
					default:left();
				}
				break;
			}
			
			//OK
			case 0x1C:
			{
				brake();break;
			}
			
			//->
			case 0x5A:
			{
				switch (status_flag)
				{
					case 0x00:right();forward();break;
					case 0x01:right();backward();break;
					default:right();
				}
				break;
			}
			
			//down
			case 0x52:
			{
				switch (status_flag)
				{
					case 0x00:brake();backward();break;
					case 0x04:backward();break;
					default:servo(INITIAL_angle);backward();
				}
				break;
			}
			default:break;
		}
	}
}

void Ircodepro(void)
{
	unsigned char i, j, k;
	unsigned char cord,value;
	
	k=1;
	for(i=0;i<4;i++)      //??|¨¤¨a4???á??¨2
	 {
	  for(j=1;j<=8;j++) //??|¨¤¨a1???á??¨28??
	     {
	      cord=IRdata[k];
	      if(cord>7)
	         value|=0x80;
	      if(j<8)
		    {
			 value>>=1;
			}
	       k++;
	     }
	 IRcode[i]=value;
	 value=0;     
	 } 
	 irpro_ok=1;
}

void servo(unsigned char t)	//5<=t<=25  %200
{
	unsigned char i;
	for(i=5;i>0;i--)
	{
		servo_port=1;
		delay_servo(t);
		servo_port=0;
		delay_servo(200-t);
	}
}

//0.1ms
void delay_servo(unsigned char _100us_count)   //error=-0.173611111111us
{
    unsigned char a,b;
		while(_100us_count)
		{
			for(b=1;b>0;b--)
					for(a=43;a>0;a--);
			_100us_count--;
		}			
}


//80ms
void delay(void)   //error = -0.000000000018us
{
    unsigned char a,b,c;
    for(c=75;c>0;c--)
        for(b=196;b>0;b--)
            for(a=1;a>0;a--);
}

void forward(void)
{
	status_flag=0x00;
	IN1=1;
	IN2=0;
	IN3=0;
	IN4=1;
	//delay();
}

void backward(void)
{
	status_flag=0x01;
	IN1=0;
	IN2=1;
	IN3=1;
	IN4=0;
	//delay();
}

void left(void)
{
	status_flag=0x02;
	servo(LEFT_ANGLE);	
}
	
void right(void)
{
	status_flag=0x03;
	servo(RIGHT_ANGLE);	
}


void brake(void)
{
	status_flag=0x04;
	IN1=1;//control
	IN2=1;
	IN3=1;
	IN4=1;
	//delay();
}

蓝牙协议控制
蓝牙串口助手app下载:我的Github主页

#include<reg52.h>
#include<intrins.h>

sbit IN1=P1^0;
sbit IN2=P1^1;
sbit IN3=P1^2;
sbit IN4=P1^3;

sbit servo_port=P2^7;									
#define INITIAL_angle 15							
#define BIAS_ANGLE 2									
#define LEFT_ANGLE INITIAL_angle-BIAS_ANGLE
#define RIGHT_ANGLE INITIAL_angle+BIAS_ANGLE

unsigned char status_flag;//0x00=forward,0x01=backward,0x02=left,0x03=right,0x04=brake

unsigned char irtime;
bit irpro_ok,ir_ok;
unsigned char IRcode[4],IRdata[33];

void servo(unsigned char t);	//5<=t<=25  %200
void delay_servo(unsigned char _100us_count);   //error=-0.173611111111us
void delay(void);   //error = -0.000000000018us
void backward(void);
void forward(void);
void left(void);
void right(void);
void brake(void);
void TIME0init(void);
void EX0init();
void TIME0_interrupt(void); 
void EX0_interrupt(void);
void Ir_work(void);
void Ircodepro(void);
void initial_status_test(void);



void main(void)
{
	EX0init();
	TIME0init();
	initial_status_test();
	while(1)
	{
		if(ir_ok)
		{
			Ircodepro();
			ir_ok=0;
		}

		if(irpro_ok)
		{
		 	Ir_work();
			irpro_ok=0;
		}
	}
}

void initial_status_test(void)
{
	servo(INITIAL_angle);	//???ú1é??
	servo(INITIAL_angle);	//???ú1é??
	forward();
	delay();
	delay();
	brake();
	backward();
	delay();
	delay();
	brake();	
}

void TIME0init(void)
{
	TMOD=0x02;
	TH0=0x00;
	TL0=0x00;
	ET0=1;
	TR0=1;	
}

void EX0init()
{
 	IT0=1;
	EX0=1;
	EA=1;
}

void TIME0_interrupt(void) interrupt 1 using 1
{
	irtime++;
}

void EX0_interrupt(void) interrupt 0
{
 	static unsigned char i;		  
	static bit startflag;		

	if(startflag)
	{
		if(irtime>40&&irtime<60)
		 	i=0;
		IRdata[i]=irtime;
		irtime=0;
		i++;
		if(i==33)
		{
		 	ir_ok=1;
			startflag=0;
		}	
	}
	else
	{
	 	irtime=0;
		startflag=1;
	}
}  

void Ir_work(void)
{
	if (IRcode[0]==0x00&&IRcode[1]==0xFF)
	{
		   		switch(IRcode[2])//0x00FF
		{
			//up
			case 0x18:
			{
				switch (status_flag)
				{
					case 0x01:brake();forward();break;
					case 0x04:forward();break;
					default:servo(INITIAL_angle);forward();
				}
				break;
			}
			
			//<-
			case 0x08:
			{
				switch (status_flag)
				{
					case 0x00:left();forward();break;
					case 0x01:left();backward();break;
					default:left();
				}
				break;
			}
			
			//OK
			case 0x1C:
			{
				brake();break;
			}
			
			//->
			case 0x5A:
			{
				switch (status_flag)
				{
					case 0x00:right();forward();break;
					case 0x01:right();backward();break;
					default:right();
				}
				break;
			}
			
			//down
			case 0x52:
			{
				switch (status_flag)
				{
					case 0x00:brake();backward();break;
					case 0x04:backward();break;
					default:servo(INITIAL_angle);backward();
				}
				break;
			}
			default:break;
		}
	}
}

void Ircodepro(void)
{
	unsigned char i, j, k;
	unsigned char cord,value;
	
	k=1;
	for(i=0;i<4;i++)      //??|¨¤¨a4???á??¨2
	 {
	  for(j=1;j<=8;j++) //??|¨¤¨a1???á??¨28??
	     {
	      cord=IRdata[k];
	      if(cord>7)
	         value|=0x80;
	      if(j<8)
		    {
			 value>>=1;
			}
	       k++;
	     }
	 IRcode[i]=value;
	 value=0;     
	 } 
	 irpro_ok=1;
}

void servo(unsigned char t)	//5<=t<=25  %200
{
	unsigned char i;
	for(i=5;i>0;i--)
	{
		servo_port=1;
		delay_servo(t);
		servo_port=0;
		delay_servo(200-t);
	}
}

//0.1ms
void delay_servo(unsigned char _100us_count)   //error=-0.173611111111us
{
    unsigned char a,b;
		while(_100us_count)
		{
			for(b=1;b>0;b--)
					for(a=43;a>0;a--);
			_100us_count--;
		}			
}


//80ms
void delay(void)   //error = -0.000000000018us
{
    unsigned char a,b,c;
    for(c=75;c>0;c--)
        for(b=196;b>0;b--)
            for(a=1;a>0;a--);
}

void forward(void)
{
	status_flag=0x00;
	IN1=1;
	IN2=0;
	IN3=0;
	IN4=1;
	//delay();
}

void backward(void)
{
	status_flag=0x01;
	IN1=0;
	IN2=1;
	IN3=1;
	IN4=0;
	//delay();
}

void left(void)
{
	status_flag=0x02;
	servo(LEFT_ANGLE);	
}
	
void right(void)
{
	status_flag=0x03;
	servo(RIGHT_ANGLE);	
}


void brake(void)
{
	status_flag=0x04;
	IN1=1;//control
	IN2=1;
	IN3=1;
	IN4=1;
	//delay();
}

超声波测距自动避障行驶

//INT0->P3.2<-ECHO TRIG->P1.4
#include<reg52.h>
#include <intrins.h>

#define STRAIGHT_DISTANCE_SETTING 30	//正前方测距的临界距离
#define ROUND_DISTANCE_SETTING 15			//左右方测距的临界距离
#define INITIAL_angle 14							//舵机初始位置
#define BIAS_ANGLE 5									//舵机左右偏置
#define LEFT_ANGLE INITIAL_angle+BIAS_ANGLE
#define RIGHT_ANGLE INITIAL_angle-BIAS_ANGLE

sbit servo_port=P2^7;									//舵机IO口
sbit ECHO=P3^2;												//接超声波输出信号
sbit TRIG=P1^4;												//超声波触发信号
sbit IN1=P1^0;												//motor A ->Right
sbit IN2=P1^1;
sbit IN3=P1^2;												//motor B ->Left
sbit IN4=P1^3;

unsigned char time_H,time_L;
int distance,time,left_distance,right_distance;

void delay(void);
void forward(void);
void backward(void);
void left(void);
void right(void);
void brake(void);
void compute_distance(void);
void DELAY100ms(void);
void DELAY15us(void);
void detect_distance(void);
void initTIMER0(void);
void servo(unsigned char t);
void delay_servo(unsigned char _100us_count);
void detect_left_distance(void);
void detect_right_distance(void);

void main(void)
{	
	initTIMER0();
	servo(INITIAL_angle);	//舵机归位
	
	while(1)
	{
		detect_distance();
		while(distance < STRAIGHT_DISTANCE_SETTING)
		{	
			brake();
			backward();
			brake();
			
			detect_left_distance();	//舵机左方测距
			left_distance=distance;
			
			detect_right_distance();	//舵机右方测距
			right_distance=distance;
			
			servo(INITIAL_angle);	//舵机归位
			
			if((left_distance>ROUND_DISTANCE_SETTING)||(right_distance>ROUND_DISTANCE_SETTING))
			{
				left_distance>right_distance?	left() : right();
			}
			else
			{
				backward();
				brake();
				brake();
				left();
			}
			detect_distance();
		}
		forward();
	}
}

void servo(unsigned char t)	//5<=t<=25  %200
{
	unsigned char i;
	for(i=25;i>0;i--)
	{
		servo_port=1;
		delay_servo(t);
		servo_port=0;
		delay_servo(200-t);
	}
}

//0.1ms
void delay_servo(unsigned char _100us_count)   //error=-0.173611111111us
{
    unsigned char a,b;
		while(_100us_count)
		{
			for(b=1;b>0;b--)
        for(a=89;a>0;a--);
			_100us_count--;
		}			
}

void detect_distance(void) //(cm)
{
		EX0=1;
		TR0=1;
		TRIG=1;
		DELAY15us();
		TRIG=0;
		DELAY100ms();
		EX0=0;
		compute_distance();
}

void detect_left_distance(void) //(cm)
{	
		servo(LEFT_ANGLE);
		EX0=1;
		TR0=1;
		TRIG=1;
		DELAY15us();
		TRIG=0;
		servo(LEFT_ANGLE);
		servo(LEFT_ANGLE);
		EX0=0;
		compute_distance();
}

void detect_right_distance(void) //(cm)
{
		servo(RIGHT_ANGLE);
		EX0=1;
		TR0=1;
		TRIG=1;
		DELAY15us();
		TRIG=0;
		servo(RIGHT_ANGLE);
		servo(RIGHT_ANGLE);
		EX0=0;
		compute_distance();
}

void INTER0_process(void)	interrupt 0  
{
	TR0=0;
	time_H=TH0;
	time_L=TL0;
	TH0=0;
	TL0=0;
}

void initTIMER0(void)
{
	TMOD=0x09;
	TH0=0x00;
	TL0=0x00;
	EA=1;
	IT0=1;
}

void DELAY15us(void)   //误差 0us
{
    unsigned char d;
    for(d=12;d>0;d--);
}

void DELAY100ms(void)
{
		unsigned char a,b,c;
    for(c=131;c>0;c--)
        for(b=156;b>0;b--)
            for(a=3;a>0;a--);
}

void compute_distance(void)
{
	time=0;
	time|=time_H;
	time<<=8;
	time|=time_L;
	distance=time*0.0093;	
}

//40ms
void delay(void)   //误差 -0.000000000009us
{
		unsigned char a,b,c;
    for(c=75;c>0;c--)
        for(b=196;b>0;b--)
            for(a=1;a>0;a--);
}

void forward(void)	//前进
{
	IN1=1;//control
	IN2=0;
	IN3=1;
	IN4=0;
	delay();
}

void backward(void)	//后退
{
	IN1=0;//control
	IN2=1;
	IN3=0;
	IN4=1;
	delay();
	delay();
	delay();
	delay();
}

void left(void)	//左转
{
	IN1=1;//control
	IN2=0;
	IN3=0;
	IN4=1;
	delay();
	delay();
	delay();	
	brake();
}
	
void right(void)	//右转
{
	IN1=0;//control
	IN2=1;
	IN3=1;
	IN4=0;
	delay();
	delay();
	delay();	
	brake();
}

void brake(void)	//制动
{
	IN1=1;//control
	IN2=1;
	IN3=1;
	IN4=1;
	delay();
	delay();
	delay();
}

蓝牙协议控制小车机械臂

/************************************************************
servo1 右 40-120 right
servo2 左 0-50	left
servo3 底座 0-180	bottom
servo4 上爪 100-125	up
************************************************************/


#include<reg52.h>           
#include <intrins.h>  
#include <stdio.h>
#include <math.h>
typedef  unsigned char  uchar;        
typedef  unsigned int   uint;        


sbit scl=P3^6;                   //时钟输入线
sbit sda=P3^7;                   //数据输入/输出端


#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 0x00
#define PCA9685_PRESCALE 0xFE


#define LED0_ON_L 0x06
#define LED0_ON_H 0x07
#define LED0_OFF_L 0x08
#define LED0_OFF_H 0x09


#define ALLLED_ON_L 0xFA
#define ALLLED_ON_H 0xFB
#define ALLLED_OFF_L 0xFC
#define ALLLED_OFF_H 0xFD

unsigned char remote_command[7]; //包头(0xA5)+原数据+校验和(1B)+包尾(0x5A)
unsigned char data_index=0;
bit command_flag;


void delayms(uint z);
void delayus();
void init();
void start();
void stop();
void ACK();
void write_byte(uchar byte);
uchar PCA9685_read(uchar address);
uchar read_byte();
void PCA9685_write(uchar address,uchar date);
void reset(void) ;
void setPWMFreq(float freq); 
void servo_control(uchar num, uchar angle);
void command_process(void);
void init_bluetooth_timer0(void);
void bluetooth_interrupt_process(void);
void begin(void); 
void servo_angle(void);
uchar servo1=90;
uchar servo2=90;
uchar servo3=90;
uchar servo4=90;


/*---------------------------------------------------------------
                      主函数
----------------------------------------------------------------*/
void main()
{
	init();
	begin();
	setPWMFreq(50);  
	init_bluetooth_timer0();
	servo_angle();
	while(1)
	{
		if(command_flag)
		{
			command_process();
			servo_angle();
		}
	}       
}


void servo_angle(void)
{
	servo_control(0,servo1);
	delayms(2);
	servo_control(1,servo2);
	delayms(2);
	servo_control(2,servo3);
	delayms(2);
	servo_control(3,servo4);
}

void command_process(void)
{	
		if(remote_command[0]==0xA5)
		{
			servo1=remote_command[1]+90;
			servo2=remote_command[2]+90;
			servo3=remote_command[3]+90;
			servo4=remote_command[4]+90;
		}
		command_flag=0;
}

void init_bluetooth_timer0(void)
{	
	TMOD=0x20;
	TH1=253;
	TL1=TH1;
	SCON=0x50;
	TR1=1;
	EA=1;
	ES=1;
}

void bluetooth_interrupt_process(void)	interrupt 4 
{
	if(RI)
	{
		remote_command[data_index]=SBUF;
		data_index++;
		if(data_index==7)
		{
			data_index=0;
			command_flag=1;
		}
		RI=0;
	}
}

/**********************函数的声明*********************************/
/*---------------------------------------------------------------
                  毫秒延时函数
----------------------------------------------------------------*/
void delayms(uint z)
{
  unsigned char a,b;
	while(z)
	{
    for(b=102;b>0;b--)
        for(a=3;a>0;a--);
		z--;
	}
}
/*---------------------------------------------------------------
                                                                        IIC总线所需的通用函数
----------------------------------------------------------------*/
/*---------------------------------------------------------------
                 微妙级别延时函数 大于4.7us
----------------------------------------------------------------*/
void delayus()
{
		_nop_();  //if Keil,require use intrins.h
    _nop_();  //if Keil,require use intrins.h
}
/*---------------------------------------------------------------
                 IIC总线初始化函数 
----------------------------------------------------------------*/
void init()
{
    sda=1;                //sda scl使用前总是被拉高
    delayus();
    scl=1;
    delayus();
}
/*---------------------------------------------------------------
                 IIC总线启动信号函数
----------------------------------------------------------------*/
void start()
{
    sda=1;
    delayus();
    scl=1;                        //scl拉高时 sda突然来个低电平 就启动了IIC总线
    delayus();
    sda=0;
    delayus();
    scl=0;
    delayus();
}
/*---------------------------------------------------------------
                 IIC总线停止信号函数
----------------------------------------------------------------*/
void stop()
{
    sda=0;
    delayus();
    scl=1;                         //scl拉高时 sda突然来个高电平 就停止了IIC总线
    delayus();
    sda=1;                   
    delayus();
}
/*---------------------------------------------------------------
                 IIC总线应答信号函数
----------------------------------------------------------------*/
void ACK()
{
    uint i;
    scl=1;
    delayus();
    while((sda=1)&&(i<255))         
			i++;                                        
    scl=0;                                  
    delayus();
}
/*---------------------------------------------------------------
                 写一个字节,无返回值,需输入一个字节值
----------------------------------------------------------------*/
void write_byte(uchar byte)
{
    uchar i,temp;
    temp=byte;
    for(i=0;i<8;i++)
    {
        temp=temp<<1;  
        scl=0;                  
				delayus();
				sda=CY;
				delayus();
				scl=1;           
				delayus();
    }
    scl=0;                  
    delayus();
    sda=1;                 
    delayus();
}
/*---------------------------------------------------------------
                 读一个字节函数,有返回值
----------------------------------------------------------------*/
uchar read_byte()
{
		uchar i,j,k;
		scl=0;
		delayus();
		sda=1;
		delayus();
		for(i=0;i<8;i++)        
		{
			delayus();
			scl=1;
			delayus();
			if(sda==1)
			{
					j=1;
			}
			else j=0;
			k=(k<< 1)|j;
			scl=0;            
		}
		delayus();
		return k;
}
/*---------------------------------------------------------------
                有关PCA9685模块的函数
----------------------------------------------------------------*/
/*---------------------------------------------------------------
                向PCA9685里写地址,数据
----------------------------------------------------------------*/
void PCA9685_write(uchar address,uchar date)
{
		start();
		write_byte(PCA9685_adrr);        //PCA9685的片选地址
		ACK();                          
		write_byte(address);  //写地址控制字节
		ACK();
		write_byte(date);          //写数据
		ACK();
		stop();
}
/*---------------------------------------------------------------
            从PCA9685里的地址值中读数据(有返回值)
----------------------------------------------------------------*/
uchar PCA9685_read(uchar address)
{
		uchar date;
		start();
		write_byte(PCA9685_adrr); //PCA9685的片选地址
		ACK();
		write_byte(address);
		ACK();
		start();
		write_byte(PCA9685_adrr|0x01);        //地址的第八位控制数据流方向,就是写或读
		ACK();
		date=read_byte();
		stop();
		return date;
}
/*---------------------------------------------------------------
                        PCA9685复位
----------------------------------------------------------------*/
void reset(void) 
{
	PCA9685_write(PCA9685_MODE1,0x0);
}


void begin(void) 
{
	reset();
}
/*---------------------------------------------------------------
                                        PCA9685修改频率函数
----------------------------------------------------------------*/
void setPWMFreq(float freq) 
{
		uint prescale,oldmode,newmode;
		float prescaleval;
		freq *= 0.92;  // Correct for overshoot in the frequency setting 
		prescaleval = 25000000;
		prescaleval /= 4096;
		prescaleval /= freq;
		prescaleval -= 1;
		prescale = floor(prescaleval + 0.5);
		
		oldmode = PCA9685_read(PCA9685_MODE1);
		newmode = (oldmode&0x7F) | 0x10; // sleep
		PCA9685_write(PCA9685_MODE1, newmode); // go to sleep
		PCA9685_write(PCA9685_PRESCALE, prescale); // set the prescaler
		PCA9685_write(PCA9685_MODE1, oldmode);
		delayms(2);
		PCA9685_write(PCA9685_MODE1, oldmode | 0xa1); 
}
/*---------------------------------------------------------------
                                PCA9685修改角度函数
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 servo_control(uchar num, uchar angle) 
{
		uint off = 102.4+2.275555556*angle;
		PCA9685_write(LED0_ON_L+4*num,0);
		PCA9685_write(LED0_ON_H+4*num,0);
		PCA9685_write(LED0_OFF_L+4*num,off);
		PCA9685_write(LED0_OFF_H+4*num,off>>8);
}

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-09-05 11:11:07  更:2021-09-05 11:13:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 1:54:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码