標(biāo)題:
ATmega16實(shí)現(xiàn)八個電位器分別同時控八個舵機(jī),還可以更多
[打印本頁]
作者:
HYH520
時間:
2017-6-12 12:49
標(biāo)題:
ATmega16實(shí)現(xiàn)八個電位器分別同時控八個舵機(jī),還可以更多
上回用了一個定時器控制三個舵機(jī)行不通,這次在次按照網(wǎng)上的思路,用了兩個定時器,成功實(shí)現(xiàn)了atmega16八個電位器分別同時控八個舵機(jī),實(shí)際還可以更多,
通過實(shí)驗(yàn)發(fā)現(xiàn)舵機(jī)受控的周期不一定要20ms,八路舵機(jī),每個舵機(jī)的控制周期可以延伸,例如40ms給一次脈沖,也是能控制舵機(jī)旋轉(zhuǎn)至固定角度,在這里,控制舵機(jī)的應(yīng)該是高電平信號持續(xù)時間,由于從20ms延長到40ms,所以單片機(jī)可以控制更多的舵機(jī),20ms能控制8個,40ms能控制16個,但是20ms相對于40ms控制周期的舵機(jī)來說更穩(wěn)定,可能是由于原本1s內(nèi),以20ms為周期的信號,可以對舵機(jī)發(fā)送50次控制信號,延長到40ms,只能對舵機(jī)發(fā)送25次控制信號,這樣會導(dǎo)致舵機(jī)控制頻率降低,從而導(dǎo)致相對的不穩(wěn)定,這里使用的是普通舵機(jī),數(shù)碼舵機(jī)應(yīng)該不會出現(xiàn)這種情況。
最后貼上代碼,實(shí)測可用:
/**************八通道電位器控制八舵機(jī)****************
* 編寫:HYH
* 日期:2017-6-12
* 晶振:12mhz
* 說明:定時/計(jì)數(shù)器0固定每2.5ms溢出中斷,負(fù)責(zé)拉高對
* 應(yīng)端口,定時/計(jì)數(shù)器1負(fù)責(zé)在tc1中斷產(chǎn)生后將對
* 應(yīng)端口的電平拉低,依次循環(huán)形成八個通道舵機(jī)
* 控制pwm波
*****************************************************/
#include <iom16v.h>
#include <macros.h>
#define uchar unsigned char
#define uint unsigned int
#define OUTPUT PORTD //定義pd口為舵機(jī)信號輸出口
#define ADCN ADMUX
unsigned char output_high[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //數(shù)組控制各個io口高電平
unsigned int i=0;
unsigned int j=0;
unsigned char ADCN_[8]={0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47}; //數(shù)組控制ADC通道選擇
unsigned int adcn_[8]; //存取八個通道的ADC值
unsigned int adcn_change[8]; //存儲adcn_[]經(jīng)過轉(zhuǎn)換成計(jì)數(shù)器1初值的值
/************延時函數(shù)***********/
void delay(unsigned int ms)
{
unsigned int i,j;
for(i=0;i<ms;i++)
{
for(j=0;j<1141;j++);
}
}
/*********端口設(shè)置函數(shù)*********/
void port_init(void)
{
DDRD|=0XFF;
PORTD&=0X00; //設(shè)置舵機(jī)信號輸出端口
DDRA&=0X00;
PORTA|=0Xff; //設(shè)置adc通道端口,帶上拉輸入
SREG=0X80; //開放全局中斷
}
void timer0_init()
{
TIMSK|=(1<<TOIE0); //是能溢出中斷
TCCR0|=(1<<CS02)|(0<<CS01)|(0<<CS00); //12mhz晶振 256預(yù)分頻
TCNT0=139;
//計(jì)數(shù)器初值,(256-139)/(12mhz/256)=2.5ms
}
void timer1_init()
{
TCCR1A|=0X00; //普通模式
TCCR1B|=(0<<CS12)|(0<<CS11)|(1<<CS10); //無預(yù)分頻
TIMSK|=(1<<TOIE1);
}
/**********ad轉(zhuǎn)換函數(shù)**********/
unsigned int ADC_init()
{
unsigned int addata;
ADCN=ADCN_[j]; //AVCC為基準(zhǔn)電,設(shè)置adc通道選擇
ADCSRA=0XD8; //使能ADC,允許中斷 11011000
ADCSRA|=BIT(ADSC); //開始A/D轉(zhuǎn)換
while(!(ADCSRA&(BIT(ADIF)))); //等待轉(zhuǎn)換完成
addata=ADCL; //獲取ADC結(jié)果
addata=addata+ADCH*256;
return addata; //返回ADC值
}
void main()
{
timer0_init();
timer1_init();
ADC_init();
port_init();
}
/*********定時器0中斷函數(shù)************
* 說明:定時器每溢出一次,舵機(jī)通道調(diào)
* 至下一個,拉高該舵機(jī)通道io口
* 并把對應(yīng)通道的adcn_change[]值
* 賦給定時/計(jì)數(shù)器初值
************************************/
#pragma interrupt_handler timer0_ovf:10
void timer0_ovf()
{
OUTPUT|=output_high[i];
TCNT0=139;
TCNT1=adcn_change[i];
i++;
if(i>=8)
i=0;
}
/************定時/計(jì)數(shù)器1中斷函數(shù)********
* 說明:將對應(yīng)端口電平拉高
****************************************/
#pragma interrupt_handler timer1_ovf:9
void timer1_ovf()
{
TCNT1=0;
if(i==0)
OUTPUT&=~BIT(7);
else
OUTPUT&=~BIT(i-1);
}
/************ADC中斷函數(shù)**************/
#pragma interrupt_handler ADCN_change:15
void ADCN_change()
{
adcn_[j]=ADC_init();
adcn_change[j]=59536-24*adcn_[j]; //將adc值轉(zhuǎn)化為定時/計(jì)數(shù)器1初值,控制高電平持續(xù)時間
j++;
if(j>=8)
j=0;
ADC_init(); //adc轉(zhuǎn)換
}
復(fù)制代碼
0.png
(56.86 KB, 下載次數(shù): 250)
下載附件
2017-6-12 15:57 上傳
全部資料下載地址:
ADC多通道.zip
(537.96 KB, 下載次數(shù): 32)
2017-6-12 12:45 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
作者:
admin
時間:
2017-6-12 15:59
好資料,51黑有你更精彩!!!
作者:
erzhu2007
時間:
2017-8-15 15:47
哇,思路清晰啊,舅服你
作者:
erzhu2007
時間:
2017-8-15 19:58
多個數(shù)字舵機(jī)控制,樓主講下具體思路嗎?我不管小板凳已經(jīng)拿來了
作者:
成森林
時間:
2018-1-31 16:23
金幣不足了,先收藏了。
作者:
成森林
時間:
2018-2-25 16:08
終于可以下載到了,謝謝樓主。
作者:
HYH520
時間:
2018-3-8 12:48
數(shù)字舵機(jī)區(qū)別于傳統(tǒng)的模擬舵機(jī),模擬舵機(jī)需要給它不停的發(fā)送PWM信號,才能讓它保持在規(guī)定的位置或者讓它按照某個速度轉(zhuǎn)動,數(shù)字舵機(jī)則只需要發(fā)送一次PWM信號就能保持在規(guī)定的某個位置
作者:
工作狂
時間:
2018-3-10 16:45
好資料,51黑有你更精彩!!!
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1