当前位置: 首页 > news >正文

STC15单片机-整合代码,完成软件设计

整合代码,完成软件设计

按产品思维开发,是先把模块的程序编写好,比如按键、串口,RS-485、WIFI等,这样就会有很多.c源文件和.h头文件,最后再按照程序流程图将功能组合在一起,就形成了一个完整的产品

产品效果

一个物联网项目的雏形,可以采集设备温度,可以控制灯,温度可以通过网络上传到服务器,服务器也可以下发指令控制灯,也可通过Modbus协议进行本地设备的通信,走的是RS-485接口,上位机显示设备温度,同时可以设置设备的灯的亮度,通过长按按键可以控制设备进入低功耗模式,单击按键将设备唤醒,服务器也可以发送待机指令控制设备进入低功耗模式

产品功能

数码管显示PCB板温度;

上位机通过RS-485接口,Modbus协议与开发板通讯;

TCP服务器通过WIFI模块,TCP协议与开发板通讯;

按键1长按2s系统待机,待机功耗低至1.1uA;

按键1单击,系统恢复正常运行;

按键2单击,切换PWM灯亮度;

按键2双击,连接TCP服务器;

按键2长按,WIFI模块进入配网模式。

程序

文件结构

在这里插入图片描述

main.c ->主函数文件,包含 main函数,主要的系统框架,分为系统运行和系统待机,根据系统状态位改变;

Public.c ->公共函数文件,包含Delay延时函数、Memory_Clr内存清理函数、Error_Handler错误处理函数、Sys_Soft_Reset系统软件复位函数;

LED.c->LED外设函数,包含LED打开、关闭、翻转函数;

Sys_init.c->系统初始化函数,包含GPIO初始化函数、Power_ON_indication上电指示、IE_Init中断初始化函数、Sys_Init系统初始化函数,包含各种外设的初始化函数;

Timer0.c ->定时器函数,包含定时器初始化,中断服务函数;

KEY1.c->按键1函数,包含按键检测,使用的是外部中断检测方法,检测单击和长按;

KEY2.c->按键2函数,使用的是状态机来扫描按键2;

PWM.c ->PWM初始化、亮度调节、占空比储存与恢复函数等;

IAP.c->字节读、字节写、扇区擦除等函数;

UART1.c ->串口1初始化、发送字节、发送字符串、发送数组,RS-485开启和关闭,printf函数重定向,中断、串口协议解析等函数;

ADC.c->ADC初始化,采集ADC值、滤波算法函数等;

TM1620.c ->驱动IC TM1620的初始化,协议,温度显示等函数。

NTC.c ->NTC外设函数,包含获取NTC电压值,查表,获取环境温度;

CRC-16.c ->校验函数,主要包含CRC-16校验函数;

Modbus.c ->Modbus外设函数,主要包含Modbus 协议解析函数、根据功能码分为读保持寄存函数,写保持寄存器函数;

ESP8266.c -> WIFI模块函数,包含模块初始化、配网,连接服务器,发送PCB板温度、接收服务器信息等函数;

UART2.c->串口2的相关函数,发送字节、发送字符串、发送数组,中断,主要与WiFi模块通信;

System.c->系统文件,包含系统运行,进入待机配置,退出待机配置,系统待机等函数;

WatchDog.c ->看门狗文件,包含看门狗初始化与喂狗函数;

程序

main.c

如果产品有低功耗,则可以使用这个系统框架,根据系统状态位切换系统状态,分为系统运行和系统待机

因为public.h中没有预编译宏定义Monitor_Run_Code,所以不会往串口输出信息,而且这些本就是调试信息,在出产品时是不需要的

/*
* @name   main
* @brief  主函数
* @param  void	
* @retval int      
*/
int main(void)
{
	//系统初始化
	Hradware.Sys_Init();

	//串口1发送初始化信息
	#ifdef Monitor_Run_Code
		printf("Initialization completed,system startup!\r\n\r\n");
	#endif
	
	//系统主循环
	while(1)
	{
		if(System.ucSystem_Statues == System_Run)
		{
			System.Run();		//系统运行
		}
		else
		{
			System.StandBy();	//系统待机
		}
	}
}

System.c

系统运行函数Run(),系统正常运行时,所执行的功能

/*
* @name   Run
* @brief  系统运行
* @param  None
* @retval None   
*/
static void Run()
{
    static uint16_t i = 0;
    //获取PCB板温度
    NTC.Get_Temperature_Value();
    //数码管显示温度
    TM1620.Disp_Tempareture();

    //按键2双击
    if(KEY2.Double_Click == TRUE)
    {
        KEY2.Double_Click = FALSE;
        //连接TCP服务器
        ESP8266.TCP_Connect_Server();
    }
    //接收TCP服务器信息
    ESP8266.Receive_Information();
    //将温度通过TCP传到服务器
    ESP8266.Transfer_Tempareture(NTC.fTemperature);

    i = 500;
    while(i--)
    {
        Public.Delay_ms(1);
        //状态机扫描按键2
        KEY2.KEY_Detect();

        if(UART1.ucRec_Flag == TRUE)
        {
            break;
        }
        if(KEY1.KEY_Flag == TRUE)
        {
            break;
        }
        if(KEY2.KEY_Flag == TRUE)
        {
            break;
        }
    }
    //按键1检测,长按2S进入待机模式
    KEY1.KEY_Detect();
    //模块配网
    ESP8266.SmartConfig();
    //按键1触发调整PWM灯亮度
    PWM.PWM_LED_Adjust_Brightness();
    //串口1协议解析
    UART1.Protocol();
}

系统进入停机模式函数Halt(),由StandBy()函数调用;

/*
* @name   Halt
* @brief  系统停机模式,只能外部中断唤醒
* @param  None
* @retval None   
*/
static void Halt()
{
    //串口打印调试信息
    #ifdef Monitor_Run_Code
        printf("The MCU enter halt mode!\r\n\r\n");
    #endif

    //喂狗
    WatchDog.Feed();
    
    //进入停机配置
    Halt_Enter_Config();

    //进入掉电模式
    PCON |= BIT1;   //这里单片机已经停止运行,只有外部中断来了才能唤醒继续向下执行
    /*被唤醒后,手册要求执行4个空操作,因为单片机启动后可能不太稳定,所以
	用空操作等待系统稳定*/
    _nop_();
    _nop_();
    _nop_();
    _nop_();

    //退出停机配置
    Halt_Exit_Config();
    
    //串口打印调试信息
    #ifdef Monitor_Run_Code
        printf("The MCU Exit halt mode!\r\n");
    #endif

    System.ucSystem_Statues = System_Run;   //系统正常运行
    KEY1.KEY_Flag = FALSE;
}

系统流程图

在这里插入图片描述

系统运行流程图

在这里插入图片描述

按键1:

1、通过外部中断检测

2、长按超过2s,系统进入待机模式

3、单击,系统退出待机模式

按键2:

1、通过状态机扫描

2、单击,切换PWM灯亮度

3、双击,连接TCP服务器

4、长按超过2s,WIFI模块进行配网

定时器1:

间隔5ms中断一次,运行指示灯间隔1s闪烁一次

相关文章:

  • 直流有刷电机调速原理及Matlab/Simulink仿真
  • 基于bootstrap+Java+MySQL的高校成绩管理系统
  • java基于ssm+vue+elementui的旅游线路分享管理系统
  • 最近公共祖先 LCA
  • Deterministic Policy Gradient Algorithms
  • Java8时间日期库DateTime API及示例
  • np.random.seed(), torch.manual_seed(args.seed)
  • 真真正正的九面阿里才定级 P6+ 支持背调,还不来看?(建议收藏)
  • Fedora 24 Beta 版发布下载!
  • k-NN分类算法详解与分析(k近邻分类算法)
  • 03-数据链路层
  • Maven进阶实战
  • C++引用用法学习笔记
  • linux下的动态静态库
  • [GXYCTF2019]禁止套娃
  • 【MySQL经典案例分析】 Waiting for table metadata lock
  • 【跃迁之路】【735天】程序员高效学习方法论探索系列(实验阶段492-2019.2.25)...
  • angular2 简述
  • C++11: atomic 头文件
  • ES6系列(二)变量的解构赋值
  • flask接收请求并推入栈
  • Invalidate和postInvalidate的区别
  • js写一个简单的选项卡
  • Laravel核心解读--Facades
  • Redis中的lru算法实现
  • Unix命令
  • 从@property说起(二)当我们写下@property (nonatomic, weak) id obj时,我们究竟写了什么...
  • 分享几个不错的工具
  • 基于Android乐音识别(2)
  • 阿里云移动端播放器高级功能介绍
  • ​创新驱动,边缘计算领袖:亚马逊云科技海外服务器服务再进化
  • #define 用法
  • #我与Java虚拟机的故事#连载12:一本书带我深入Java领域
  • (4)logging(日志模块)
  • (9)STL算法之逆转旋转
  • (Bean工厂的后处理器入门)学习Spring的第七天
  • (Spark3.2.0)Spark SQL 初探: 使用大数据分析2000万KF数据
  • (补)B+树一些思想
  • (分类)KNN算法- 参数调优
  • (附源码)node.js知识分享网站 毕业设计 202038
  • (附源码)计算机毕业设计ssm基于Internet快递柜管理系统
  • (三)c52学习之旅-点亮LED灯
  • (十五)devops持续集成开发——jenkins流水线构建策略配置及触发器的使用
  • .NET Standard 的管理策略
  • .Net(C#)自定义WinForm控件之小结篇
  • .NET/C# 阻止屏幕关闭,阻止系统进入睡眠状态
  • .NET:自动将请求参数绑定到ASPX、ASHX和MVC(菜鸟必看)
  • .NET成年了,然后呢?
  • .NET面试题解析(11)-SQL语言基础及数据库基本原理
  • [ 云计算 | Azure 实践 ] 在 Azure 门户中创建 VM 虚拟机并进行验证
  • [AS3]URLLoader+URLRequest+JPGEncoder实现BitmapData图片数据保存
  • [Django 0-1] Core.Handlers 模块
  • [hdu 2826] The troubles of lmy [简单计算几何 - 相似]
  • [IE9] IE9 beta版下载链接
  • [IE编程] WebBrowser控件的多页面浏览(Tabbed Browsing)开发接口