这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 合作大赛 » AVR单片机驱动二相步进电机(单极驱动)简易程序,带串口控制

共1条 1/1 1 跳转至

AVR单片机驱动二相步进电机(单极驱动)简易程序,带串口控制

高工
2015-06-14 13:39:01     打赏

AVR单片机驱动二相步进电机(单极驱动)简易程序,带串口控制。
编译器为ICC6.31A;
#include"iom16v.h"
#include"macros.h"
#define uint unsigned int
#define uchar unsigned char
#pragma interrupt_handler usart:14
uchar i;
uchar  const *p;
uchar zf=1; //电机正反转标志;
uchar  k1=5;
//uchar const timer2dath[10]={};
//uchar const timer2datl[10]={};
unsigned char const suzhu1[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
                      0x77,0x7c,0x39,0x5e,0x79,0x71};
uchar const bjdjdat[48]={0x80,0xa0,0x20,0x60,0x40,0x50,0x10,0x90,
                           0x80,0x90,0x10,0x50,0x40,0x60,0x20,0xa0,
         0x80,0x20,0x40,0x10,0x80,0x20,0x40,0x10,
         0x80,0x10,0x40,0x20,0x80,0x10,0x40,0x20,
         0xa0,0x60,0x50,0x90,0xa0,0x60,0x50,0x90,
         0xa0,0x90,0x50,0x60,0xa0,0x90,0x50,0x60
          };//设置单片机IO口高低电平数据组,用以驱动步进电机的各相按需通电;
uint const timer1dat[11]={36000,23000,13000,7000,4300,3000,2500,2100,1800,1700,0};//定时器1定时数据,用于控制电机的转速,定时越短转速越快;            
uchar uartdat[4]={0,0,0,0}; //划出串行通信时所需的寄存器;
uchar add,open,jslopen;
void siansi(unsigned int dat,unsigned char bit,unsigned int time)//数码管显示函数
{
 //PORTA&=~BIT(4);
 PORTC&=~BIT(7);
 PORTA&=~0x17;
 PORTB=suzhu1[dat];
 PORTA|=bit ;
 PORTA|=BIT(4);
 PORTC|=BIT(7);
 while(time--);
 
}        
void ioinit()//IO口初始化;
{
 DDRB=0XFF;
 DDRD=0XF3;
 DDRA|=0X17;
 DDRC|=0X80;
 PORTD|=0X0f;
}
void usart()//串行接收中断处理;
{
 uchar a;
 a=UDR;
 if(a==168)
 {
  open=1;
  add=0;
 }
 if(a==138&&open)
 {
  open=0;
  uartdat[add]=a;
  jslopen=1;
 }
if(open)
{
uartdat[add]=a;
 add++;
}
}
void jsl()//一帧数据处理;
 {
 uchar j;
 jslopen=0;
 switch(uartdat[1])
 {
  case 1:
  if(uartdat[2])TIMSK|=0X04;
  else TIMSK&=~0X04;
  break;
  case 2:
  if(uartdat[2]>0)
  k1=uartdat[2]-1;
  else k1=10;
  break;
  case 3:
  if(uartdat[2]&&!zf)p=p-8,zf=1;
  if(!uartdat[2]&&zf)p=p+8,zf=0;
  break;
  case 4:
 if(uartdat[2]==1&&zf)p=bjdjdat;
 if(uartdat[2]==1&&!zf)p=bjdjdat+8;
 if(uartdat[2]==2&&zf)p=bjdjdat+16;
 if(uartdat[2]==2&&!zf)p=bjdjdat+24;
 if(uartdat[2]==3&&zf)p=bjdjdat+32;
 if(uartdat[2]==3&&!zf)p=bjdjdat+40;
  break;
 }
 for(j=0;j<4;j++)
 {
  /* 等待发送缓冲器为空 */
  while ( !( UCSRA & (1<<UDRE)) )
 ;
 /* 将数据放入缓冲器,发送数据 */
 UDR=uartdat[j];
 }
 }
void uartinit()//串行口初始化;
{
 UCSRA=0X00;
 UCSRB=0X98;
 UCSRC=0X86;
 UBRRH=0X00;
 UBRRL=71;
 SREG|=0X80;
}
#pragma interrupt_handler timer1:9 
void timer1() //定时器1中断处理;
{
 TCNT1=65536-timer1dat[k1];
 i++;
 if(i>7)i=0;
 PORTD&=0X0F;
 if(k1==10)return;
 PORTD|=p[i];
}
void timer1init()
{
 TCCR1A=0X00;
 TCCR1B=0X02;
 TIMSK|=0X04;
}
void main(void)//主程序;
{
 p=bjdjdat;
 uartinit();
 ioinit();
 timer1init();
 while(1)
 {
  siansi(timer1dat[k1]%10,7,1000);
  siansi(timer1dat[k1]%100/10,6,1000);
  siansi(timer1dat[k1]%1000/100,5,1000);
  siansi(timer1dat[k1]%10000/1000,4,1000);
  siansi(timer1dat[k1]/10000,3,1000);
  if(zf)siansi(14,2,1000);
  else siansi(15,2,1000);
  if(jslopen)jsl();
 
 }
}



共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]