|
上回用了一個(gè)定時(shí)器控制三個(gè)舵機(jī)行不通,這次在次按照網(wǎng)上的思路,用了兩個(gè)定時(shí)器,成功實(shí)現(xiàn)了atmega16八個(gè)電位器分別同時(shí)控八個(gè)舵機(jī),實(shí)際還可以更多,
通過(guò)實(shí)驗(yàn)發(fā)現(xiàn)舵機(jī)受控的周期不一定要20ms,八路舵機(jī),每個(gè)舵機(jī)的控制周期可以延伸,例如40ms給一次脈沖,也是能控制舵機(jī)旋轉(zhuǎn)至固定角度,在這里,控制舵機(jī)的應(yīng)該是高電平信號(hào)持續(xù)時(shí)間,由于從20ms延長(zhǎng)到40ms,所以單片機(jī)可以控制更多的舵機(jī),20ms能控制8個(gè),40ms能控制16個(gè),但是20ms相對(duì)于40ms控制周期的舵機(jī)來(lái)說(shuō)更穩(wěn)定,可能是由于原本1s內(nèi),以20ms為周期的信號(hào),可以對(duì)舵機(jī)發(fā)送50次控制信號(hào),延長(zhǎng)到40ms,只能對(duì)舵機(jī)發(fā)送25次控制信號(hào),這樣會(huì)導(dǎo)致舵機(jī)控制頻率降低,從而導(dǎo)致相對(duì)的不穩(wěn)定,這里使用的是普通舵機(jī),數(shù)碼舵機(jī)應(yīng)該不會(huì)出現(xiàn)這種情況。
最后貼上代碼,實(shí)測(cè)可用:
- /**************八通道電位器控制八舵機(jī)****************
- * 編寫(xiě):HYH
- * 日期:2017-6-12
- * 晶振:12mhz
- * 說(shuō)明:定時(shí)/計(jì)數(shù)器0固定每2.5ms溢出中斷,負(fù)責(zé)拉高對(duì)
- * 應(yīng)端口,定時(shí)/計(jì)數(shù)器1負(fù)責(zé)在tc1中斷產(chǎn)生后將對(duì)
- * 應(yīng)端口的電平拉低,依次循環(huán)形成八個(gè)通道舵機(jī)
- * 控制pwm波
- *****************************************************/
- #include <iom16v.h>
- #include <macros.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define OUTPUT PORTD //定義pd口為舵機(jī)信號(hào)輸出口
- #define ADCN ADMUX
- unsigned char output_high[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //數(shù)組控制各個(gè)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]; //存取八個(gè)通道的ADC值
- unsigned int adcn_change[8]; //存儲(chǔ)adcn_[]經(jīng)過(guò)轉(zhuǎn)換成計(jì)數(shù)器1初值的值
-
- /************延時(shí)函數(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ī)信號(hào)輸出端口
- DDRA&=0X00;
- PORTA|=0Xff; //設(shè)置adc通道端口,帶上拉輸入
- SREG=0X80; //開(kāi)放全局中斷
- }
- 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); //無(wú)預(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); //開(kāi)始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();
- }
- /*********定時(shí)器0中斷函數(shù)************
- * 說(shuō)明:定時(shí)器每溢出一次,舵機(jī)通道調(diào)
- * 至下一個(gè),拉高該舵機(jī)通道io口
- * 并把對(duì)應(yīng)通道的adcn_change[]值
- * 賦給定時(shí)/計(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;
- }
- /************定時(shí)/計(jì)數(shù)器1中斷函數(shù)********
- * 說(shuō)明:將對(duì)應(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)化為定時(shí)/計(jì)數(shù)器1初值,控制高電平持續(xù)時(shí)間
- 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
|
評(píng)分
-
查看全部評(píng)分
|