圣龙扬特-AVR电子

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 1276|回复: 3
打印 上一主题 下一主题

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

[复制链接]

26

主题

1

好友

3446

积分

超级版主

Rank: 8Rank: 8

UID
7
帖子
140
精华
0
注册时间
2013-2-26
在线时间
20 小时

突出贡献

跳转到指定楼层
楼主
发表于 2013-3-9 19:49:33 |只看该作者 |倒序浏览
/************************************
* 步进电机的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();
}
}
}
}
回复

使用道具 举报

26

主题

1

好友

3446

积分

超级版主

Rank: 8Rank: 8

UID
7
帖子
140
精华
0
注册时间
2013-2-26
在线时间
20 小时

突出贡献

沙发
发表于 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--)
                    {;}
                }
        }
回复

使用道具 举报

67

主题

4

好友

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

UID
2
帖子
343
精华
0
注册时间
2013-2-20
在线时间
366 小时
板凳
发表于 2013-3-9 20:06:47 |只看该作者
我是来抢沙发的,抢完才发现沙发没了。
回复

使用道具 举报

1

主题

0

好友

652

积分

高级会员

Rank: 4

UID
21
帖子
45
精华
0
注册时间
2013-2-26
在线时间
11 小时
地板
发表于 2013-3-9 22:03:30 |只看该作者
给铜爷顶起
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

Archiver|手机版|圣龙扬特-AVR电子 ( 鲁ICP备05022832号 )

GMT+8, 2024-5-4 02:20 , Processed in 0.206816 second(s), 18 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部