基于ATmega128編碼器控制步進電機的平衡系統(tǒng)
這里是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;itime;i++)
{
NOP();
}
}
void delay_nms(unsigned int time)
{
unsigned int i,j;
for(i=0;itime;i++)
{
for(j=0;j1045;j++);
}
}
#elif F_CPU == 8000000
void delay_nus(unsigned int time)
{
unsigned int i;
for(i=0;itime;i++)
{
NOP();NOP();
}
}
void delay_nms(unsigned int time)
{
unsigned int i,j;
for(i=0;itime;i++)
{
for(j=0;j1178;j++);
}
}
#elif F_CPU == 11059200
void delay_nus(unsigned int time)
{
unsigned int i;
for(i=0;itime;i++)
{
NOP();NOP();NOP();NOP();NOP();
}
}
void delay_nms(unsigned int time)
{
unsigned int i,j;
for(i=0;itime;i++)
{
for(j=0;j1578;j++);
}
}
#elif F_CPU == 12000000
void delay_nus(unsigned int time)
{
unsigned int i;
for(i=0;itime;i++)
{
NOP();NOP();NOP();NOP();NOP();
}
}
void delay_nms(unsigned int time)
{
unsigned int i,j;
for(i=0;itime;i++)
{
for(j=0;j1713;j++);
}
}
#elif F_CPU == 16000000
void delay_us(unsigned int time)
{
unsigned int i;
for(i=0;itime;i++)
{
NOP();NOP();NOP();NOP();NOP();NOP();
NOP();NOP();NOP();NOP();
}
}
void delay_ms(unsigned int time)
{
unsigned int i,j;
for(i=0;itime;i++)
{
for(j=0;j2288;j++);
}
}
#endif
這里是dianji.h
#ifndef __DIANJI_H
#define __DIANJI_H
#define EN_1 PORTC|=(10)
#define EN_0 PORTC=~(10)
void one_circle(void);
void circle(unsigned int xcircle);
#endif
這里是dianji.c
#include"dianji.h"
#include"delay.h"
#includeiom128v.h>
/*步進電機旋轉(zhuǎn)一周子函數(shù)*/
void one_circle(void)
{
unsigned int i;
for(i=0;i3200;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;jxcircle;j++)
{
for(i=0;i3;i++)
{
EN_1;
delay_us(100);
EN_0;
delay_us(100);
}
}
}
這里是caiji.h
#ifndef __CAIJI_H
#define __CAIJI_H
//宏定義595
#define SCK_0 PORTB=~(1PB4)
#define SCK_1 PORTB|=(1PB4)
#define LCK_0 PORTB=~(1PB5)
#define LCK_1 PORTB|=(1PB5)
#define SDI_0 PORTB=~(1PB6)
#define SDI_1 PORTB|=(1PB6)
#define DIR_0 PORTC=~(11)
#define DIR_1 PORTC|=(11)
void init_xianshi(void);
void send_595(unsigned char dat);
void jiaoduzhuanhuan(void);
#endif
這里是caiji.c
#include"caiji.h"
#include"dianji.h"
#includeiom128v.h>
#includemacros.h>
#includemath.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;i8;i++)
{
LCK_0;//時鐘線拉低
if(dat0x80)
SDI_1;
else SDI_0;
dat=dat1;
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(!(PING0X04))
cir++;
while(cir)
{
if(!k)
{
delay_ms(800);
if(d=3)
one_circle();
d++;
}
}
if(!(PING0X02))
{
while(PING0X01)
{
DIR_0;
circle(1);
p++;
while(p==angle);
}
while(PING0X01);
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(PIND0X02)
q=-1;
if(!(PIND0X02))
q=1;
////////////////
k=k+q;
SEI();
}
void Zhongduan_1(void)
{
CLI();
if(PIND0X01)
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
#includeiom128v.h>
#includemacros.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)
}
評論