舵机光敏电阻实现一维光源追踪
来源:互联网 发布:淘宝主图要求规范 编辑:程序博客网 时间:2024/06/11 17:11
学习430已经有几天了,一直以来就是熟悉各个模块。从最开始的点亮一个发光二级管,再做流水灯,再通过按键来控制发光二极管的亮灭,再到后来的1602、定时器做频率计,AD,再到今天的舵机控制以及光源跟踪。期间遇到了不少的问题,不过通过同学和老师还有你们的帮助,都将困难克服。但是前进的路还有很长,我们一起学习,一起努力,共同进步。下面先说说舵机。
用单片机控制舵机我还是第一次。以前在航模上用过舵机,不过那都是买的现成的遥控器之类的。刚拿到舵机的时候,我就是在想如何让舵机转动。我在网上查找资料,觉得跟步进电机很相似,但舵机只有三根线,其中有根线是用来输入PWM的。初步查找了资料以后,我用函数信号发生器给它输入周期为20ms的方波,发现如果占空比不变的话,舵机是不会动的。如果将占空比改变,在改变的时候,舵机会转动。我再次查找资料,发现要让舵机动起来,就是不断的调节占空比,但是PWM的周期是20ms固定的。高电平的时间范围是0.5ms~2.5ms。这下就简单多了,用定时器产生PWM,CCR0设置周期,CCR1设置可调的占空比。CCR1=LMAX+(unsigned int)(angle*_angle),这样,就可以通过改变angle的值来调节CCR1了。很多人应该都知道这些,不好意思哈,只是想把这一过程都写出来,让不是很清楚的人都有个比较好的了解,能达到一起学习的效果就好。
舵机的问题搞定了,然后就是传感器的问题。首先就选了光敏电阻,它便宜,而且这里备用的比较多。用了两个光敏电阻。(注意)刚开始的时候用一个很长的黑色的套筒将光敏电阻罩住了,光敏电阻的阻值很大,这样就出现了一个问题。就是在分压的时候必须要用很大的电阻去分压。如果输入到AD去采样的话,就出现。 很大的问题看看这张图,就是我采用的比较简单的电路图。如果R3比较大的话,有电流流入点A,那么点A的电压就会很高,从而改变了取样点A的电压值。这就是使用msp430中ADC10的时候要注意的一个问题。如果将光敏电阻的套筒变短一点,那么光敏电阻R1的值就会降低一些,R2和R3的电阻就能相应的减小,A点的电压就不会有太大的影响了。用在其他地方的时候也要注意这个问题,不然会很麻烦。AD是使用双通道的,有不明白的可以看我前几天发的帖子http://www.9mcu.com/9mcubbs/forum.php?mod=viewthread&tid=960789&extra=page%3D1。这个系统就是把AD,舵机,定时器的程序揉和在一起了。下面上程序,图片还有视频。东西做的不好,见笑了~~~
//**********************************************
//***********一维光源跟踪系统*******************
// --------------------------------
// -->|P1.0(A0) P1.2(PWM)|-->
// -->|P1.1(A1) P1.6(lcdrs)|-->
// | P1.7(lcden)|-->
// | lcdrw|----
// | | \|/
// | msp430g2553 |
//**********************************************
#include<msp430g2553.h>
#include<1602.h>
#include<duoji.h>
#define uint unsigned int
#define uchar unsigned char
uchar table_num[]={"0123456789"};
uint a[8],b[2],c,d,c_ge,c_shi,c_bai,c_qian,d_ge,d_shi,d_bai,d_qian;
uint i,j,num_1,num_0,diff;
uchar Direction=0;
float k;
void adc()
{
ADC10CTL0&=~ENC;//关闭采样使能
while(ADC10CTL1&BUSY);//检测AD是否繁忙
ADC10CTL0|=ENC+ADC10SC;//启动ADC
ADC10SA=(unsigned int)a;//获取a[]的首地址。首先对A1、A0采样,放入a[0]和a[1]中。再对A1、A0采样,放入a[2]和a[3]中,如此循环下去。
_BIS_SR(GIE);//低功耗模式0,开中断
for(i=0;i<2;i++)
{
b=0;
for(j=0;j<4;j++)
b+=a[i+j*2];
}
for(i=0;i<2;i++)
{
b=b/4;
}
num_1=(int)(b[0]*1.08);//根据需要,可以更改这里的数值,将量程调到0~1024
num_0=(int)(b[1]*1.08);//根据需要,可以更改这里的数值,将量程调到0~1024
num_1=num_1-num_1%10;
num_0=num_0-num_0%10;
if(num_0>num_1)
diff=num_0-num_1;
else if(num_0<num_1)
diff=num_1-num_0;
else diff=0;
}
void display()
{
delay_Nms(50);
c=(int)(num_1*3.3);//转换为电压值
c_ge=c/1000;
c_shi=c%1000/100;
c_bai=c%100/10;
c_qian=c%10;
d=(int)(num_0*3.3);//转换为电压值
d_ge=d/1000;
d_shi=d%1000/100;
d_bai=d%100/10;
d_qian=d%10;
write_com(0x80);
write_data(table_num[num_1/1000]);
write_data(table_num[num_1%1000/100]);
write_data(table_num[num_1%100/10]);
write_data(table_num[num_1%10]);
write_data('=');
write_data(table_num[c_ge]);
write_data('.');
write_data(table_num[c_shi]);
write_data(table_num[c_bai]);
write_data(table_num[c_qian]);
write_data('V');
write_com(0x80+0x40);
write_data(table_num[num_0/1000]);
write_data(table_num[num_0%1000/100]);
write_data(table_num[num_0%100/10]);
write_data(table_num[num_0%10]);
write_data('=');
write_data(table_num[d_ge]);
write_data('.');
write_data(table_num[d_shi]);
write_data(table_num[d_bai]);
write_data(table_num[d_qian]);
write_data('V');
}
void main()
{
WDTCTL=WDTPW+WDTHOLD;//关看门狗
P2SEL=0x00;//P2为I/O模式
P2DIR|=0xff;//P2为LCD输出
P1DIR|=BIT6+BIT7;//P1.6和P1.7为LCD的输出
P1SEL|=BIT1+BIT0;//P1.1和P1.2设置为ADC功能A1和A0
P1DIR&=0xfc;
ADC10CTL1|=CONSEQ_3+INCH_1;//序列通道单次转换+最大通道为A1
ADC10CTL0|=ADC10SHT_2+MSC+ADC10ON+ADC10IE;
ADC10DTC1|=0x08;//一共采样8次
ADC10AE0|=BIT0+BIT1;//打开A0和A1的模拟输入通道
init_clock();//时钟初始化
motor();//舵机初始化
init_lcd();//lcd初始化
_BIS_SR(GIE);//开中断
TACTL|=MC_1+TASSEL_2;//增计数模式+SMCLK
k=80;//让舵机从中间位置开始转动
while(1)
{
adc();
display();//lcd显示
set_angle(k);
delay_Nms(25);//更改延时,可以调节舵机转动的快慢
////////////////////////////////
if(diff>30)//当两值相差大于50的时候,转动
{
if((num_0)>(num_1))
Direction=0;
else if(num_0<num_1)
Direction=1;
else Direction=2;
}
else Direction=2;
//////////////////////////////////
if(Direction==0)//逆时针转动
k=k+1.5; //逆时针转动
else if(Direction==1) //顺时针转动
k=k-1.5; //顺时针转动
else k=k;
///////////////////////////////////////
if(k>160)
Direction=1; //换为减
if(k<20)
Direction=0; //换为加
}
}
#pragma vector=ADC10_VECTOR
__interrupt void ADC(void)
{
LPM0_EXIT;//退出低功耗模式
}
用单片机控制舵机我还是第一次。以前在航模上用过舵机,不过那都是买的现成的遥控器之类的。刚拿到舵机的时候,我就是在想如何让舵机转动。我在网上查找资料,觉得跟步进电机很相似,但舵机只有三根线,其中有根线是用来输入PWM的。初步查找了资料以后,我用函数信号发生器给它输入周期为20ms的方波,发现如果占空比不变的话,舵机是不会动的。如果将占空比改变,在改变的时候,舵机会转动。我再次查找资料,发现要让舵机动起来,就是不断的调节占空比,但是PWM的周期是20ms固定的。高电平的时间范围是0.5ms~2.5ms。这下就简单多了,用定时器产生PWM,CCR0设置周期,CCR1设置可调的占空比。CCR1=LMAX+(unsigned int)(angle*_angle),这样,就可以通过改变angle的值来调节CCR1了。很多人应该都知道这些,不好意思哈,只是想把这一过程都写出来,让不是很清楚的人都有个比较好的了解,能达到一起学习的效果就好。
舵机的问题搞定了,然后就是传感器的问题。首先就选了光敏电阻,它便宜,而且这里备用的比较多。用了两个光敏电阻。(注意)刚开始的时候用一个很长的黑色的套筒将光敏电阻罩住了,光敏电阻的阻值很大,这样就出现了一个问题。就是在分压的时候必须要用很大的电阻去分压。如果输入到AD去采样的话,就出现。 很大的问题看看这张图,就是我采用的比较简单的电路图。如果R3比较大的话,有电流流入点A,那么点A的电压就会很高,从而改变了取样点A的电压值。这就是使用msp430中ADC10的时候要注意的一个问题。如果将光敏电阻的套筒变短一点,那么光敏电阻R1的值就会降低一些,R2和R3的电阻就能相应的减小,A点的电压就不会有太大的影响了。用在其他地方的时候也要注意这个问题,不然会很麻烦。AD是使用双通道的,有不明白的可以看我前几天发的帖子http://www.9mcu.com/9mcubbs/forum.php?mod=viewthread&tid=960789&extra=page%3D1。这个系统就是把AD,舵机,定时器的程序揉和在一起了。下面上程序,图片还有视频。东西做的不好,见笑了~~~
//**********************************************
//***********一维光源跟踪系统*******************
// --------------------------------
// -->|P1.0(A0) P1.2(PWM)|-->
// -->|P1.1(A1) P1.6(lcdrs)|-->
// | P1.7(lcden)|-->
// | lcdrw|----
// | | \|/
// | msp430g2553 |
//**********************************************
#include<msp430g2553.h>
#include<1602.h>
#include<duoji.h>
#define uint unsigned int
#define uchar unsigned char
uchar table_num[]={"0123456789"};
uint a[8],b[2],c,d,c_ge,c_shi,c_bai,c_qian,d_ge,d_shi,d_bai,d_qian;
uint i,j,num_1,num_0,diff;
uchar Direction=0;
float k;
void adc()
{
ADC10CTL0&=~ENC;//关闭采样使能
while(ADC10CTL1&BUSY);//检测AD是否繁忙
ADC10CTL0|=ENC+ADC10SC;//启动ADC
ADC10SA=(unsigned int)a;//获取a[]的首地址。首先对A1、A0采样,放入a[0]和a[1]中。再对A1、A0采样,放入a[2]和a[3]中,如此循环下去。
_BIS_SR(GIE);//低功耗模式0,开中断
for(i=0;i<2;i++)
{
b=0;
for(j=0;j<4;j++)
b+=a[i+j*2];
}
for(i=0;i<2;i++)
{
b=b/4;
}
num_1=(int)(b[0]*1.08);//根据需要,可以更改这里的数值,将量程调到0~1024
num_0=(int)(b[1]*1.08);//根据需要,可以更改这里的数值,将量程调到0~1024
num_1=num_1-num_1%10;
num_0=num_0-num_0%10;
if(num_0>num_1)
diff=num_0-num_1;
else if(num_0<num_1)
diff=num_1-num_0;
else diff=0;
}
void display()
{
delay_Nms(50);
c=(int)(num_1*3.3);//转换为电压值
c_ge=c/1000;
c_shi=c%1000/100;
c_bai=c%100/10;
c_qian=c%10;
d=(int)(num_0*3.3);//转换为电压值
d_ge=d/1000;
d_shi=d%1000/100;
d_bai=d%100/10;
d_qian=d%10;
write_com(0x80);
write_data(table_num[num_1/1000]);
write_data(table_num[num_1%1000/100]);
write_data(table_num[num_1%100/10]);
write_data(table_num[num_1%10]);
write_data('=');
write_data(table_num[c_ge]);
write_data('.');
write_data(table_num[c_shi]);
write_data(table_num[c_bai]);
write_data(table_num[c_qian]);
write_data('V');
write_com(0x80+0x40);
write_data(table_num[num_0/1000]);
write_data(table_num[num_0%1000/100]);
write_data(table_num[num_0%100/10]);
write_data(table_num[num_0%10]);
write_data('=');
write_data(table_num[d_ge]);
write_data('.');
write_data(table_num[d_shi]);
write_data(table_num[d_bai]);
write_data(table_num[d_qian]);
write_data('V');
}
void main()
{
WDTCTL=WDTPW+WDTHOLD;//关看门狗
P2SEL=0x00;//P2为I/O模式
P2DIR|=0xff;//P2为LCD输出
P1DIR|=BIT6+BIT7;//P1.6和P1.7为LCD的输出
P1SEL|=BIT1+BIT0;//P1.1和P1.2设置为ADC功能A1和A0
P1DIR&=0xfc;
ADC10CTL1|=CONSEQ_3+INCH_1;//序列通道单次转换+最大通道为A1
ADC10CTL0|=ADC10SHT_2+MSC+ADC10ON+ADC10IE;
ADC10DTC1|=0x08;//一共采样8次
ADC10AE0|=BIT0+BIT1;//打开A0和A1的模拟输入通道
init_clock();//时钟初始化
motor();//舵机初始化
init_lcd();//lcd初始化
_BIS_SR(GIE);//开中断
TACTL|=MC_1+TASSEL_2;//增计数模式+SMCLK
k=80;//让舵机从中间位置开始转动
while(1)
{
adc();
display();//lcd显示
set_angle(k);
delay_Nms(25);//更改延时,可以调节舵机转动的快慢
////////////////////////////////
if(diff>30)//当两值相差大于50的时候,转动
{
if((num_0)>(num_1))
Direction=0;
else if(num_0<num_1)
Direction=1;
else Direction=2;
}
else Direction=2;
//////////////////////////////////
if(Direction==0)//逆时针转动
k=k+1.5; //逆时针转动
else if(Direction==1) //顺时针转动
k=k-1.5; //顺时针转动
else k=k;
///////////////////////////////////////
if(k>160)
Direction=1; //换为减
if(k<20)
Direction=0; //换为加
}
}
#pragma vector=ADC10_VECTOR
__interrupt void ADC(void)
{
LPM0_EXIT;//退出低功耗模式
}
- 舵机光敏电阻实现一维光源追踪
- 光敏电阻
- 光敏电阻
- 蓝牙AmoMcu_254x传感器---光敏电阻的实现
- Arduino + Cubieboard + 继电器 + 光敏电阻 实现天亮自动播放音乐
- Arduino程序-光敏电阻
- Arduino使用光敏电阻实验
- 光敏电阻的简单介绍
- 光敏电阻测试数码管显示
- 光敏电阻测试数码管显示
- 光敏电阻的一些特性
- PIC通过AD使用光敏电阻
- Arduino 光敏电阻调节呼吸灯
- 光敏电阻与光电二极管的区别
- 光敏电阻的原理及应用
- 电路设计_光敏电阻学习笔记
- 【Arduino】使用光敏电阻测量光照强度
- arduino中使用光敏电阻控制LED灯
- broken necklace
- Comparator和Comparable在排序中的应用
- 笔划输入法查找算法示例(Lua实现)
- eas bos 导入解决方案后,启动报错org.eclipse.core.runtime.CoreException
- Android ApiDemos示例解析(105):Views->Buttons
- 舵机光敏电阻实现一维光源追踪
- Vaadin Web应用开发教程(6):使用资源
- /dev/null 2>&1 详解
- VC用法汇总
- 关于断点的一些知识
- VC控件使用( Tab Control等)
- 一个修改桌面背景色的例子
- PHP学习笔记-数组
- 语句用于实现mysql查询前几条记录