久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

增量式編碼器學習筆記(包含程序)

[復制鏈接]
跳轉到指定樓層
樓主
ID:80436 發表于 2015-5-21 22:47 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式



假設函數IS_PIN_A_HIGH()和IS_PIN_B_HIGH()是讀取A,B兩個引腳的狀態
假設有兩個外中斷INT0和INT1都已經配置為雙邊沿觸發模式,則解碼如下:
  • //! 編碼計數器
  • static volatile uint32_t s_wQDCounter = 0;
  • ISR(INT0_vect)
  • {
  •     if (IS_PIN_A_HIGH() && IS_PIN_B_HIGH()) {
  •         s_wQDCounter++;
  •     } else {
  •         s_wQDCounter--;
  •     }
  • }
  • ISR(INT1_vect)
  • {
  •     if (IS_PIN_A_HIGH() && IS_PIN_B_HIGH()) {
  •         s_wQDCounter--;
  •     } else {
  •         s_wQDCounter++;
  •     }
  • }


[color=rgb(51, 102, 153) !important]復制代碼

讀取全局變量s_wQDCounter的時候別忘記加入中斷保護。如果要追求效率,可以將計數器類型修改為uint16_t。

--------------------------
以上就是中斷法,可以用引腳電平變化中斷來做。上面的代碼是4倍頻。如果要2倍頻,去掉任何一個中斷處理程序即可。
如果要單倍頻,選擇任意一個外中斷,并選擇只對某個邊沿觸發即可。

多年測試,穩定可靠~
記住一句口訣:

任意邊沿觸發模式下,A和B進行電平比較:
對A觸發的中斷:同加異減
對B觸發的中斷:同減異加
反之亦然

總結到最后,就是 同加異減,同減異加


附工程
#include <avr/io.h>
#include <avr/interrupt.h>
unsigned int flag=0;
unsigned char count=0;
unsigned int num=0;
unsigned int GrayData=0;
unsigned int Hdata=0;
unsigned int Ldata=0;
#define set_bit(x,y) ((x)|=(1<<(y)))
#define clr_bit(x,y) ((x)&=~(1<<(y)))
#define PUL  PORTA ^= (1 << PA2)
static volatile unsigned int s_wQDCounter = 0;
// unsigned int s_wQDCounter = 0;
/*unsigned int  GtoB(unsigned int num)
{
        num ^= num >> 16;
    num ^= num >> 8;
        num ^= num >> 4;
        num ^= num >> 2;
        //num ^= num >> 1;
        return num^(num >> 1);
}  */

unsigned int GraytoDecimal(unsigned int x)
{
        unsigned int y = x;
        while(x>>=1)
        y ^= x;
        return y;
}

unsigned int DecimaltoGray(unsigned int x)
{
        return x^(x>>1);
}

unsigned int BinToInt(char *bin)
{
        unsigned int Value=0;
        while(*bin)
        {
        Value=Value<<1;
        Value += (*bin)-'0';
        bin++;
        };
        return Value;
}

//==================================================
const unsigned char seg[]={        0xC0, // 0
        0xF9, // 1
        0xA4, // 2
        0xB0, // 3
        0x99, // 4
        0x92, // 5
        0x82, // 6
        0xF8, // 7
        0x80, // 8
        0x90 // 9
};


//==================================================

//IO端口初始化
void PortInit(void)
{
        DDRA=0XFF;
        PORTA=0XFF;
        DDRB=0XFF;
        PORTB=0XFF;
        DDRC=0XFF;
        PORTC=0XFF;
    DDRD=0x00;
        PORTD=0XFF;
        //set_bit(PORTA,PA0);
       
       
}

//Timer0初始化
void Timer0Init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x06; //set count
OCR0  = 0xFA;  //set compare
TCCR0 = 0x03; //start timer
}

void int_init(void)//配置外部中斷
{
        MCUCR |= 0x05;
        MCUCSR|= 0x00;
        GICR  |= 0xC0;
}


//==================================================

//定時器0溢出中斷服務程序
ISR(TIMER0_OVF_vect) //4ms刷新顯示一次
{
        TCNT0=0X06;
        flag++;
        count++;

        switch(count)
        {
                case 1:if(num/1000){PORTA=0X01;PORTB=seg[num/1000];}else PORTB=0XFF;break;
                case 2:if(((num/1000)+(num%1000/100))){PORTA=0X02;PORTB=seg[num%1000/100];}else PORTB=0XFF;break;
                case 3:if(((num/1000)+(num%1000/100)+(num%100/10))){PORTA=0X04;PORTB=seg[num%100/10];}else PORTB=0XFF;break;
                case 4:PORTA=0X08;PORTB=seg[num%10];break;
                case 5:count=0;break;
                default:break;
        }
        num=s_wQDCounter;
       
}
unsigned char IS_PIN_A_HIGH(void)  //PD2 CHA //編碼器A相
{
if ((PIND&(1<<PD2))==0)return 1;
else return 0;

       
}
unsigned char IS_PIN_B_HIGH(void) //PD3 CHB 編碼器B相
{
if ((PIND&(1<<PD3))==0)return 1;
else return 0;
       
}
ISR(INT0_vect)
{  
        cli();
    if (IS_PIN_A_HIGH() && IS_PIN_B_HIGH()) {
        s_wQDCounter++;
    } else {
        s_wQDCounter--;
    }
        sei();
}

ISR(INT1_vect)
{
        cli();
    if (IS_PIN_A_HIGH() && IS_PIN_B_HIGH()) {
        s_wQDCounter--;
    } else {
        s_wQDCounter++;
    }
        sei();
}


//==================================================

//主函數
int main(void)
{
        cli();
        TIMSK = 0x01; //timer interrupt sources
        PortInit();
        Timer0Init();
        int_init();
        sei();
        while (1){;}
}
       



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

使用道具 舉報

沙發
ID:80436 發表于 2015-5-21 22:49 | 只看該作者
        位置式PID
#include "RobotLib.h"
#include "string.h"
typedef struct PID
{

float SetPoint;       // 設定目標 Desired Value
float  Proportion;   // 比例系數 Proportional Const
float Integral;     // 積分系數 Integral Const
float Derivative;  // 微分系數 Derivative Const
int LastError;    // 上次偏差
int PrevError;
int SumError;    // 歷史誤差累計值
} PID;


//PID 運算的C 實現代碼
float PIDCalc( PID *pp, int NextPoint )
{
int dError,Error;
Error = pp->SetPoint*10-NextPoint; // 偏差,設定值減去當前采樣值
pp->SumError += Error; // 積分,歷史偏差累加
dError = Error-pp->LastError; // 當前微分,偏差相減
pp->PrevError = pp->LastError; // 保存
pp->LastError = Error;
return (pp->Proportion * Error+ pp->Integral * pp->SumError-pp->Derivative * dError);
}
//其中(pp->Proportion * Error)是比例項;(pp->Integral * pp->SumError)是積分項;(pp->Derivative * dError)是微分。

void PIDInit (PID *pp)
{
    memset ( pp,0,sizeof(PID));
}
    
void actuator(int rdata)
{
;//PWMout
}
int main(void)
{
int output;
int input;
PID stPID; // 定義一個stPID 變量
PIDInit(&stPID);
stPID->Proportion=0.5;
stPID->Integral=0.5;
stPID->Derivative=0.0;
stPID->SetPoint=100;
   while(1)
   {
   input=AI(0);//模擬量輸入
   output=PIDCalc(&stPID,input);
   actuator(output);
   }

}
回復

使用道具 舉報

板凳
ID:467304 發表于 2019-1-13 12:06 | 只看該作者
請問增量式編碼器的輸出和格雷碼有關嗎?格雷碼不是絕對式編碼器才用到的 嘛?
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日本精品一区二区三区视频 | 亚洲aⅴ精品 | 免费在线观看成人 | 国产美女一区 | 国产精品91网站 | 久久国产精品99久久久久久丝袜 | 精品一级电影 | 欧美日韩国产一区二区三区 | 亚洲成人精品在线观看 | 欧美a在线 | 日韩中文字幕在线播放 | 国产露脸国语对白在线 | 欧美综合久久 | 欧美国产在线一区 | 欧美日韩视频在线第一区 | 草久久久 | 亚洲福利电影网 | 中文字幕综合 | 中文字幕第二十页 | 亚洲一区欧美一区 | 毛片a级 | 久久在线看 | 日日干日日色 | 精品视频在线一区 | 337p日本欧洲亚洲大胆精蜜臀 | 波多野结衣在线观看一区二区三区 | 狠狠涩| 99久久免费精品国产男女高不卡 | 自拍视频网 | 亚洲视频欧美视频 | 国产乱码精品1区2区3区 | 99reav | 日韩在线| 欧美一级片a | 日本小电影网站 | 精品麻豆剧传媒av国产九九九 | 在线āv视频 | 日韩精品成人在线 | 久久区二区 | 国产专区免费 | 国产最好的av国产大片 |