C语言单片机

#include <reg52.h>

#include <string.h>

#include "IndeUart2.h"

#include "keys.h"

#include "OLED12864.h"

#include "Timer0.h"

#define BUFFER_SIZE 128 //用宏申明一个缓冲区大小

unsigned char xdata Laser_Uart_RecvBufferBUFFER_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_Data4=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_DataKey_Value-1=Laser_Uart_Read();//采集一次距离信息

View_DisData0=Dis_DataKey_Value-1/10000+0x30;//Dis_Data数组中下标为Key_Value-1位置的值除以10000的商+0x30赋值给数组View_DisData下标为0的位置

View_DisData1=Dis_DataKey_Value-1%10000/1000+0x30;//Dis_Data数组中下标为Key_Value-1位置的值除以10000的余数,再除以1000的商+0x30赋值给数组View_DisData下标为1的位置

View_DisData3=Dis_DataKey_Value-1%1000/100+0x30;//Dis_Data数组中下标为Key_Value-1位置的值除以1000的余数,再除以100的商+0x30赋值给数组View_DisData下标为3的位置

View_DisData4=Dis_DataKey_Value-1%100/10+0x30;//Dis_Data数组中下标为Key_Value-1位置的值除以100的余数,再除以10的商+0x30赋值给数组View_DisData下标为4的位置

View_DisData5=Dis_DataKey_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_Data1*Dis_Data2;//数组DisData中的第二个值乘以第三个值,再赋值给Area_daa

Area_Data=Area_Data/1000;//得到面积,单位平方毫米

Volume_Data=Area_Data*Dis_Data3;//面积乘以数组中的第4个值,再赋值给Volume_Data

Volume_Data=Volume_Data/1000;//得到体积 立方毫米

Area_View0=Area_Data/1000000+0x30;//面积除以1000000的商+0x30赋值给Area_View数组的第一个值

Area_View1=Area_Data%1000000/100000+0x30;//面积除以1000000的余数,再除以100000的商+0x30赋值给Area_View数组的第二个值

Area_View2=Area_Data%100000/10000+0x30;//面积除以100000的余数,再除以10000的商+0x30赋值给Area_View数组的第三个值

Area_View3=Area_Data%10000/1000+0x30;//面积除以10000的余数,再除以1000的商+0x30赋值给Area_View数组的第四个值

Area_View5=Area_Data%1000/100+0x30;//面积除以1000的余数,再除以100的商+0x30赋值给Area_View数组的第六个值

Area_View6=Area_Data%100/10+0x30;//面积除以100的余数,再除以10的商+0x30赋值给Area_View数组的第七个值

Area_View7=Area_Data%10/1+0x30;//面积除以10的余数+0x30赋值给Area_View数组的第八个值

Volume_View0=Volume_Data/100000000+0x30;//Volume_Data除以100000000的商+0x30赋值给Volume_View数组的第一个值

Volume_View1=Volume_Data%10000000/100000+0x30;//Volume_Data除以10000000的余数,再除以100000+0x30赋值给Volume_View数组的第二个值

Volume_View2=Volume_Data%1000000/100000+0x30;//Volume_Data除以1000000的余数,再除以100000+0x30赋值给Volume_View数组的第三个值

Volume_View3=Volume_Data%100000/10000+0x30;//Volume_Data除以100000的余数,再除以10000+0x30赋值给Volume_View数组的第四个值

Volume_View4=Volume_Data%10000/1000+0x30;//Volume_Data除以10000的余数,再除以1000+0x30赋值给Volume_View数组的第五个值

Volume_View6=Volume_Data%1000/100+0x30;//Volume_Data除以1000的余数,再除以100+0x30赋值给Volume_View数组的第七个值

Volume_View7=Volume_Data%100/10+0x30;//Volume_Data除以100的余数,再除以10+0x30赋值给Volume_View数组的第八个值

Volume_View8=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_RecvBufferLaser_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_RecvBufferNum_Con_A!=':')//Laser_Uart_RecvBuffer数组中从下标为0开始,找到不等于 : 的位置

{

Num_Con_A++;//得到数字第一位位置

}

while(Laser_Uart_RecvBufferNum_Con_B!='.')//Laser_Uart_RecvBuffer数组中从下标为0开始,找到不等于 . 的位置

{

Num_Con_B++;//得到数字小数点位置

}

if((Num_Con_B-Num_Con_A)==3)//不等于 : 的位置与不等于 . 的位置下标相差3,进入下面

{

if(Laser_Uart_RecvBufferNum_Con_A+1==' ')//下标为 : 的下一个位置是空格,进入下面

{

Count_Data=Laser_Uart_RecvBufferNum_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_RecvBufferNum_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_RecvBufferNum_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_RecvBufferNum_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_RecvBufferNum_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_RecvBufferNum_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;//返回结果

}

相关推荐
hai31524754312 分钟前
# FiveOS V5.0 交付(终极合成器版 · 物理合规修正)
人工智能·stm32·单片机·嵌入式硬件·神经网络
嵌入式ZYXC26 分钟前
第6章:通信接口的硬件特性——为什么你的UART乱码、I2C死锁、SPI干扰大?
stm32·单片机·嵌入式硬件·物联网·智能硬件
2301_7779983428 分钟前
基础IO:IO操作&&重定向
linux·c语言
社交怪人30 分钟前
【收费】信息学奥赛一本通C语言解法(题号2055)
c语言
夜月yeyue35 分钟前
TCP/IP 协议解析
linux·服务器·c语言·网络·网络协议·tcp/ip
三佛科技-134163842121 小时前
AIP8P005B 与FT60E112A(8位I/O型单片机)对比分析,FT60E112A能否兼容替代AIP8P005B?
单片机·嵌入式硬件·物联网·智能家居·pcb工艺
fffzd1 小时前
STM32:串口--轮询模式
stm32·单片机·嵌入式硬件·串口·hal库·轮询模式
municornm1 小时前
单片机IO不够?ULN2003A救急方案
单片机·嵌入式硬件
m0_618526201 小时前
矩阵RGB三色LED驱动芯片CH466(SPI模式)
单片机·嵌入式硬件
染予1 小时前
实现功能:给stm32F427zgt6开发板配置网络,电脑可以ping通开发板
stm32·单片机·嵌入式硬件