用stc15w和旧光驱移植arduino写字机GRBL之四:FIFO算法
本帖最后由 XTXB 于 2018-11-25 09:39 编辑用stc15w4k32s4和旧光驱移植arduino写字机GRBL连载:
用stc15w4k32s4和旧光驱移植arduino写字机GRBL之一:机架搭建
https://www.amobbs.com/thread-5701202-1-1.html
用stc15w4k32s4和旧光驱移植arduino写字机GRBL之二:PCB制作
https://www.amobbs.com/thread-5701573-1-1.html
用stc15w4k32s4和旧光驱移植arduino写字机GRBL之三:Bresenham算法
https://www.amobbs.com/thread-5701994-1-1.html
用stc15w4k32s4和旧光驱移植arduino写字机GRBL之四:FIFO算法
GRBL为协调匹配各个部分数据传递及处理速度的差异,用了三个环形队列:
FIFO算法实现过程图解:
下面在STC上实现FIFO串口发送接收,跟GRBL不同的是,avr是在
USART寄存器空 中断中完成数据的发送,咱这个是在主循环中完成:
//用环形队列通过串口1发送接收数据实验
#include "STC15Fxxxx.H" //stc15w4k32s4时钟24M
#define RX_BUFFER_SIZE 128//接收缓冲尺寸
#define TX_BUFFER_SIZE 64 //发送数据缓存尺寸
u8 xdata rx_buffer;//定义一个接收队列
u8 rx_buffer_head = 0;
u8 rx_buffer_tail = 0;
u8 xdata tx_buffer;
u8 tx_buffer_head = 0;
u8 tx_buffer_tail = 0;
bit B_TX1_Busy; //发送忙标志
//==========================串口波特率初始化===================
//===========================================================
void Uart1_Init(void)
{
//9600bps@24MHz9600bps 串口1
SCON = 0x50; //8位数据,可变波特率
AUXR &= 0xBF; //定时器1时钟为Fosc/12,即12T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设定定时器1为16位自动重装方式
TL1 = 0xCC;
TH1 = 0xFF;
TR1 = 1; //启动定时器1
ES = 1; //串行中断 允许控制位
REN = 1; //串口1允许接收
EA=1; //开全局中断
}
//
//========================接收队列有关操作=====================
//===========================================================
//复位队列
void serial_reset_read_buffer(void)
{
rx_buffer_tail = rx_buffer_head;
tx_buffer_tail = tx_buffer_head;
}
//入队, 将串口1接收到的数据加入到接收队列rx_buffer[ ]中
void ISR_USART_RX(void)
{
static u8 next_head=0;
next_head = rx_buffer_head + 1;
if (next_head == RX_BUFFER_SIZE)next_head = 0;
// Write data to buffer unless it is full.
if (next_head != rx_buffer_tail)//如果接收队列未满
{
rx_buffer = SBUF;
rx_buffer_head = next_head;
}
else
{
;//队列满处理
}
}
//出队,读接收队列的数据
u8 serial_read(void)
{
static u8 Temp = 0;
if (rx_buffer_head == rx_buffer_tail)
{ //如果是空
return 0;
}else {
Temp= rx_buffer;
rx_buffer_tail++;
if (rx_buffer_tail == RX_BUFFER_SIZE)rx_buffer_tail = 0;
return Temp;
}
}
//============================发送队列有关操作=================
//===========================================================
//入队,将需要发送的数据加入到发送队列tx_buffer[]中
void serial_write(u8 Byt)
{
static u8 next_head;
next_head = tx_buffer_head + 1;
if (next_head == TX_BUFFER_SIZE) { next_head = 0; }
if (next_head !=tx_buffer_tail)//如果发送队列未满
{
tx_buffer = Byt;
tx_buffer_head = next_head;
}
else
{
;//队列满处理
}
}
//出队,将发送队列的数据通过串口发送出去
void Send_tx_buffer(void)
{
if (tx_buffer_head != tx_buffer_tail){ //队列如果不是空
SBUF= tx_buffer;
tx_buffer_tail++;
if (tx_buffer_tail == TX_BUFFER_SIZE)tx_buffer_tail = 0;
B_TX1_Busy = 1;
while(B_TX1_Busy); //等待发送完成
}
}
//发送一个字符串
void printString(const char *s)
{
while (*s)
serial_write(*s++);
}
//====================== UART1中断函数=========================
//============================================================
void UART1_int (void) interrupt 4
{
if(RI)//有接收
{
RI = 0;
ISR_USART_RX();
}
if(TI)//发送完成
{
TI = 0; //清除TI位
B_TX1_Busy = 0;//发送缓冲为空
}
}
//======================主函数 ===========================
//=========================================================
void main(void)
{
u32 ui_UART_Cnt=0;//延时计数器
u8 temp;
P2M1=B0000_0000; //00上拉准双向口/10浮空输入
P2M0=B0000_0100; //11开漏输出/01推挽输出
Uart1_Init();
serial_reset_read_buffer();
printString("stc15w4k32串口环形队列实验\r\n");
for (;;){
ui_UART_Cnt++;
Send_tx_buffer();//将发送队列tx_buffer[ ]的数据发送出去
if(ui_UART_Cnt>160000){ //延时计数器
ui_UART_Cnt=0;
P22=!P22;//"hello world"
if(temp=serial_read()){ //读接收队列rx_buffer[ ]的数据,如果不为空
serial_write(temp);//加入发送队列tx_buffer[ ]中
}
}
}
}
//
顶一下楼主 几年前做3D打印机的时候,要是有你这资料,我就能少花一点时间了。 好帖子,抽空好好学习一下 本帖最后由 XTXB 于 2018-11-24 20:30 编辑
honami520 发表于 2018-11-24 15:01
几年前做3D打印机的时候,要是有你这资料,我就能少花一点时间了。
多谢大侠光临!本人当爱好者多年,天生愚笨,到现在还是小白一枚,这些都是结合众网友的资料,写的一点见解,不一定完善,请多指教! 往fifo里写数,至少要判一下fifo满不满吧 本帖最后由 XTXB 于 2018-11-24 19:22 编辑
shiva_shiva 发表于 2018-11-24 18:53
往fifo里写数,至少要判一下fifo满不满吧
多谢指教!马上改。 顶一下大牛 点个赞,这套代码如果熟悉,可以干很多有意思的东西~~ 谢绡分享{:smile:} 请教LZ,你上面缓存的那个图片不错,这种样式是用什么来画的? mangolu 发表于 2021-1-31 18:56
请教LZ,你上面缓存的那个图片不错,这种样式是用什么来画的?
办公软件office Publisher XTXB 发表于 2021-2-2 21:57
办公软件office Publisher
哦,谢谢 帖子移动通知:
原分论坛:8051/STC32【已下线】
目标分论坛:51单片机
移动时间:0小时之后
页:
[1]