• 6-ESP8266 SDK开发基础入门篇--操作系统入门使用


    了解了8266的串口了,这一节咱就自己写程序,处理一下数据,如果接收到

    0xaa 0x55 0x01  就控制指示灯亮

    0xaa 0x55 0x00  就控制指示灯灭

    注意哈,我是用的假设没有操作系统的思路,其实如果有了操作系统应该用操作系统提供的API实现

    因为8266是用的FreeRtos,,,我还没有深入了解这个系统,所以我先用我的方式实现,后期的文章可能需要等些时间更新了,因为我需要充电

    定义一些变量

    u8  Usart1ReadBuff[Usart1ReadLen]={0};//接收数据的数组
    u32 Usart1ReadCnt = 0;//串口1接收到的数据个数
    u32 Usart1ReadCntCopy = 0;//串口1接收到的数据个数拷贝
    u8  Usart1ReadFlage=0;//串口1接收到一条完整数据

     

     其实就是在满中断里面把数据存到咱定义的数组,在空闲中断里面读出来剩余的数据

    然后置位一个标志,说明接收到一条完整的数据了

    LOCAL void
    uart0_rx_intr_handler(void *para)
    {
        /* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents
        * uart1 and uart0 respectively
        */
        uint8 RcvChar;
        uint8 uart_no = UART0;//UartDev.buff_uart_no;
        uint8 fifo_len = 0;
        uint8 buf_idx = 0;
        //uint8 fifo_tmp[128] = {0};//只是告诉我们这个单片机的内部FIFO是128字节大小
        uint32 uart_intr_status = READ_PERI_REG(UART_INT_ST(uart_no)) ;//读取中断状态
        while (uart_intr_status != 0x0)
        {
            if (UART_FRM_ERR_INT_ST == (uart_intr_status & UART_FRM_ERR_INT_ST)) // 接收帧错误中断,,,可能是数据位数不对,或者接收到的数据不满8bit...等等
            {
                WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_FRM_ERR_INT_CLR);// 清除中断寄存器的 帧错误位
            }
            else if (UART_RXFIFO_FULL_INT_ST == (uart_intr_status & UART_RXFIFO_FULL_INT_ST)) //进入FIFO满中断
            {
                fifo_len = (READ_PERI_REG(UART_STATUS(UART0)) >> UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT;//读出来内部FIFO缓存的数据个数
    
                while (fifo_len--)
                {
                    if(Usart1ReadCnt<Usart1ReadLen-1)//别超过了数组的大小
                    {
                        Usart1ReadBuff[Usart1ReadCnt] = READ_PERI_REG(UART_FIFO(UART0)) & 0xFF;//取出来一个数据
                        Usart1ReadCnt++;
                    }
                    else
                    {
                        Usart1ReadCnt = 0;
                    }
                }
                WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR);// 清除满中断
            }
            else if (UART_RXFIFO_TOUT_INT_ST == (uart_intr_status & UART_RXFIFO_TOUT_INT_ST)) //空闲中断,证明接受到了一条完整的数据
            {
                fifo_len = (READ_PERI_REG(UART_STATUS(UART0)) >> UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT;//读出来接收的数据个数
    
                while (fifo_len--)
                {
                    if(Usart1ReadCnt<Usart1ReadLen-1)//别超过了数组的大小
                    {
                        Usart1ReadBuff[Usart1ReadCnt] = READ_PERI_REG(UART_FIFO(UART0)) & 0xFF;//取出来一个数据
                        Usart1ReadCnt++;
                    }
                    else
                    {
                        Usart1ReadCnt = 0;
                    }
                }
    
                Usart1ReadCntCopy = Usart1ReadCnt;//串口1接收到的数据个数拷贝
                Usart1ReadCnt = 0;
                Usart1ReadFlage=1;//串口1接收到一条完整数据
    
                WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_TOUT_INT_CLR);// 清除空闲标志位
            }
            else if (UART_TXFIFO_EMPTY_INT_ST == (uart_intr_status & UART_TXFIFO_EMPTY_INT_ST))//发送FIFO里面的数据个数少于20个,进入中断
            {
    
                WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_TXFIFO_EMPTY_INT_CLR);// 清除中断标志
                CLEAR_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA);//清除中断
            }
            else
            {
                //skip
            }
    
            uart_intr_status = READ_PERI_REG(UART_INT_ST(uart_no)) ;
        }
    }

     其实现在就是处理

    #include "uart.h"
    
    
    extern u8  Usart1ReadBuff[Usart1ReadLen];//接收数据的数组
    extern u32 Usart1ReadCnt;//串口1接收到的数据个数
    extern u32 Usart1ReadCntCopy;//串口1接收到的数据个数拷贝
    extern u8  Usart1ReadFlage;//串口1接收到一条完整数据

    处理数据之前先预热一下操作系统

    控制LED 1S亮 1S灭

    对了因为咱用的是操作系统哈,所以千万别这样想

     应该建一个函数,还记得上一节不,对了咱只是说操作系统的使用哈,不讲实质

     现在呢,把这个函数交给操作系统去管理

     然后再完善

     但是这样下载进去,不可以....

    还记得上一节说的不,任务必须有延时

    延时是用

    vTaskDelay(1000/portTICK_RATE_MS );//延时1S

    vTaskDelay(2000/portTICK_RATE_MS );//延时2S

     有人可能有疑问,为什么要用这个,其实这是操作系统提供的延时的API,调用它给的,操作系统才知道这里要延时一会.我先去执行别的任务去

    如果你不要操作系统提供的,用自己的硬延时 类如for 什么的,其实就是在这里等着了,,,,一般哈,对于延时比较苛刻的咱用自己的

    比如采集DHT11,DS18B20,等等,,,这种不是很苛刻的,咱就用操作系统提供的

    好了现在下载进去,会看到这个灯1S亮,1S灭

    现在咱做个好玩的,两个任务控制两个灯

     

     下载进去,大家会发现神奇的事情  同时亮,同时灭

      

    其实这就是操作系统的魅力所在....如果任务延时上一样,那么你会看着两个函数是同时进行的

    首先说一点哈

     

    看着是同时亮和灭,其实他们之间有延时,就是大约延时个任务调度的时间

    其实操作系统是不断的轮询各个任务,不断的挂起任务(让任务停止运行),启动任务

    串口处理放到下一节吧

    https://www.cnblogs.com/yangfengwu/p/11087558.html

  • 相关阅读:
    Notes about "Exploring Expect"
    Reuse Sonar Checkstyle Violation Report for Custom Data Analysis
    Eclipse带参数调试的方法
    MIT Scheme Development on Ubuntu
    Manage Historical Snapshots in Sonarqube
    U盘自动弹出脚本
    hg的常用配置
    Java程序员的推荐阅读书籍
    使用shared memory 计算矩阵乘法 (其实并没有加速多少)
    CUDA 笔记
  • 原文地址:https://www.cnblogs.com/yangfengwu/p/11087467.html
Copyright © 2020-2023  润新知