基于STC11F02E 步进电机电路验证程序 (2)

昨天简单的把代码写完了,其实也超简单,主要及部分步进电机控制、UART通信。

 

 

DEV层

dev层为硬件层,主要和单片机寄存器打交道,完成I/O口初始化,uart初始化。

初始化i/o口

 默认51的准双向口,弱上拉驱动uln2803没问题。

void dev_init_pin(void)
{

	P1M1=0;P1M0=0; 
	P2M1=0;P2M0=0;
	P3M1=0;P3M0=0;
	
}

 

初始化uart

波特率:9600 数据位:8位 1停止位 无校验。而且串口开启中断接收发送,在main函数打开中断标志位。

void dev_init_uart(void)
{

	SCON=0X50;			
	TMOD=0X20;			
	TH1=-3;				//9600
	TL1=-3;
	ES=1;						
	EA=1;						
	TR1=1;					

}

HAL层

hal层为硬件抽象层,主要负责模块实例化。负责板级初始化、步进电机控制、ir-cut自控、内部flash操作。

步进电机控制

步进电机转一圈360°,64步。hal_turn_up_motor向上转头函数,向下、左、右函数类似我就不贴出来了。param t为步数。左右转337.5°,分五个位置,每转一位置15步;上下3个位置,每转一位置4步。

sbit HAL_MOTOR_UD_F1 =P1^2;
sbit HAL_MOTOR_UD_F2 =P1^1;
sbit HAL_MOTOR_UD_F3 =P1^0;
sbit HAL_MOTOR_UD_F4 =P3^7;

sbit HAL_MOTOR_LR_F1 =P1^6;
sbit HAL_MOTOR_LR_F2 =P1^5;
sbit HAL_MOTOR_LR_F3 =P1^4;
sbit HAL_MOTOR_LR_F4 =P1^3;


void delay(unsigned int t)
{                           
   unsigned int k;
   while(t--)
   {
     for(k=0; k<125; k++)
     { }
   }
}


void hal_turn_up_motor(unsigned int n)
{
	unsigned char i;
	unsigned int  j;
	
	for (j=0; j<8*n; j++){
		for (i=0; i<8; i++){
			switch(i){
				case 0:HAL_MOTOR_UD_F1=1;HAL_MOTOR_UD_F2=0;HAL_MOTOR_UD_F3=0;HAL_MOTOR_UD_F4=0;
							break;
				case 1:HAL_MOTOR_UD_F1=1;HAL_MOTOR_UD_F2=1;HAL_MOTOR_UD_F3=0;HAL_MOTOR_UD_F4=0;
							break;
				case 2:HAL_MOTOR_UD_F1=0;HAL_MOTOR_UD_F2=1;HAL_MOTOR_UD_F3=0;HAL_MOTOR_UD_F4=0;
							break;
				case 3:HAL_MOTOR_UD_F1=0;HAL_MOTOR_UD_F2=1;HAL_MOTOR_UD_F3=1;HAL_MOTOR_UD_F4=0;
							break;				
				case 4:HAL_MOTOR_UD_F1=0;HAL_MOTOR_UD_F2=0;HAL_MOTOR_UD_F3=1;HAL_MOTOR_UD_F4=0;
							break;
				case 5:HAL_MOTOR_UD_F1=0;HAL_MOTOR_UD_F2=0;HAL_MOTOR_UD_F3=1;HAL_MOTOR_UD_F4=1;
							break;	
				case 6:HAL_MOTOR_UD_F1=0;HAL_MOTOR_UD_F2=0;HAL_MOTOR_UD_F3=0;HAL_MOTOR_UD_F4=1;
							break;
				case 7:HAL_MOTOR_UD_F1=1;HAL_MOTOR_UD_F2=0;HAL_MOTOR_UD_F3=0;HAL_MOTOR_UD_F4=1;
							break;								
				default:
							break;				
				
			}         
      delay(15);            
    }
  }
	
 }

flash操作

内部e2rom的操作直接用的官方的代码,自己用的时候封装一层就OK。

#define ADDR_ID      0x07F9

/*Declare SFR associated with the IAP */
sfr IAP_DATA    =   0xC2;           //Flash data register
sfr IAP_ADDRH   =   0xC3;           //Flash address HIGH
sfr IAP_ADDRL   =   0xC4;           //Flash address LOW
sfr IAP_CMD     =   0xC5;           //Flash command register
sfr IAP_TRIG    =   0xC6;           //Flash command trigger
sfr IAP_CONTR   =   0xC7;           //Flash control register

/*Define ISP/IAP/EEPROM command*/
#define CMD_IDLE    0               //Stand-By
#define CMD_READ    1               //Byte-Read
#define CMD_PROGRAM 2               //Byte-Program
#define CMD_ERASE   3               //Sector-Erase

/*Define ISP/IAP/EEPROM operation const for IAP_CONTR*/
//#define ENABLE_IAP 0x80           //if SYSCLK<30MHz
//#define ENABLE_IAP 0x81           //if SYSCLK<24MHz
#define ENABLE_IAP  0x82            //if SYSCLK<20MHz
//#define ENABLE_IAP 0x83           //if SYSCLK<12MHz
//#define ENABLE_IAP 0x84           //if SYSCLK<6MHz
//#define ENABLE_IAP 0x85           //if SYSCLK<3MHz
//#define ENABLE_IAP 0x86           //if SYSCLK<2MHz
//#define ENABLE_IAP 0x87           //if SYSCLK<1MHz


/*----------------------------
Disable ISP/IAP/EEPROM function
Make MCU in a safe state
----------------------------*/
void IapIdle()
{
    IAP_CONTR = 0;                  //Close IAP function
    IAP_CMD = 0;                    //Clear command to standby
    IAP_TRIG = 0;                   //Clear trigger register
    IAP_ADDRH = 0x80;               //Data ptr point to non-EEPROM area
    IAP_ADDRL = 0;                  //Clear IAP address to prevent misuse
}

/*----------------------------
Read one byte from ISP/IAP/EEPROM area
Input: addr (ISP/IAP/EEPROM address)
Output:Flash data
----------------------------*/
unsigned char IapReadByte(unsigned int addr)
{
    unsigned char dat;                       //Data buffer

    IAP_CONTR = ENABLE_IAP;         //Open IAP function, and set wait time
    IAP_CMD = CMD_READ;             //Set ISP/IAP/EEPROM READ command
    IAP_ADDRL = addr;               //Set ISP/IAP/EEPROM address low
    IAP_ADDRH = addr >> 8;          //Set ISP/IAP/EEPROM address high
    IAP_TRIG = 0x5a;                //Send trigger command1 (0x5a)
    IAP_TRIG = 0xa5;                //Send trigger command2 (0xa5)
    _nop_();                        //MCU will hold here until ISP/IAP/EEPROM operation complete
    dat = IAP_DATA;                 //Read ISP/IAP/EEPROM data
    IapIdle();                      //Close ISP/IAP/EEPROM function

    return dat;                     //Return Flash data
}

/*----------------------------
Program one byte to ISP/IAP/EEPROM area
Input: addr (ISP/IAP/EEPROM address)
       dat (ISP/IAP/EEPROM data)
Output:-
----------------------------*/
void IapProgramByte(unsigned int addr, unsigned char dat)
{
    IAP_CONTR = ENABLE_IAP;         //Open IAP function, and set wait time
    IAP_CMD = CMD_PROGRAM;          //Set ISP/IAP/EEPROM PROGRAM command
    IAP_ADDRL = addr;               //Set ISP/IAP/EEPROM address low
    IAP_ADDRH = addr >> 8;          //Set ISP/IAP/EEPROM address high
    IAP_DATA = dat;                 //Write ISP/IAP/EEPROM data
    IAP_TRIG = 0x5a;                //Send trigger command1 (0x5a)
    IAP_TRIG = 0xa5;                //Send trigger command2 (0xa5)
    _nop_();                        //MCU will hold here until ISP/IAP/EEPROM operation complete
    IapIdle();
}

APP层

app层负责最上层业务处理。简化一下就是发送 0x68和0x16控制电机上下转动指定角度。

char uuu =2;

void main()
{
	app_init_machine();																												
	
	ES = 1;               
	EA = 1; 
	
	while(1){

	//	app_task_loop();
		if(uuu == 0){
			hal_turn_up_motor(4);
			uuu =2;
		}else if(uuu == 1){
			hal_turn_down_motor(4);
			uuu =2;
		}
	}

}



void UART_ISR (void) interrupt 4 using 1
{
	
	if(RI == 1){
		RI = 0;		      																														
		g_uart_data.RXData = SBUF;  																								
		
		if(g_uart_data.RXData == 0x68){
			uuu =1;
		}else if(g_uart_data.RXData == 0x16){
			uuu =0;
		}
    }
}

 

基本代码和业务就是这样了,只要通过uart接口这套代码都可以用,主要看外挂的什么芯片了485呀、can呀、wifi模块······

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值