找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 7026|回復(fù): 7
打印 上一主題 下一主題
收起左側(cè)

ATmega16實(shí)現(xiàn)八個(gè)電位器分別同時(shí)控八個(gè)舵機(jī),還可以更多

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
  上回用了一個(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è)可用:

  1. /**************八通道電位器控制八舵機(jī)****************
  2. *   編寫(xiě):HYH
  3. *   日期:2017-6-12
  4. *   晶振:12mhz
  5. *   說(shuō)明:定時(shí)/計(jì)數(shù)器0固定每2.5ms溢出中斷,負(fù)責(zé)拉高對(duì)
  6. *         應(yīng)端口,定時(shí)/計(jì)數(shù)器1負(fù)責(zé)在tc1中斷產(chǎn)生后將對(duì)
  7. *         應(yīng)端口的電平拉低,依次循環(huán)形成八個(gè)通道舵機(jī)
  8. *         控制pwm波
  9. *****************************************************/
  10. #include <iom16v.h>
  11. #include <macros.h>

  12. #define  uchar unsigned char
  13. #define  uint  unsigned int

  14. #define OUTPUT PORTD         //定義pd口為舵機(jī)信號(hào)輸出口
  15. #define ADCN ADMUX         

  16. unsigned char output_high[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //數(shù)組控制各個(gè)io口高電平
  17. unsigned int i=0;
  18. unsigned int j=0;
  19. unsigned char ADCN_[8]={0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47};  //數(shù)組控制ADC通道選擇
  20. unsigned int adcn_[8];     //存取八個(gè)通道的ADC值
  21. unsigned int adcn_change[8];    //存儲(chǔ)adcn_[]經(jīng)過(guò)轉(zhuǎn)換成計(jì)數(shù)器1初值的值
  22.         
  23. /************延時(shí)函數(shù)***********/
  24. void delay(unsigned int ms)
  25. {
  26.         unsigned int i,j;
  27.         for(i=0;i<ms;i++)
  28.            {
  29.            for(j=0;j<1141;j++);
  30.        }
  31. }
  32. /*********端口設(shè)置函數(shù)*********/
  33. void port_init(void)
  34. {
  35.         DDRD|=0XFF;
  36.         PORTD&=0X00;        //設(shè)置舵機(jī)信號(hào)輸出端口
  37.     DDRA&=0X00;   
  38.     PORTA|=0Xff;          //設(shè)置adc通道端口,帶上拉輸入
  39.         SREG=0X80;             //開(kāi)放全局中斷
  40. }
  41. void timer0_init()
  42. {
  43.         TIMSK|=(1<<TOIE0);                //是能溢出中斷
  44.         TCCR0|=(1<<CS02)|(0<<CS01)|(0<<CS00); //12mhz晶振  256預(yù)分頻
  45.         TCNT0=139;   
  46.                           //計(jì)數(shù)器初值,(256-139)/(12mhz/256)=2.5ms
  47. }
  48. void timer1_init()
  49. {
  50.     TCCR1A|=0X00;               //普通模式
  51.         TCCR1B|=(0<<CS12)|(0<<CS11)|(1<<CS10);     //無(wú)預(yù)分頻   
  52.     TIMSK|=(1<<TOIE1);
  53. }

  54. /**********ad轉(zhuǎn)換函數(shù)**********/
  55. unsigned int ADC_init()
  56. {
  57.     unsigned int addata;                        
  58.          ADCN=ADCN_[j];                                          //AVCC為基準(zhǔn)電,設(shè)置adc通道選擇
  59.          ADCSRA=0XD8;                                         //使能ADC,允許中斷 11011000
  60.          ADCSRA|=BIT(ADSC);                                //開(kāi)始A/D轉(zhuǎn)換
  61.          while(!(ADCSRA&(BIT(ADIF))));        //等待轉(zhuǎn)換完成
  62.      addata=ADCL;                                //獲取ADC結(jié)果
  63.          addata=addata+ADCH*256;
  64.          return addata;                        //返回ADC值
  65. }   

  66. void main()
  67. {
  68.         timer0_init();
  69.         timer1_init();
  70.         ADC_init();
  71.         port_init();
  72. }
  73. /*********定時(shí)器0中斷函數(shù)************
  74. *   說(shuō)明:定時(shí)器每溢出一次,舵機(jī)通道調(diào)
  75. *         至下一個(gè),拉高該舵機(jī)通道io口
  76. *         并把對(duì)應(yīng)通道的adcn_change[]值
  77. *         賦給定時(shí)/計(jì)數(shù)器初值
  78. ************************************/
  79. #pragma interrupt_handler timer0_ovf:10
  80. void timer0_ovf()
  81. {
  82.     OUTPUT|=output_high[i];
  83.     TCNT0=139;
  84.         TCNT1=adcn_change[i];
  85.         i++;
  86.         if(i>=8)
  87.         i=0;
  88. }
  89. /************定時(shí)/計(jì)數(shù)器1中斷函數(shù)********
  90. *    說(shuō)明:將對(duì)應(yīng)端口電平拉高
  91. ****************************************/
  92. #pragma interrupt_handler timer1_ovf:9
  93. void timer1_ovf()
  94. {   
  95.     TCNT1=0;
  96.         if(i==0)
  97.     OUTPUT&=~BIT(7);
  98.         else
  99.         OUTPUT&=~BIT(i-1);
  100. }
  101. /************ADC中斷函數(shù)**************/
  102. #pragma interrupt_handler ADCN_change:15
  103. void ADCN_change()
  104. {
  105.     adcn_[j]=ADC_init();
  106.         adcn_change[j]=59536-24*adcn_[j];     //將adc值轉(zhuǎn)化為定時(shí)/計(jì)數(shù)器1初值,控制高電平持續(xù)時(shí)間
  107.     j++;
  108.         if(j>=8)
  109.         j=0;
  110.         ADC_init();               //adc轉(zhuǎn)換
  111. }
復(fù)制代碼




全部資料下載地址:
ADC多通道.zip (537.96 KB, 下載次數(shù): 32)



評(píng)分

參與人數(shù) 1黑幣 +100 收起 理由
admin + 100 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏4 分享淘帖 頂 踩

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:1 發(fā)表于 2017-6-12 15:59 | 只看該作者
好資料,51黑有你更精彩!!!
回復(fù)

使用道具 舉報(bào)

板凳
ID:87734 發(fā)表于 2017-8-15 15:47 | 只看該作者
哇,思路清晰啊,舅服你
回復(fù)

使用道具 舉報(bào)

地板
ID:87734 發(fā)表于 2017-8-15 19:58 | 只看該作者
多個(gè)數(shù)字舵機(jī)控制,樓主講下具體思路嗎?我不管小板凳已經(jīng)拿來(lái)了
回復(fù)

使用道具 舉報(bào)

5#
ID:76408 發(fā)表于 2018-1-31 16:23 | 只看該作者
金幣不足了,先收藏了。
回復(fù)

使用道具 舉報(bào)

6#
ID:76408 發(fā)表于 2018-2-25 16:08 | 只看該作者
終于可以下載到了,謝謝樓主。
回復(fù)

使用道具 舉報(bào)

7#
ID:206921 發(fā)表于 2018-3-8 12:48 | 只看該作者
數(shù)字舵機(jī)區(qū)別于傳統(tǒng)的模擬舵機(jī),模擬舵機(jī)需要給它不停的發(fā)送PWM信號(hào),才能讓它保持在規(guī)定的位置或者讓它按照某個(gè)速度轉(zhuǎn)動(dòng),數(shù)字舵機(jī)則只需要發(fā)送一次PWM信號(hào)就能保持在規(guī)定的某個(gè)位置
回復(fù)

使用道具 舉報(bào)

8#
ID:33897 發(fā)表于 2018-3-10 16:45 | 只看該作者
好資料,51黑有你更精彩!!!
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表