|
单片机程序
其实可以用的单片机方案很多,51/AVR/PIC/ARM都可以,我这个人有一个原则就是实用简单可靠性。为了通用起见,便于大家制作,因此选用了最通用的51平台了。原件也便宜好找。
推荐国货精品(一般我只用国货,电脑神舟的,手机山寨的,汽车奇瑞的,冰箱海尔的,空调美的的,洗衣机小天鹅的)
(深圳宏晶电子的STC11F01单片机)(此处涉及广告,删除文字若干,版主留)
不到2元的价格,还自带6M左右的晶体,虽然频率随季节有些漂移,但是通过我的程序分频处理还是可以用的(为此我专门放到冰箱里2小时)。另外一片芯片是驱动步进电机用的,原来打算用一片MD127,但是这个芯片成本高很多,管脚也不好焊。关键是一片两片难买到。因此用最常用的ULN2003代替了,一般只要1块钱,我买的是7毛钱的,好像用得还可以。
以下是程序:setp-motor.c
//相机镜头电机驱动板适应于MD127驱动(4MOS门) 或ULM2003(7-OC门)
//本程序由www.5imx.com的模友“电动机”博士友情奉献
//采用任意兼容的51单片机即可实现,推荐深圳宏晶电子的STC单片机STC11F01
#include <reg51.h>
//sfr WDT_CONTR = 0xE1 ; //看门狗控制寄存器
//sfr AUXR =0x8e; //两个STC专用的寄存器
//sfr BRT=0x9c;
//sfr AUXR1 =0xA2;
//舵机信号的抽样间隔比较范围,每100us一个单位
//位于M1~M2之间是舵机的中立位,小于M1是左,大于M2是右,M0和M3是设置的保护区
#define M0 0x02
#define M1 0x0c
#define M2 0x12
#define M3 0x20
//步进电机步进速度单位,越小越快,越大越慢
//电阻选择不合适的话,太快可能动力不足
#define Step_time 5
//test_127是一个循环标志,就是将相位数组依次送出的指针
static char test_127=0; //相指针变量
//I-O口定义,分别对应A+,A-,B+,B-四个信号
sbit IN1_127=P1^0;
sbit IN2_127=P1^1;
sbit IN3_127=P1^2;
sbit IN4_127=P1^5;
//sbit IN4_127=P1^3; //其它单片机可以改为连续管脚
sbit Servo=P3^7; //这是舵机PPM信号输入口管脚定义
//步进脉冲图案相位数组
//const unsigned char motortb[]={0x08,0x0A,0x02,0x06,0x04,0x05,0x01,0x09};//P1.0~P1.3
const unsigned char motortb[]={0x20,0x22,0x02,0x06,0x04,0x05,0x01,0x21}; //P1.0~P1.5
//全局变量
static unsigned char ZOOM; //镜头方向,0停止,1,2前进后推
static unsigned char flag; //监测到PPM 信号标志
static unsigned char getsov; //捕获到的PPM脉冲抽样计数,每100us一个单位
//定时器0 超时处理,用于捕获PPM
void timer0(void) interrupt 1
{
if(Servo){ //PPM高电平处理
if(flag==1){getsov++;} //高电平计数
else{flag=1;getsov=0;} //捕获上升沿
}
else{ //PPM低电平处理
if(flag==1){
if(getsov>M0){ZOOM=1;} //Zoom OUT
if(getsov>M1){ZOOM=0;} //STOP
if(getsov>M2){ZOOM=2;} //Zoom IN
if(getsov>M3){ZOOM=0;} //Error 信号错误
flag=0; //处理捕获完毕,清零
}
}
}
init_system()
{
TMOD = 0x02; /*定时器0,1-8bit自动重加载模式0*/
//time 0定时加载计数
TH0=206;TL0=206;//置定时数 ,内部6M,每个刻度为2us,100us为50个刻度,256-50 =206
ET0=1; TR0=1; //开启定时器0
EA=1; /*开中断*/
}
//延时程序,不同晶体频率可以修改125的值
void PAUSE(unsigned int ms)
{
unsigned char j;
while(ms--){
for(j=0;j<125;j++)
{;}
}
}
//stop
void md127_keepmode(void)//钳住相位
{
IN1_127=0;
IN2_127=0;
IN3_127=0;
IN4_127=0;
}
void md127_reverse(void)//反向后退
{
unsigned char i;
i=P1&0xf0;
i=i+motortb[test_127];
P1=i;
test_127++;
if(test_127>7)
test_127=0;
PAUSE(Step_time);
md127_keepmode();
}
void md127_forward(void)//正向前进
{
unsigned char i;
i=P1&0xf0;
i=i+motortb[test_127];
P1=i;
test_127--;
if(test_127<0)
test_127=7;
PAUSE(Step_time);
md127_keepmode();
}
//主程序
void main()
{
ZOOM=0;
init_system();
while(1){
if(ZOOM==0){md127_keepmode();}
if(ZOOM==1){md127_reverse();}
if(ZOOM==2){md127_forward();}
}
} |
|