⽤于单⽚机编程的⼀种简单的主函数框架
常见的单⽚机最⼩系统(最⼩外围电路)中,会带有单⽚机、晶振、LDO、按键、LED指⽰灯。假如是使⽤STM32,现在通常会配合
STM32CubeMX,快速⽣成初始化代码和⼯程项⽬⽂件。在⽣成了⼀套⼯程项⽬后,需要在⽂件的特定位置加上⽤户代码。
我对操作系统编程不熟悉,但需要把单⽚机对外扩模块的操作程序编成任务,每个任务在⼀秒钟内执⾏的次数不同。因此需要编个简单的框
架,控制每个任务的执⾏次数。
/* Private variables ---------------------------------------------------------*/
uint32_t counter_10ms, counter_50ms, counter_100ms, counter_500ms, counter_1000ms, counter_2000ms, counter_3s, counter_5s, counter_10s, counter_20s 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) {
if(counter_2000ms<19) {
counter_2000ms++;
} else {
counter_2000ms = 0;
flag_2000ms = 1;
}
}
}
上⾯的程序中,每1ms执⾏⼀次ADC采样。还有每100ms执⾏⼀次程序把数据传输到上位机显⽰。直接把上⾯的代码复制到STM32CubeMX⽣成的项⽬⽂件,即可快速的分配CPU运算资源。
另外,最简单的状态机编程结构如下。
本例⼦⽤STM32和NodeMCU通信,驱动NodeMCU和⼿机连接,并通过TCP协议把⼀句句的信息传输到⼿机。
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;
}
}
还有⼀种状态机写法,

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。