Grbl在51单片机上的验证 STC12C5A60S2

纵观网络上各位大神在数控方面的神作,却没有什么人做一些分享,那么,从我开始好了,这里只做了STC12C5A60S2这种51单片机成功对接Grbl上位机软件以及将接受到的G代码转换为float型坐标,验证这么一个功能,为以后深入编写电机控制,做一个基础铺垫。

这里所完成的功能很简单,所以代码也不难,主要是了解Grbl通信协议,以及G代码解析两个点,下面,我带大家来解读这两个点。

1、了解Grbl

在百度文库上,我上传了基本的协议,可以点击查看

http://wenku.baidu.com/link?url=Mu-JK2FGfv9pStTQqdVxxTF4I7PfQG8PdMl-zhS7tkEWjyNFvraf9uLpgAh7CS28bGrck3vxgHp5r262d6N9WGxBj9CvipySgCYm3v1nhje


这里我就不赘述了。

但是有一点,通信就是,你问我一句,我回你一句,所以是上位机先问下单片机:你是不是Grbl设备啊?,然后单片机得回答说:是啊,我是Grbl xx,然后上位机收到回复后才开始建立通信,这一点,在下面程序里的setup();完成

通信完全建立好后,就进入loop();函数里面,这时就等待上位机发送G代码了,上位机每次发送一行代码,单片机接受后,处理完成后,回复ok,上位机才会发送下一句。

基本就是这些了,其实很简单是不是。


2、将通信协议写入程序代码中,并完成G代码解析:


首先你应该有一点编程基础,然后应该就不难了。


其中动用的主要子函数是

Echo_Position(float x,float y, float z);
用来反馈当前坐标的

Analysis_Gcode(unsigned char *p_buffer);
用来解析G代码的


以下是函数的主体。

#include"STC12C5A60S2.h"
#include"UART.h"
#include"M_string.h"
#include"stdio.h"
enum axis{X_AXIS=0,Y_AXIS,Z_AXIS,E_AXIS};
xdata float Machine_Coordinates[4]={0.0,0.0,0.0,0.0};
xdata float Work_Coordinates[4]={0.0,0.0,0.0,0.0};

const unsigned char code ECHO_GRBL[]="Grbl";
const unsigned char code ECHO_POS[]="";
const unsigned char code ECHO_ERROR[]="error";
#define R_POS	11
const unsigned char code ECHO_OK[]="ok";
void Echo_Position(float x,float y, float z)
{
	#define CLR_BUF() do{\
		for(i=0;i<12;i++)\
		{\
			Buffer[i]=0x00;\
		}\
	}while(0)
	unsigned char i;
	unsigned char Buffer[12];//1+5+1+3+1+1
	Clear_Uart_sendBuffer();
	for(sendBuffer_Index=0;sendBuffer_Index



然后涉及到串口的设置,这里使用的是方式3,注意,1验证(我忘记调整这个点了,所以导致Grbl上位机对回复的位置无法处理,因为乱码嘛,坐标显示就一直为0)


#include"STC12C5A60S2.h"
#include"intrins.h"
#include"UART.H"
xdata unsigned char Uart_sendBuffer[128];
xdata unsigned char Uart_recvBuffer[128];
xdata unsigned char sendBuffer_Index=0;
xdata unsigned char recvBuffer_Index=0;
bit Uart_busy=0;
#define FOSC 11095200	//默认11.0592MHz晶振
//TH1=256-(FOSC/32/baud_rate);
#define UART_PARYTY3
#message "Uart mode 3"
#message "Use this Uart.h will occupy Timer1"
void Clear_Uart_sendBuffer()
{
	sendBuffer_Index=0;
	while(sendBuffer_Index<128)
	{
		Uart_sendBuffer[sendBuffer_Index]=0;
		sendBuffer_Index++;
	}
	sendBuffer_Index=0;
}
void Clear_Uart_recvBuffer()
{
	recvBuffer_Index=0;
	while(recvBuffer_Index<128)
	{
		Uart_recvBuffer[recvBuffer_Index]=0;
		recvBuffer_Index++;
	}
	recvBuffer_Index=0;
}
void Serial_begin(unsigned long baud_rate)
{
	Clear_Uart_sendBuffer();
	Clear_Uart_recvBuffer();
#ifdef UART_PARYTY3
	AUXR|=0x40;
	SCON=0xDA;							//9bit 奇校验
	TMOD=0x20;							//T1 8位自动重装模式
	TH1=0xFF-(FOSC/32/baud_rate)+1;		//初值
	TL1=TH1;
	TR1=1;
	ES=1;
	REN=1;
	TI=0;
	RI=0;
	EA=1;
#else
	
#endif
}


void Uart_SendByte(unsigned char chr)
{
	TI=0;
	Uart_busy=1;
	SBUF=chr;
	while(Uart_busy);
}
void Serial_println(unsigned char *str)
{
	unsigned char i;
	while(*str && i<128)
	{
		Uart_SendByte(*str);
		str++;
		i++;
	}
	Uart_SendByte(0x0D);
	Uart_SendByte(0x0A);
}
void Uart_Recv(void) interrupt 4 using 0
{
//	ES=0;//关闭串口中断
	if(RI && recvBuffer_Index<128)	//如果是接收引发中断,且接收缓冲没有占满
	{
		Uart_recvBuffer[recvBuffer_Index]=SBUF;	//将SBUF数据放入接收缓冲
		recvBuffer_Index++;
	}
	RI=0;//清除接收中断标志
	TI=0;
	Uart_busy=0;
//	ES=1;//打开串口中断
}

Uart.c的头文件,用来引用Uart.c里的函数

#ifndef UART_h
#define UART_h
extern bit Uart_busy;
extern xdata unsigned char Uart_sendBuffer[128];
extern xdata unsigned char Uart_recvBuffer[128];
extern xdata unsigned char sendBuffer_Index;
extern xdata unsigned char recvBuffer_Index;
#include"STC12C5A60S2.h"
void Serial_begin(unsigned long boundrate);
#define Serial_end()	do{REN = 0;}
void Clear_Uart_sendBuffer();
void Clear_Uart_recvBuffer();
void Uart_SendByte(unsigned char chr);
void Serial_print(unsigned char *str);
void Serial_println(unsigned char *str);
#endif

还有两个文件,M_string.h,M_string.lib,都不能少,这是两个处理字符串的函数。

其中string.lib是我自己做的库,主要是为了不出现UNCALLED SEGMENT这样的经典WARNING,点击下载(http://pan.baidu.com/s/1i43PSSt),其中包含库,头文件,以及函数原型,有些可能有错误,希望大家发现后能指出,这样,也不枉我共享这些东西。

最后再说一点,也是很重要的一点,波特率115200,不是原先默认的9600,记得改。

你可能感兴趣的:(STC12C5A60S2,单片机,编程,Grbl,51单片机,STC12C5A60S2)