[问答] 请问哪位大神可以分享带串口控制的AVR单片机驱动二相步进电机(单极驱动)的简易程序?

邓刚1234 ( 楼主 ) 2018-6-26 05:12:50  显示全部楼层
本帖最后由 一只耳朵怪 于 2018-6-26 11:05 编辑

  • 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;
  • }
  • 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();
  • }
  • }

0个回复

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

本版积分规则


关闭

站长推荐上一条 /9 下一条

小黑屋|手机版|Archiver|电子发烧友 ( 粤ICP备14022951号-2 )

GMT+8, 2018-9-24 14:06 , Processed in 0.555292 second(s), 23 queries , Memcache On.

Powered by 电子发烧友网

© 2015 bbs.elecfans.com

微信扫描
快速回复 返回顶部 返回列表