• C语言单片机


    #include
    #include
    #include "IndeUart2.h"
    #include "keys.h"
    #include "OLED12864.h"
    #include "Timer0.h"


    #define BUFFER_SIZE 128 //用宏申明一个缓冲区大小
     
    unsigned char xdata Laser_Uart_RecvBuffer[BUFFER_SIZE];//储存激光传感器回传的数据
    unsigned char Laser_Uart_RecvCount = 0;    
    void Laser_Uart_Data_Receive(unsigned char Recv_Data);
    unsigned long Laser_Uart_Read(void);
    void Laser_Uart_DataInit(void);
    void Laser_delay500ms(void);//以上是函数申明

    unsigned long Dis_Data[4]=0; //把数组初始化为0
    unsigned char View_DisData[]="00.000M";//用值初始化数组

    unsigned long Area_Data=0;//面积数据
    unsigned long Volume_Data=0;//体积数据

    unsigned char Area_View[]="0000.000";//用值初始化数组
    unsigned char Volume_View[]="00000.000";//用值初始化数组

    void main()
    {
        Uart2_Init();//初始化串口2
        OLED_Init();//初始化OLED
        Timer0_Init();//初始化定时器0
        OLED_P8x16Str(0,0,"00.000M  00.000M");//在界面上显示内容(具体显示什么要看单片机)
        OLED_P8x16Str(0,2,"00.000M  00.000M");
        OLED_P8x16Str(0,4,"S:0000.000M2    ");
        OLED_P8x16Str(0,6,"V:00000.000M3   ");
        while(1)
        {
            if(Key_Change)//不为0有按键按下
            {
                Key_Change=0;//没有收到按键按下时为0
                Laser_Uart_DataInit();//初始化缓冲区
                Dis_Data[Key_Value-1]=Laser_Uart_Read();//采集一次距离信息
                
                View_DisData[0]=Dis_Data[Key_Value-1]/10000+0x30;//Dis_Data数组中下标为Key_Value-1位置的值除以10000的商+0x30赋值给数组View_DisData下标为0的位置
                View_DisData[1]=Dis_Data[Key_Value-1]%10000/1000+0x30;//Dis_Data数组中下标为Key_Value-1位置的值除以10000的余数,再除以1000的商+0x30赋值给数组View_DisData下标为1的位置
                View_DisData[3]=Dis_Data[Key_Value-1]%1000/100+0x30;//Dis_Data数组中下标为Key_Value-1位置的值除以1000的余数,再除以100的商+0x30赋值给数组View_DisData下标为3的位置
                View_DisData[4]=Dis_Data[Key_Value-1]%100/10+0x30;//Dis_Data数组中下标为Key_Value-1位置的值除以100的余数,再除以10的商+0x30赋值给数组View_DisData下标为4的位置
                View_DisData[5]=Dis_Data[Key_Value-1]%10+0x30;//Dis_Data数组中下标为Key_Value-1位置的值除以10的余数+0x30赋值给数组View_DisData下标为5的位置
                
                switch(Key_Value)//根据按键数值,修改显示内容
                {
                    case 1:OLED_P8x16Str(0,0,View_DisData);break;//按下1,把View_DisData中的数据在界面显示
                    case 2:OLED_P8x16Str(72,0,View_DisData);break;//按下2,把View_DisData中的数据在界面显示
                    case 3:OLED_P8x16Str(0,2,View_DisData);break;//按下3,把View_DisData中的数据在界面显示
                    case 4:OLED_P8x16Str(72,2,View_DisData);break;//按下4,把View_DisData中的数据在界面显示
                }    //以上1、2、3、4每次只会有一个触发

                Area_Data=Dis_Data[1]*Dis_Data[2];//数组DisData中的第二个值乘以第三个值,再赋值给Area_daa
                Area_Data=Area_Data/1000;//得到面积,单位平方毫米
                
                Volume_Data=Area_Data*Dis_Data[3];//面积乘以数组中的第4个值,再赋值给Volume_Data
                Volume_Data=Volume_Data/1000;//得到体积 立方毫米
                
                
                Area_View[0]=Area_Data/1000000+0x30;//面积除以1000000的商+0x30赋值给Area_View数组的第一个值
                Area_View[1]=Area_Data%1000000/100000+0x30;//面积除以1000000的余数,再除以100000的商+0x30赋值给Area_View数组的第二个值
                Area_View[2]=Area_Data%100000/10000+0x30;//面积除以100000的余数,再除以10000的商+0x30赋值给Area_View数组的第三个值
                Area_View[3]=Area_Data%10000/1000+0x30;//面积除以10000的余数,再除以1000的商+0x30赋值给Area_View数组的第四个值
                
                Area_View[5]=Area_Data%1000/100+0x30;//面积除以1000的余数,再除以100的商+0x30赋值给Area_View数组的第六个值
                Area_View[6]=Area_Data%100/10+0x30;//面积除以100的余数,再除以10的商+0x30赋值给Area_View数组的第七个值
                Area_View[7]=Area_Data%10/1+0x30;//面积除以10的余数+0x30赋值给Area_View数组的第八个值
                
                Volume_View[0]=Volume_Data/100000000+0x30;//Volume_Data除以100000000的商+0x30赋值给Volume_View数组的第一个值
                Volume_View[1]=Volume_Data%10000000/100000+0x30;//Volume_Data除以10000000的余数,再除以100000+0x30赋值给Volume_View数组的第二个值
                Volume_View[2]=Volume_Data%1000000/100000+0x30;//Volume_Data除以1000000的余数,再除以100000+0x30赋值给Volume_View数组的第三个值
                Volume_View[3]=Volume_Data%100000/10000+0x30;//Volume_Data除以100000的余数,再除以10000+0x30赋值给Volume_View数组的第四个值
                Volume_View[4]=Volume_Data%10000/1000+0x30;//Volume_Data除以10000的余数,再除以1000+0x30赋值给Volume_View数组的第五个值
                
                Volume_View[6]=Volume_Data%1000/100+0x30;//Volume_Data除以1000的余数,再除以100+0x30赋值给Volume_View数组的第七个值
                Volume_View[7]=Volume_Data%100/10+0x30;//Volume_Data除以100的余数,再除以10+0x30赋值给Volume_View数组的第八个值
                Volume_View[8]=Volume_Data%10/1+0x30;//Volume_Data除以10的余数+0x30赋值给Volume_View数组的第九个值
                
                OLED_P8x16Str(16,4,Area_View);//显示面积
                OLED_P8x16Str(16,6,Volume_View);//显示体积
            }


        }
    }

    /*
      功能描述: 定时器0中断函数
      函数参数: 无
      返回说明: 无
    */

    void Timer0_Interrupt(void) interrupt 1    //    定时器0中断函数
    {
        
        TH0 = 0xDC;    //重置定时时间,如果初始化使用的是定时方式2则不需要重置
        TL0 = 0x00;
      Key_Acquisition();//等待键盘输入
    }

    void Laser_Uart_DataInit()//初始化数据
    {
        memset(Laser_Uart_RecvBuffer,0,BUFFER_SIZE);    // 清空缓冲区
        Laser_Uart_RecvCount = 0;                                // 缓冲区下标归位
    }

    void Laser_Uart_Data_Receive(unsigned char Recv_Data)//接收到Recv_Data的一个字节的数据
    {
        if((Recv_Data == 0)||(Recv_Data == 0X0D) || (Recv_Data == 0X0A) || (Recv_Data >= 32 && Recv_Data <= 127) )
        {//符合条件就把接收到的数据赋值给数组Laser_Uart_RecvBuffer下标为Laser_Uart_RecvCount的位置,之后Laser_Uart_RecvCount等于Laser_Uart_RecvCount加1
            Laser_Uart_RecvBuffer[Laser_Uart_RecvCount++] = Recv_Data;
        }    
    }

    void Laser_delay500ms(void)   //延迟500ms
    {
        unsigned char a,b,c;
        for(c=246;c>0;c--)//通过循环246*212*25次来延时500ms
            for(b=212;b>0;b--)
                for(a=25;a>0;a--);
    }


    unsigned long Laser_Uart_Read()//读取一次激光传感器数据
    {
        unsigned char Num_Con_A=0;//初始化变量
        unsigned char Num_Con_B=0;//初始化变量
        unsigned long Count_Data=0;//初始化变量
        unsigned long Return_Data=0;//初始化变量

        Uart2_SendOneByte('F');//此函数需要根据使用的串口调整
        Laser_delay500ms();//延时500毫秒
        if(Laser_Uart_RecvCount<10)//如果Laser_Uart_RecvBuffer中的数据少于10个字节,就返回0
        {
            Return_Data=0;
        }
        else//Laser_Uart_RecvBuffer中数据大于等于10个字节
        {
            while(Laser_Uart_RecvBuffer[Num_Con_A]!=':')//Laser_Uart_RecvBuffer数组中从下标为0开始,找到不等于 : 的位置
            {
                Num_Con_A++;//得到数字第一位位置
                
            }
            while(Laser_Uart_RecvBuffer[Num_Con_B]!='.')//Laser_Uart_RecvBuffer数组中从下标为0开始,找到不等于 . 的位置
            {
                Num_Con_B++;//得到数字小数点位置
            }
            if((Num_Con_B-Num_Con_A)==3)//不等于 : 的位置与不等于 . 的位置下标相差3,进入下面
            {
                if(Laser_Uart_RecvBuffer[Num_Con_A+1]==' ')//下标为 : 的下一个位置是空格,进入下面
                {
                    Count_Data=Laser_Uart_RecvBuffer[Num_Con_A+2]-0x30;//Laser_Uart_RecvBuffer在数组下标为 : 的位置+2的值-0x30,赋值给Count_data
                    Return_Data=Count_Data*1000;//Return_Data值等于Count_Data*1000
                }
                else
                {//下标为 : 的下一个位置不是空格,进入下面
                    Count_Data=Laser_Uart_RecvBuffer[Num_Con_A+1]-0x30;//Laser_Uart_RecvBuffer在数组下标为 : 的位置+1的值-0x30,赋值给Count_data
                    Return_Data=Count_Data*10000;//Return_Data等于Count_Data*10000
                    Count_Data=Laser_Uart_RecvBuffer[Num_Con_A+2]-0x30;Laser_Uart_RecvBuffer在数组下标为 : 的位置+2的值-0x30,赋值给Count_data
                    Return_Data=Return_Data+Count_Data*1000;//Return_Data等于Return_Data+Count_Data*1000
                }
            }
            Count_Data=Laser_Uart_RecvBuffer[Num_Con_B+1]-0x30;//Count_Data等于在Laser_Uart_RecvBuffer数组中找到 . 的位置+1下标的值,再-0x30
            Return_Data=Return_Data+Count_Data*100;//Return_Data等于Return_Data+Count_Data*1000
            
            Count_Data=Laser_Uart_RecvBuffer[Num_Con_B+2]-0x30;//Count_Data等于在Laser_Uart_RecvBuffer数组中找到 . 的位置+2下标的值,再-0x30
            Return_Data=Return_Data+Count_Data*10;//Return_Data等于Return_Data+Count_Data*10
            
            Count_Data=Laser_Uart_RecvBuffer[Num_Con_B+3]-0x30;//Count_Data等于在Laser_Uart_RecvBuffer数组中找到 . 的位置+2下标的值,再-0x30
            Return_Data=Return_Data+Count_Data;//Return_Data等于Return_Data+Count_Data
        }
        return Return_Data;//返回结果
    }


     

  • 相关阅读:
    深入理解WPF的ResourceDictionary
    在浏览器中输入www.baidu.com发生了什么,用了哪些层的协议
    Vue3 相较 Vue2 做的重大更新
    项目部署;流程
    关于安卓唯一标识的汇总及最佳做法
    音视频常见问题(六):视频黑边或放大
    Go的任务调度单元与并发编程
    C#难点语法讲解之委托---从应用需求开始讲解
    从程序员到架构师:大数据量、缓存、高并发、微服务、多团队协同等核心场景实战书籍
    [项目管理-25]:高效沟通的利器,结构思考力与树形结构化表达
  • 原文地址:https://blog.csdn.net/mawanbing/article/details/136442497