欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5245|回復: 6
打印 上一主題 下一主題
收起左側

avr單片機m16用一個定時器實現一個多個電位器控制多個舵機

[復制鏈接]
跳轉到指定樓層
樓主
ID:206921 發表于 2017-6-1 23:50 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
最近在研究多個舵機的控制,上網找了很多資料,編寫了一個程序,用三個電位器分別控制三個舵機,只用tc0定時計數器,最后無法實現,原理是對的,不知道哪里出了問題,程序如下:
#include <iom16v.h>
#include <macros.h>
#include "1602LCD_drive.h"
//unsigned char line1_data[]={"ADC1:"};     //
//unsigned char line2_data[]={"ADC3:"};          
//unsigned char line3_data[]={"ADC2:"};                     
#define  uchar unsigned char
#define  uint  unsigned int
#define OUTPUT PORTC
#define SER0 0x01
#define SER1 0x02
#define SER2 0x04
#define ADCN ADMUX
#define ADC0 0x40
#define ADC1 0x41
#define ADC2 0x42
char Counter=1;
char num=0;
char time=0;
       

/************延時函數***********/
void delay(unsigned int ms)
{
        unsigned int i,j;
        for(i=0;i<ms;i++)
           {
           for(j=0;j<1141;j++);
       }
}
/*********端口設置函數*********/
void port_init(void)
{
     PORTB=0XFF;                        //設置1602端口的
     DDRB=0XFF;
    DDRD=0XFF;       
    PORTD=0Xff;       
    DDRC=0XFF;               //設置pc口為舵機pwm輸出
    PORTC|=0X00;
    DDRA&=0X00;                     //adc口設為輸入,帶上啦電阻
    PORTA|=0Xff;
}
void timer0_init()
{
        SREG=0X80;
        TIMSK|=(1<<TOIE0);                //是能溢出中斷
        TCCR0|=(0<<CS02)|(0<<CS01)|(1<<CS00); //12mhz晶振  無預分頻60/12m=5us
        TCNT0=0;                          //計數器初值
}

/**********ad轉換函數**********/
unsigned int adc_()
{
         unsigned int addata;                                
         ADMUX=0X40;                                          //AVCC為基準電,AD0為輸入通道 01000010
         ADCSRA=0XC0;                                         //使能ADC,自動連續轉換 11000000
         ADCSRA|=BIT(ADSC);                                //開始A/D轉換
         while(!(ADCSRA&(BIT(ADIF))));        //等待轉換完成
         addata=ADCL;                                //獲取ADC結果
         addata=addata+ADCH*256;
         return addata;                        //返回ADC值
}   

/**ADC通道轉換函數**/
uint adc_change()
{
     unsigned int ada, adcx;
         ada=adc_();
         adcx=ada/2.5+100;
         return adcx;
}


/********************主函數**********************/
void main()
{
        port_init();
        adc_();
        timer0_init();
       
        adc_change();
}

#pragma interrupt_handler timer0_ovf:10
void timer0_ovf()
{   
         TCNT0=196;            //重新賦值256-196=60,溢出一次等于5us
         adc_change();           //adc值轉換成counter計數值最大值
     Counter++;
         time++;            
         if(num==0&&Counter<=1)          //這里
         {
             ADCN=ADC0;                                 //設置adc通道為adc0
             OUTPUT|=SER0;                                  //輸出口為PC0
                 //k[0]=adc_change()/100;
             //k[1]=(adc_change()%100)/10;
             //LCD_write_char(14,1,k[0]+0x30);
             //LCD_write_char(15,1,k[1]+0x30);
                 
         }
                 
         if(num==1&&Counter<=1)
         {
             ADCN=ADC1;                 //adc通道為adc1
             OUTPUT|=SER1;           //修改輸出口為pc1
                 //k[0]=adc_change()/100;
             //k[1]=(adc_change()%100)/10;
             //LCD_write_char(5,1,k[0]+0x30);
             //LCD_write_char(6,1,k[1]+0x30);
               
         }
if(num==2&&Counter<=1)
         {
             ADCN=ADC2;           //adc通道為adc2
             OUTPUT|=SER2;            //輸出口為pc2
         }
if(Counter>=adc_change())          //如果計數值大于adc轉換值
         {     
                 OUTPUT&=0X00;                   //所有輸出口拉低
                 num=num+1;                     //num+1
                 Counter=0;                      //重新計數
                  if(num>=3)                       //num大于三所有c口拉低
                 OUTPUT&=0X00;
         }
       
         if(time>=4000)                //計數達到4000?4000*5us=20000us=20ms為舵機周期
        {
                 num=0;                     //全部重新賦值                       
                 time=0;
                  Counter=0;   
    }
}

小白一個,求大神指教!








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

相關帖子

回復

使用道具 舉報

沙發
ID:207004 發表于 2017-6-2 10:49 | 只看該作者
你可以用pmw波控制舵機

評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

無效樓層,該帖已經被刪除
地板
ID:207029 發表于 2017-6-2 11:44 | 只看該作者
你的問題很籠統!具體怎么無法實現?有哪些錯誤?體現在哪里?原理圖可否曬出來,否則怎么幫助你?單片機這個東西定制性很強,你單單拿出個程序我想神仙也幫不了你!

評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

5#
ID:206921 發表于 2017-6-2 13:07 | 只看該作者
jlqiu 發表于 2017-6-2 10:50
你可以用pmw波控制舵機

那個我會,現在要實現的是多個電位器分別控制多個舵機,采用的是模擬pwm波形,而不是用定時器的快速pwm

評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

6#
ID:206921 發表于 2017-6-2 14:05 | 只看該作者
zt2017 發表于 2017-6-2 11:44
你的問題很籠統!具體怎么無法實現?有哪些錯誤?體現在哪里?原理圖可否曬出來,否則怎么幫助你?單片機這 ...

你說的對,具體如下
m16芯片,12mhz晶振,電位器3個,舵機三個,
單片機的PA0~PA2口作為ADC輸入通道,分別接三個電位器,采用單端接入法,
PC0~PC2為舵機信號輸出腳,分別鏈接三個舵機的信號線
程序思路是這樣
設置定時器溢出中斷,使能ADC轉換,把得到的ADC值0~1000,通過adc_change()函數轉化成100~500,100*5us=0.5ms,500*5us=2.5ms,就是一個舵機的脈沖周期,
例如第一次轉換是ADC0,舵機通道SER0(pc0)電平拉高,得到的adc_change()的值為200(相當于脈沖周期200*5us=1ms),賦給Counter,定時器TCNT0初值為196,經過200次溢出,Counter的值達到200,
執行Counter清零,ADCN(ADC輸入通道選擇)重新賦值為ADC1,舵機通道SER1(pc1)拉高,
此時讀取ADC1的值,賦給Counter,再執行如上指令,直到第三通道的舵機脈沖完成,num大于3,所有pc口拉低
程序中每次計數器溢出,time+1,溢出4000次(4000*5us=20ms),為一個舵機控制周期,超過4000,次,time,Counter等清0,重新計數。

程序最后測試結果為,pc0端口保持高點平,pc1,pc2保持低電平,舵機就沒反應,電位器都檢查了,電路連接良好。可能是程序出錯。

評分

參與人數 1黑幣 +40 收起 理由
admin + 40 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

7#
ID:207004 發表于 2017-6-5 15:52 | 只看該作者
HYH520 發表于 2017-6-2 13:07
那個我會,現在要實現的是多個電位器分別控制多個舵機,采用的是模擬pwm波形,而不是用定時器的快速pwm

用仿真軟件調試過嗎?輸出方波符合舵機波形嗎?
回復

使用道具 舉報

8#
無效樓層,該帖已經被刪除
9#
ID:206921 發表于 2017-6-12 12:26 | 只看該作者
已實現八個電位器分別同時控制八個舵機,請看新帖
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表