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

專注電子技術(shù)學習與研究
當前位置:單片機教程網(wǎng) >> MCU設(shè)計實例 >> 瀏覽文章

基于Mega128編碼器控制步進電機的平衡系統(tǒng)

作者:佚名   來源:本站原創(chuàng)   點擊數(shù):  更新時間:2011年11月10日   【字體:

    提起編碼器,可能大家并不陌生,因為這東西真的很常用,現(xiàn)在的主流編碼器一般精度都是比較高的,基本上都是基于光柵的。畢竟用硬件用電刷做到512精度以上是很困難的,而且成本也是很高的,這里我就不多說什么了。

    編碼器一般共有三個主通道,每個主通道有分為兩個分支;一個VCC,一個GND,一條屏蔽線。前兩個通道一般是比較精確的脈沖信號,且之間有四分之一左右的相位差用來判斷正反轉(zhuǎn)的,第三通道基本上是旋轉(zhuǎn)一周才會有一個脈沖信號的那種。

 
    提到步進電機,就一定要有一個合適的電機驅(qū)動,個人是比較喜歡用L298n這款芯片的,因為它價格低,操作比較簡單。
 
    對于這個系統(tǒng),我是用128的外部中斷的下降沿觸發(fā)方式來捕捉編碼器的脈沖的,硬件連接方面電機驅(qū)動和主控芯片一定要注意地線的連接。
 
    下面是程序的完整代碼下載地址: http://www.zg4o1577.cn/f/bmma.rar         

 
這里是delay.h
====================================================================
//根據(jù)CPU時鐘頻率選擇
#ifndef F_CPU
//#define F_CPU 7372800
//#define F_CPU 8000000
//#define F_CPU 11059200
//#define F_CPU 12000000
#define F_CPU 16000000
#endif



//------------------------------------------------------------------------------
//1、2、3、5和10us的精確延時,用于需要精確時間的場合,比如DS18B20
//------------------------------------------------------------------------------
#if   F_CPU == 7372800
#define DELAY_1US NOP();NOP();NOP();NOP();NOP();NOP();NOP()
#define DELAY_2US DELAY_1US;DELAY_1US
#define DELAY_3US DELAY_1US;DELAY_1US;DELAY_1US
#define DELAY_5US DELAY_2US;DELAY_3US
#define DELAY_10US DELAY_5US;DELAY_5US

#elif F_CPU == 8000000
#define DELAY_1US NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP()
#define DELAY_2US DELAY_1US;DELAY_1US
#define DELAY_3US DELAY_1US;DELAY_1US;DELAY_1US
#define DELAY_5US DELAY_2US;DELAY_3US
#define DELAY_10US DELAY_5US;DELAY_5US

#elif F_CPU == 11059200
#define DELAY_1US NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP()
#define DELAY_2US DELAY_1US;DELAY_1US
#define DELAY_3US DELAY_1US;DELAY_1US;DELAY_1US
#define DELAY_5US DELAY_2US;DELAY_3US
#define DELAY_10US DELAY_5US;DELAY_5US

#elif F_CPU == 12000000
#define DELAY_1US NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP()
#define DELAY_2US DELAY_1US;DELAY_1US
#define DELAY_3US DELAY_1US;DELAY_1US;DELAY_1US
#define DELAY_5US DELAY_2US;DELAY_3US
#define DELAY_10US DELAY_5US;DELAY_5US

#elif F_CPU == 16000000
#define DELAY_1US NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP()
#define DELAY_2US DELAY_1US;DELAY_1US
#define DELAY_3US DELAY_1US;DELAY_1US;DELAY_1US
#define DELAY_5US DELAY_2US;DELAY_3US
#define DELAY_10US DELAY_5US;DELAY_5US
#endif


//------------------------------------------------------------------------------
//函數(shù)聲明
//------------------------------------------------------------------------------

void delay_nus(unsigned int);//<10us時誤差較大,用于無須精確延時的場合

void delay_nms(unsigned int);


#endif//__DELAY_H


====================================================================
 這里是delay.c
====================================================================
//|文件名稱|delay.c
//|--------|--------------------------------------------------------------------
//|描    述|延時文件
//|--------|--------------------------------------------------------------------
//|說    明|delay_us(unsigned int time)用于不需精確定時的場合,<10us時誤差較大
//|        |若要精確定時用delay.h里的宏
//|--------|--------------------------------------------------------------------
//|調(diào)用文件|delay.h
//|--------|--------------------------------------------------------------------
//|作    者|
//|--------|--------------------------------------------------------------------
//|版    本|
//|--------|--------------------------------------------------------------------
//|時    間|
//|--------|--------------------------------------------------------------------
//|E-mail  |
//|--------|--------------------------------------------------------------------
//|開發(fā)環(huán)境|ICCAVR6.31
//==============================================================================

#include "delay.h"

#if F_CPU == 7372800
void delay_nus(unsigned int time)
{
  unsigned int i;
  for(i=0;i<time;i++)
  {
    NOP();
  }
}

void delay_nms(unsigned int time)
{
  unsigned int i,j;
  for(i=0;i<time;i++)
  {
    for(j=0;j<1045;j++);
  }
}

#elif F_CPU == 8000000
void delay_nus(unsigned int time)
{
  unsigned int i;
  for(i=0;i<time;i++)
  {
    NOP();NOP();
  }
}

void delay_nms(unsigned int time)
{
  unsigned int i,j;
  for(i=0;i<time;i++)
  {
    for(j=0;j<1178;j++);
  }
}

#elif F_CPU == 11059200
void delay_nus(unsigned int time)
{
  unsigned int i;
  for(i=0;i<time;i++)
  {
    NOP();NOP();NOP();NOP();NOP();
  }
}

void delay_nms(unsigned int time)
{
  unsigned int i,j;
  for(i=0;i<time;i++)
  {
    for(j=0;j<1578;j++);
  }
}

#elif F_CPU == 12000000
void delay_nus(unsigned int time)
{
  unsigned int i;
  for(i=0;i<time;i++)
  {
    NOP();NOP();NOP();NOP();NOP();
  }
}

void delay_nms(unsigned int time)
{
  unsigned int i,j;
  for(i=0;i<time;i++)
  {
    for(j=0;j<1713;j++);
  }
}

#elif F_CPU == 16000000
void delay_us(unsigned int time)
{
  unsigned int i;
  for(i=0;i<time;i++)
  {
    NOP();NOP();NOP();NOP();NOP();NOP();
NOP();NOP();NOP();NOP();
  }
}

void delay_ms(unsigned int time)
{
  unsigned int i,j;
  for(i=0;i<time;i++)
  {
    for(j=0;j<2288;j++);
  }
}

#endif
====================================================================
 這里是dianji.h
====================================================================
#ifndef __DIANJI_H
#define __DIANJI_H

#define EN_1 PORTC|=(1<<0)
#define EN_0 PORTC&=~(1<<0)

void one_circle(void);
void circle(unsigned int xcircle);

#endif

====================================================================
 這里是dianji.c
====================================================================
#include"dianji.h"
#include"delay.h"
#include<iom128v.h>


/*步進電機旋轉(zhuǎn)一周子函數(shù)*/
void one_circle(void)
{
  unsigned int i;
for(i=0;i<3200;i++)
{
EN_1;
delay_us(100);
EN_0;
delay_us(100);
}
}
/*步進電機根據(jù)編碼器計算的數(shù)值旋轉(zhuǎn)任意角度子函數(shù)*/
void circle(unsigned int xcircle)
{
  unsigned int i,j;
for(j=0;j<xcircle;j++)
{
for(i=0;i<3;i++)
{
   EN_1;
delay_us(100);
EN_0;
delay_us(100);
}
}
}
====================================================================
 這里是caiji.h
====================================================================
#ifndef __CAIJI_H
#define __CAIJI_H

 //宏定義595
#define SCK_0 PORTB&=~(1<<PB4)
#define SCK_1 PORTB|=(1<<PB4)
#define LCK_0 PORTB&=~(1<<PB5)
#define LCK_1 PORTB|=(1<<PB5)
#define SDI_0 PORTB&=~(1<<PB6)
#define SDI_1 PORTB|=(1<<PB6) 

#define DIR_0 PORTC&=~(1<<1)
#define DIR_1 PORTC|=(1<<1)


void init_xianshi(void);
void send_595(unsigned char dat);
void jiaoduzhuanhuan(void);


#endif

====================================================================
 這里是caiji.c
====================================================================
#include"caiji.h"
#include"dianji.h"
#include<iom128v.h>
#include<macros.h>
#include<math.h>

//一些變量的定義
int k=0;
unsigned int x=1,d=0,c=0,cir=0;
unsigned int a,aa,q,angle=0,p=0;
//595(數(shù)碼管)顯示數(shù)組
unsigned char led[]=
{
0x3F, // 0
0x06, // 1
0x5B, // 2
0x4F, // 3
0x66, // 4
0x6D, // 5
0x7D, // 6
0x07, // 7
0x7F, // 8
0x6F, // 9
};
//外部中斷0~3向量號碼
#pragma interrupt_handler Zhongduan_0:2
#pragma interrupt_handler Zhongduan_1:3
#pragma interrupt_handler Zhongduan_2:4

//端口輸入輸出初始化
void init_xianshi(void)
{
DDRA=0XFF;
DDRB=0XFF;//595控制口
DDRC=0XFF;//正反轉(zhuǎn)提示LED
PORTC=0XFF;//LED初始化(暗)
}


//595串入一字節(jié)并處發(fā)送一字節(jié)子函數(shù)
void send_595(unsigned char dat)
{
   unsigned char i;
   LCK_0;
   SDI_1;
   SCK_0;
   //上面的三條語句為了初始化端口狀態(tài)
   for(i=0;i<8;i++)
   {
    LCK_0;//時鐘線拉低
 
    if(dat&0x80)
        SDI_1;
     else SDI_0;
     dat=dat<<1;
   delay_us(100);  
    LCK_1;          //時鐘線拉高將數(shù)據(jù)讀入595的移位寄存器    
    delay_us(100); 
   }
   SCK_1; //發(fā)送數(shù)據(jù)到并行端口
   SCK_0;   
}

void jiaoduzhuanhuan(void)
{
  init_xianshi();
  EIMSK=0X0F;
  EICRA=0XAA; 
 while(1)
  { 
 if(a!=aa) /*如果有角度變化就執(zhí)行下面的程序*/
 {
angle++;
 
if(!(PING&0X04))
cir++; 
while(cir)
{
if(!k)
  {
   delay_ms(800);
 if(d<=3)
     one_circle();
 d++;
  }
 }  
 
 if(!(PING&0X02))
 {
 while(PING&0X01)
 {
   DIR_0;
  circle(1);
   p++;
   while(p==angle);
 }
  while(PING&0X01);
 if(q=-1)//正轉(zhuǎn)
 DIR_1;
 circle(1);

 if(q==1)  //反轉(zhuǎn)
 DIR_1;
 }
 
  aa=a;
 

  if(!x)
  {
PORTC=0X00;
  }
  }
  /*下面為數(shù)碼管顯示編碼器當前計數(shù)的數(shù)值*/
  PORTA=0X08; 
  send_595(0x00);
  send_595(led[abs(k)%10]);
  PORTA=0X01; 
  send_595(0x00);
  send_595(led[(abs(k)%100)/10]);
  PORTA=0X02; 
  send_595(0x00);
  send_595(led[(abs(k)%1000)/100]);
  PORTA=0X04; 
  send_595(0x00);
  send_595(led[abs(k)/1000]);
SEI(); /*使能中斷*/
  } 
}

 void Zhongduan_0(void)
 {
  CLI();
  x=0;
 ////////////////// 
  if(PIND&0X02)
  q=-1;
  if(!(PIND&0X02))
  q=1;
  ////////////////
  k=k+q;
  SEI();
 }

 void Zhongduan_1(void)
 {
 CLI();

 if(PIND&0X01)
 q=1;
 k=k+q;
 if(abs(k)==10000)
 {
   k=0;
 }
 a=k;
 //EIMSK=0X0E;
 SEI();
 }
 void Zhongduan_2(void)
 {
  CLI();
  k=0;
  SEI();
  }
====================================================================
 這里是main.c
====================================================================
#include<iom128v.h>
#include<macros.h>
#include"delay.h"
#include"caiji.h"
#include"dianji.h"

void init(void)
{
  DDRC=0X03;
PORTC=0X00;
}

void main(void)
{
  init();     //初始化子函數(shù)
  jiaoduzhuanhuan(); //主程序的實現(xiàn)
}
====================================================================
程序中涉及到了一些嵌套,如果不明白的話可以給我留言哦!^_^
關(guān)閉窗口

相關(guān)文章

主站蜘蛛池模板: 欧美a级成人淫片免费看 | 精品欧美乱码久久久久久1区2区 | 黄色毛片一级 | 日批免费在线观看 | 亚洲乱码一区二区三区在线观看 | 欧美日韩中文国产一区发布 | 精品国产乱码久久久久久果冻传媒 | 91欧美精品成人综合在线观看 | 国产精品国产三级国产aⅴ无密码 | 国户精品久久久久久久久久久不卡 | 中文字幕精品一区二区三区精品 | 亚av在线 | 91精品久久久久 | 国产成人精品久久久 | 污书屋| 久久久国产一区 | 精品欧美一区二区三区久久久小说 | 免费毛片网站 | 欧美三级不卡 | 国产成人精品亚洲日本在线观看 | 欧美一区二区另类 | 日韩欧美精品 | 日韩网站在线观看 | 日韩av成人在线观看 | 一级片免费网站 | 亚洲国产日韩欧美 | 成人免费视频观看视频 | 91免费高清 | 亚洲欧美日韩久久 | 黄色成人免费看 | 97国产精品 | 欧美一级艳情片免费观看 | 亚洲bt 欧美bt 日本bt | 黄色男女网站 | www国产亚洲精品 | 黄色片视频免费 | 超碰综合| 久久久久欧美 | 日韩一区二区免费视频 | 91久久国产综合久久 | 亚洲一区二区三区视频 |