用于单片机编程的一种简单的主函数框架
2018-09-27 13:49
211 查看
常见的单片机最小系统(最小外围电路)中,会带有单片机、晶振、LDO、按键、LED指示灯。假如是使用STM32,现在通常会配合STM32CubeMX,快速生成初始化代码和工程项目文件。在生成了一套工程项目后,需要在文件的特定位置加上用户代码。
我对操作系统编程不熟悉,但需要把单片机对外扩模块的操作程序编成任务,每个任务在一秒钟内执行的次数不同。因此需要编个简单的框架,控制每个任务的执行次数。
[code]/* Private variables ---------------------------------------------------------*/ uint32_t counter_10ms, counter_50ms, counter_100ms, counter_500ms, counter_1000ms, counter_2000ms, counter_3s, counter_5s, counter_10s, counter_20s, counter_50s; uint8_t flag_1ms, flag_10ms, flag_50ms, flag_100ms, flag_500ms, flag_1000ms, flag_2000ms, flag_3s, flag_5s, flag_10s, flag_20s, flag_50s; int main(void) { //这里执行初始化代码 /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { if(flag_1ms ==1) { LEDSoftTimer(b_LED1Freq, b_LED1Duty, b_LED2Freq, b_LED2Duty); flag_1ms = 0; if(flag_ADCbusy==RESET) { ADC_GetData(); flag_ADCbusy = SET; if (HAL_ADC_Start_DMA(&hadc1, (uint32_t *)a_ADCxConvertedValues, 2) != HAL_OK) { Error_Handler(); } } } if(flag_10ms==1) { flag_10ms=0; } if(flag_50ms==1) { flag_50ms=0; } if(flag_100ms==1) { flag_100ms=0; SerialDisplay(); } if(flag_500ms==1) { flag_500ms=0; } if(flag_1000ms==1) { flag_1000ms=0; sec++; if(sec>0xff) sec = 0; } if(flag_2000ms==1) { flag_2000ms=0; } if(flag_3s==1) { flag_3s=0; } if(flag_5s==1) { flag_5s=0; } if(flag_10s==1) { flag_10s=0; } if(flag_20s==1) { flag_20s=0; } if(flag_50s==1) { flag_50s=0; } } /* USER CODE END 3 */ } //然后在systick中更新时间计数器和相关flag的值,systick中断由CPU定时器生成,每1ms中断一次 void HAL_SYSTICK_Callback(void) { flag_1ms = 1; /*update counters*/ if(counter_10ms<9) { counter_10ms++; } else { counter_10ms = 0; flag_10ms = 1; } if(counter_50ms<49) { counter_50ms++; } else { counter_50ms = 0; flag_50ms = 1; } if(counter_100ms<99) { counter_100ms++; } else { counter_100ms = 0; flag_100ms = 1; if(counter_500ms<4) { counter_500ms++; } else { counter_500ms = 0; flag_500ms = 1; } if(counter_1000ms<9) { counter_1000ms++; } else { counter_1000ms = 0; flag_1000ms = 1; UpdateDateTime(); if(counter_3s < 2) { counter_3s++; } else { counter_3s = 0; flag_3s = 1; } if(counter_5s < 4) { counter_5s++; } else { counter_5s = 0; flag_5s = 1; } if(counter_10s < 9) { counter_10s++; } else { counter_10s = 0; flag_10s = 1; } } if(counter_2000ms<19) { counter_2000ms++; } else { counter_2000ms = 0; flag_2000ms = 1; } } }
上面的程序中,每1ms执行一次ADC采样。还有每100ms执行一次程序把数据传输到上位机显示。直接把上面的代码复制到STM32CubeMX生成的项目文件,即可快速的分配CPU运算资源。
另外,最简单的状态机编程结构如下。
本例子用STM32和NodeMCU通信,驱动NodeMCU和手机连接,并通过TCP协议把一句句的信息传输到手机。
[code]void Proc_NodeMCU(void) { uint8_t CIPSEND_CustomSize[2]; uint8_t NodeMCU_ACK_res; if(Status_NodeMCU == 1) { 清空UART接收数据 发送AT指令 采用阻塞,超时的方式检查NodeMCU有没回传"OK\r\n"字符, 如果收到"OK\r\n": Status_NodeMCU=2;且flag_ProcNodeMCUActive=1;代表NodeMCU程序有效 否则无NodeMCU连接 } else if(Status_NodeMCU == 2) { 清空UART接收数据 发送AT指令配置成STATION模式 采用阻塞,超时的方式检查NodeMCU有没回传"OK\r\n"字符, 如果收到"OK\r\n": Status_NodeMCU=3; } else if(Status_NodeMCU == 3) { 清空UART接收数据 发送AT指令,控制NodeMCU连接AP 采用阻塞,超时的方式检查NodeMCU有没回传"OK\r\n"字符, 如果收到"OK\r\n": Status_NodeMCU=4; } else if(Status_NodeMCU == 4) { 清空UART接收数据 发送AT指令,NodeMCU和手机建立TCP连接 处理回传数据 如果正常:Status_NodeMCU=10; } else if(Status_NodeMCU == 10) { 清空UART接收数据 发送AT指令,控制NodeMCU进入数据透传模式,并发送信息包至手机 处理回传数据 如果正常:Status_NodeMCU=11; 如果不正常:Status_NodeMCU=4;将重新连接 } else if(Status_NodeMCU == 11) { 清空UART接收数据 发送AT指令控制NodeMCU进入低功率发送模式,减少射频干扰和功耗 Status_NodeMCU = 10;下次执行本程序可省去连接部分,直接控制NodeMCU进入数据透传模式 本次发送数据完成,flag_ProcNodeMCUActive=0; } else { Status_NodeMCU = 1; } }
还有一种状态机写法,
阅读更多相关文章推荐
- Windows编程 从消息窗口到基本窗口 游戏循环窗口框架的简单实现
- 一种简单的RPC框架
- minigui界面生成工具的一种简单实现方式,轻松实现Windows/linux minigui 跨平台界面编程
- 一个使用监听器模式实现的J2ME网络编程框架,包括一个简单的登录功能实现(含源代码)
- Unity编程笔录--ulua+PureMVC框架简单热更新使用
- 单片机编程主函数的特点
- java并发编程--Executor框架(一) 摘要: Eexecutor作为灵活且强大的异步执行框架,其支持多种不同类型的任务执行策略,提供了一种标准的方法将任务的提交过程和执行过程
- http 与 c++ 网络编程(用于简单的网络下载)
- 关于学习一种应用程序开发框架——谈编程的学习
- SharedPerferences 保存数据,android提供用于保存简单配置信息,标记,用户数据的一种方式
- 单片机的最简单的几个编程
- 控制台下实现简单的文本菜单及一般题目的主框架(可用于C/C++、特别是数据结构实验)
- 我的编程学习日志(4)-- 一种简单的测试代码的方法(freopen)
- 基于atmel mega88编写了一个简单的时间触发系统单片机框架程序
- 一个使用监听器模式实现的J2ME网络编程框架,包括一个简单的登录功能实现(含源代码)
- iOS 6编程-基于AV Foundation框架开发简单音乐播放器
- 【Unity--Apwork框架】AOP编程--拦截,用于缓存和异常处理(Unity框架的拦截注入-Interception)
- 我的编程学习日志(4)-- 一种简单的测试代码的方法(freopen)
- Socket编程及mina框架简单示例
- 简单编程(十三)编写一个方法用于求任意两个正整数的最大公约数