序
🔥 毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。
为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是:水库控制系统的设计
1 硬件原理与设计
1.1 步进电机的控制电路
利用AT89S52单片机和LM298驱动芯片构成步进电机的控制系统,控制电机正反转。在该电路设计中,加入了TLP521_4光耦电路,使单片机与步进电机的驱动电路完全隔离,以减少电机脉冲对单片机的干扰;电路图中还包括单片机外接的四个插槽,方便对单片机上的各个接口的使用,它们通过网络标志分别和各相关电路元件连接。步进电机接收的是脉冲信号,所以极容易受到干扰。
图1.1 步进电机的驱动电路
1.2 单片机工作电路
AT89S52单片机是模拟水库监测系统的核心部分,用它来控制整个系统的运行,下面是它的电路图及相应配备电路,本系统中,共用到两块AT89S52单片机,上下位端各一块,下位端即CC1100模块无线发送端,这一块单片机有三个作用,一是对传感器所采集的信息进行处理;二是将处理好的数据信息送入到CC1100模块中进行发送;三是根据信息处理结果,控制步进电机正反转。上位端的AT89S52单片机主要是用来承载CC1100模块所接收到的信息,实现串口通讯,将数据传到上位机上去。要对AT89S52单片机进行保护,在XTAL1和XTAL2间要加入晶振电路来保证单片机的正常运行。
图1.2 单片机工作电路
1.3 数码管显示电路
显示模式采用的是四位七段LED数码管显示,如同单片机的使用一样,该系统电路中也使用了两块数码管,它们的功能分别是:下位端的数码管是用来显示传感器所采集的信号,通过其显示的方波信号来计算时间差,求出水位,以及显示由流量传感器所采集的水流量的大小;上位端的数码管用来监测CC1100模块无线通讯是否成功,如果它显示的数字和下位端数码管一样,就证明无线发送/接收成功。
图1.3 数码管显示及其驱动电路
1.4 电源模块设计
由于本系统中CC1100的工作电压是3.3V,为了给其提供稳定的电压,使用了LM1117电压调节器,它能产生3.3V的稳压;该电源模块中还包括上电显示,给步进电机和单片机供电的电压块。
图1.4 电源模块
1.5 CC1100无线模块及串口通讯电路
在下面电路图中,只显示了上位端的CC1100接收模块,因为发送模块的连接方法是一样的,为了避免重复,所以没有给出。上位端接收从CC1100无线发射模块传来的信号,再将收集的信号传送到单片机上。由MX232串口通讯电路,把单片机中的数据信号传到上位机中去,通过上位机显示水库的实时参数,并对数据进行分析反馈。
图1.5 CC1100接收模块及串口通讯电路
2 软件设计
2.1 程序流程图
在本系统中,程序流程图可分为上位机端和下位机端两部分。
图2.1如下所示,是上位机端的程序流程图。
图2.1上位机端程序流程图
图2.2如下所示,是下位机端的程序流程图。
图2.1 下位机端程序流程图
在本系统中,程序流程图分为上位机端程序流程图和下位机端程序流程图两大部分。在上位机端,是编译程序来完成上下位机之间的串口通讯,以及实现数据在上下位机间的传送;而下位机端的程序流程图可以实现以下系统功能:一是实现传感器对模拟水库的实时参数的采集,如水位,流量等;二是实现CC1100无线模块的无线通讯;三是实现AT89S52单片机对步进电机的控制
2.2 CC1100模块发送和接收部分程序分析
在这里介绍CC1100模块的部分通讯代码。由于CC1100无线模块的源代码非常多,下面只介绍CC1100无线模块发送/接收部分的程序代码。程序分析如下:
//函数名:void halRfSendPacket(INT8U *txBuffer, INT8U size)
//输入:发送的缓冲区,发送数据个数
//输出:无
//功能描述:CC1100发送一组数据
void halRfSendPacket(INT8U *txBuffer, INT8U size)
{
halSpiWriteReg(CCxxx0_TXFIFO, size);
halSpiWriteBurstReg(CCxxx0_TXFIFO, txBuffer, size);
//写入要发送的数据
halSpiStrobe(CCxxx0_STX);
//进入发送模式发送数据
// Wait for GDO0 to be set -> sync transmitted
while (!GDO0);
// Wait for GDO0 to be cleared -> end of packet
while (GDO0);
halSpiStrobe(CCxxx0_SFTX);
}
void setRxMode(void)
{
halSpiStrobe(CCxxx0_SRX);
//进入接收状态
}
INT8U halRfReceivePacket(INT8U *rxBuffer, INT8U *length)
{
INT8U status[2];
INT8U packetLength;
INT8U i=(*length)*4;
// 具体多少要根据datarate和length来决定
halSpiStrobe(CCxxx0_SRX);
//进入接收状态
delay(2);
while (GDO0)
{
delay(2);
--i;
if(i<1)
return 0;
}
if ((halSpiReadStatus(CCxxx0_RXBYTES) & BYTES_IN_RXFIFO))
//如果接的字节数不为0
{
packetLength = halSpiReadReg(CCxxx0_RXFIFO);
//读出第一个字节,此字节为该帧数据长度
if (packetLength <= *length)
//如果所要的有效数据长度小于等于接收到的数据包的长度
{ halSpiReadBurstReg(CCxxx0_RXFIFO, rxBuffer, packetLength);
//读出所有接收到的数据
*length = packetLength;
//把接收数据长度的修改为当前数据的长度
// Read the 2 appended status bytes (status[0] = RSSI, status[1] = LQI)
halSpiReadBurstReg(CCxxx0_RXFIFO, status, 2);
//读出CRC校验位
halSpiStrobe(CCxxx0_SFRX);
//清洗接收缓冲区
return (status[1] & CRC_OK);
//如果校验成功返回接收成功
}
else
{
*length = packetLength;
halSpiStrobe(CCxxx0_SFRX);
//清洗接收缓冲区
return 0;
}
}
else
return 0;
}
如果学弟学妹们在毕设方面有任何问题,随时可以私信我咨询哦,有问必答!学长专注于单片机相关的知识,可以解决单片机设计、嵌入式系统、编程和硬件等方面的难题。
愿毕业生有力,陪迷茫着前行!