铜河 发表于 2013-3-9 19:49:33

基于M16的步进电机驱动实验程序

/************************************
* 步进电机的M16驱动程序 *
* 功 能:用M16驱动步进电机 *
* 实现三种驱动方式 *
* 单四拍驱动、双四拍驱动 *
* 单双八拍驱动 *
* 驱动芯片:ULN2803 *
* 联接方式:PC0-3分别通过2803接A-D *
* 步进电机公共端接+5V电源 *
* 建立日期:2008年04月05日 *
* 作 者:铜河 *
* 版 本:V1.0 *
* 修改日期:2008年04月06日 *
* 主控芯片:M16 *
* 时钟频率:外部晶体 7.3728MHZ *
* 编 译 器:ICCAVR 6.31A *
************************************/
#include <iom16v.h>
#include <macros.h>
#include "delay.h"
#define RD_KEY() ((~(PINC|0x0F))>>4)//四按键接于PC4-PC7
unsigned char i=0; //转动计数
unsigned char m=1; //驱动方式参数
unsigned char n=0; //转动方向参数
unsigned int zhuansu=61500; //转速数据
/****************************
* 端口配置函数 *
****************************/
void port_init(void)
{
PORTA = 0x40;
DDRA = 0x40;
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0xF0;
DDRC = 0x0F;
PORTD = 0x00;
DDRD = 0x00;
}
/****************************
* 正转操作函数 *
* 入 口:a 三种工作方式 *
****************************/
void bj_fs(unsigned char a)
{
switch(a)
{
case 1: //单四拍方式驱动
PORTC |= 1<<i; //A、B、C、D驱动
i++;
if(i>=4)i=0;
break;
case 2: //双四拍方式驱动
if(i!=4) //AB、BC、CD、DA驱动
PORTC |= (1<<i)|(1<<(i-1));
else
PORTC |= (1<<(i-1))|1;
i++;
if(i>=5)i=1;
break;
case 3: //单双八拍方式驱动
if(i%2) //A、AB、B、BC、C、CD、D、DA驱动
{
if(i!=7)
PORTC |= (1<<(i/2))|(1<<(i/2+1));
else
PORTC |= (1<<(i/2))|1;
}
else
{
PORTC |= 1<<(i/2);
}
i++;
if(i>=8)i=0;
break;
default:break;
}
}
/****************************
* 反转操作函数 *
* 入 口:a 三种工作方式 *
****************************/
void bj_fsf(unsigned char a)
{
switch(a)
{
case 1: //单四拍方式驱动
PORTC |= 1<<(3-i); //D、C、B、A驱动
i++;
if(i>=4)i=0;
break;
case 2: //双四拍方式驱动
if(i!=4) //AD、CD、BC、AB驱动
PORTC |= (1<<(3-i))|(1<<(4-i));
else
PORTC |= (1<<(i-1))|1;
i++;
if(i>=5)i=1;
break;
case 3: //单双八拍方式驱动
if(i%2) //DA、D、CD、C、BC、B、AB、A驱动
{
PORTC |= 1<<(3-i/2);
}
else
{
if(i)
PORTC |= (1<<(3-i/2))|(1<<(4-i/2));
else
PORTC |= (1<<(3-i/2))|1;
}
i++;
if(i>=8)i=0;
break;
case 4:

default:break;
}
}
/****************************
* 定时器1配置函数 *
* 工作模式:普通模式 *
* 工作方式:溢出中断 *
* 预 分 频:64 *
* 时钟频率:外部7.3728MHZ *
****************************/
void timer1_init(void)
{
TCCR1B = 0x00;
TCNT1H = zhuansu>>8;
TCNT1L = zhuansu&0xFF;
TCCR1A = 0x00;
TCCR1B = 0x02;
}
/****************************
* 定时器1中断函数 *
****************************/
#pragma interrupt_handler timer1_ovf_isr:9
void timer1_ovf_isr(void)
{
TCNT1H = zhuansu>>8;
TCNT1L = zhuansu&0xFF;
PORTC &= 0xF0;
if(n)
bj_fsf(m); //反转
else
bj_fs(m); //正转
}
/****************************
* 器件初始化函数 *
****************************/
void init_devices(void)
{
CLI();
port_init();
timer1_init();
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x04;
SEI();
}
/****************************
* 主函数 *
****************************/
void main(void)
{
unsigned char key,key1;
init_devices();
// asm("sbi 0x15,7");
// asm("nop");

while(1)
{
key=RD_KEY(); //按键扫描
if(key)
{
delay_ms(20);
key1=RD_KEY();
if(key==key1)
{
switch(key) //按键有效,相应处理
{
case 0x01: //S1键处理:转速增加
zhuansu += 100;
if(zhuansu>62000)zhuansu=62000;
break;
case 0x02: //S2键处理:转速降低
zhuansu -= 100;
if(zhuansu<5000)zhuansu=5000;
break;
case 0x04: //S3键处理:转换驱动方式
m++;
if(m>=4)m=1;
break;
case 0x08: //S4键处理:正反转控制
if(n)
n=0;
else
n=1;
break;
default:break;
}
}
while(key) //等待按键释放
{
delay_ms(10);
key=RD_KEY();
}
}
}
}

铜河 发表于 2013-3-9 19:52:42

其中延时函数就是普通的简单延时。
//延时函数
#include <iom16v.h>

//数据简化宏定义
#define uchar unsigned char
#define uint unsigned int

/***********************************
*         微秒级延时函数                   *
* 入口参数:i 需延时时长  us           *
* 最大延时:65536 us                             *
* 时钟频率:7.3728M 其它频率不适用 *                  
***********************************/
void delay_us(uint i)
    {
        while(i)
            {
                i--;
                NOP();
                NOP();
                NOP();
                }
        }

/***********************************
*         毫秒级延时函数                   *
* 入口参数:i 需延时时长  ms           *
* 最大延时:65536 ms                             *
* 时钟频率:7.3728M 其它频率不适用 *          
***********************************/
void delay_ms(uint i)
    {
        uint a;
        for(;i;i--)
            {
                for(a=1143;a;a--)
                    {;}
                }
        }

箫天 发表于 2013-3-9 20:06:47

我是来抢沙发的,抢完才发现沙发没了。

oneway 发表于 2013-3-9 22:03:30

给铜爷顶起
页: [1]
查看完整版本: 基于M16的步进电机驱动实验程序