XTXB 发表于 2018-11-24 11:26:31

用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[ ]中
                        }
                }               
        }
}
//


HJJ2008 发表于 2018-11-24 11:31:08

顶一下楼主

honami520 发表于 2018-11-24 15:01:21

几年前做3D打印机的时候,要是有你这资料,我就能少花一点时间了。

jerry840922 发表于 2018-11-24 15:42:33

好帖子,抽空好好学习一下

XTXB 发表于 2018-11-24 16:01:06

本帖最后由 XTXB 于 2018-11-24 20:30 编辑

honami520 发表于 2018-11-24 15:01
几年前做3D打印机的时候,要是有你这资料,我就能少花一点时间了。

多谢大侠光临!本人当爱好者多年,天生愚笨,到现在还是小白一枚,这些都是结合众网友的资料,写的一点见解,不一定完善,请多指教!

shiva_shiva 发表于 2018-11-24 18:53:49

往fifo里写数,至少要判一下fifo满不满吧

XTXB 发表于 2018-11-24 19:15:20

本帖最后由 XTXB 于 2018-11-24 19:22 编辑

shiva_shiva 发表于 2018-11-24 18:53
往fifo里写数,至少要判一下fifo满不满吧

多谢指教!马上改。

fengyunyu 发表于 2018-11-25 16:18:19

顶一下大牛

90soso 发表于 2019-3-15 17:16:14

点个赞,这套代码如果熟悉,可以干很多有意思的东西~~

thyewfty 发表于 2019-12-23 20:50:36

谢绡分享{:smile:}

mangolu 发表于 2021-1-31 18:56:44

请教LZ,你上面缓存的那个图片不错,这种样式是用什么来画的?

XTXB 发表于 2021-2-2 21:57:23

mangolu 发表于 2021-1-31 18:56
请教LZ,你上面缓存的那个图片不错,这种样式是用什么来画的?

办公软件office Publisher

mangolu 发表于 2021-2-3 01:28:28

XTXB 发表于 2021-2-2 21:57
办公软件office Publisher

哦,谢谢

armok. 发表于 2023-10-25 16:09:17

帖子移动通知:
原分论坛:8051/STC32【已下线】
目标分论坛:51单片机
移动时间:0小时之后
页: [1]
查看完整版本: 用stc15w和旧光驱移植arduino写字机GRBL之四:FIFO算法