这是对我之前《如何假装用C语言为嵌入式写一个新语言》进行一个举例,以便更好地理解这种编程方式。

报头(S)报尾(E)

报头和报尾ASCII
BUGUS42 55 47 55 53
BUGUE42 55 47 55 45
CODES43 4f 44 45 53
CODEE43 4f 44 45 45
VORCS56 4f 52 43 53
VORCE56 4f 52 43 45
CONSTS43 4f 4e 53 54 53
CONSTE43 4f 4e 53 54 45
RVARS52 56 41 52 53
RVARE52 56 41 52 45
SAVES53 41 56 45 53
SAVEE53 41 56 45 45
WVARS57 56 41 52 53
WVARE57 56 41 52 45

控制指令

指令内容指令标号(用户不可见)参数1参数2
输入输出选择(基础IO模块)0x02引脚选择(暂时0x01-0x0a)输入0输出1
输出高低选择(基础IO模块)0x03引脚选择(暂时0x01-0x0a)低电平0高电平1
毫秒级延时(时序模块)0x04延时时间(暂时0x01-0xff)

程序逻辑指令

指令内容指令标号信息1信息2信息3信息4信息5信息6
循环启动器(程序基础控制模块)0x01CODE返回位VORC返回位CONST返回位RVAR返回位SAVE返回位WVAR返回位

举例

加入用户输入了这样一个程序:

flowchart TD
    st([开始])
    set5[设置5号引脚为输入]
    set6[设置6号引脚为输出]
    set6high[设置6号输出为高电平]
    con{"while(1)?"}
    blink_delay1[延时20ms]
    blink_set0[设置6号输出为低电平]
    blink_delay2[延时20ms]
    blink_set1[设置6号输出为高电平]

    st-->set5-->set6-->set6high-->con
    con-->|是|blink_delay1
    blink_delay1-->blink_set0-->blink_delay2-->blink_set1-->con

而我们的MCU工作流程如下:

graph TB
	subgraph MCU
	key(自动指针读)-->case[进入case]
	case-->para[参数获取]
	para-->isVar(自动指针读)
	isVar--常量-->const(自动指针读)
	isVar--变量-->readvarP(自动指针读)
	readvarP--read指针-->rvar[读变量数组]
	rvar-->ans[输出]
	const-->ans
	ans-->isSave(自动指针读)
	isSave--不保存-->case
	isSave--保存-->writevarP(自动指针读)
	writevarP--write指针-->wvar[写变量数组]
	wvar-->case
	end
	subgraph 指令表
	keyline[指令表CODE]-->key
	isVarline[判断选择变量0/常量表1VORC]-->isVar
	constline[常量表CONST]-->const
	readvarline[变量表的read指针表RVAR]-->readvarP
	isSaveline[判断是1否0保存输出表SAVE]-->isSave
	writevarline[变量表的write指针表WVAR]-->writevarP
	end

这里我们只截取其中一个函数的工作流程和并对循环方式进行说明:

sequenceDiagram
    participant P as 系统
    participant C as CODE
    participant V as VORC
    participant CO as CONST
    participant R as RVAR
    participant S as SAVE
    participant W as WVAR
    par 调用函数
    	C->>+P: 0x02
    	P-->>-C: 下标=1
    	Note over C,P: 输入输出选择
    and 传入形参
    	par 参数1
    	V->>+C: 0x01
    	C-->>-V: 下标=1
    	Note over V,C: 选择常数
    	CO->>+C: 0x05
    	C-->>-CO: 下标=1
    	Note over CO, C: 5号引脚
    	
    	and 参数2
    	V->>+C:0x01
    	C-->>-V: 下标=2
    	Note over V,C: 选择常数
    	CO->>+C: 0x00
    	C-->>-CO: 下标=2
    	Note over CO, C: 输入
    	end
    end
    
    par 调用函数
    	C->>+P: 0x02
    	P-->>-C: 下标=2
    	Note over C,P: 输入输出选择
    and 传入形参
    	par 参数1
    	V->>+C: 0x01
    	C-->>-V: 下标=3
    	Note over V,C: 选择常数
    	CO->>+C: 0x05
    	C-->>-CO: 下标=3
    	Note over CO, C: 6号引脚
    	
    	and 参数2
    	V->>+C:0x01
    	C-->>-V: 下标=4
    	Note over V,C: 选择常数
    	CO->>+C: 0x01
    	C-->>-CO: 下标=4
    	Note over CO, C: 输出
    	end
    end
    
    par 调用函数
    	C->>+P: 0x03
    	P-->>-C: 下标=3
    	Note over C,P: 输出高低选择
    and 传入形参
    	par 参数1
    	V->>+C: 0x01
    	C-->>-V: 下标=5
    	Note over V,C: 选择常数
    	CO->>+C: 0x05
    	C-->>-CO: 下标=5
    	Note over CO, C: 6号引脚
    	
    	and 参数2
    	V->>+C:0x01
    	C-->>-V: 下标=6
    	Note over V,C: 选择常数
    	CO->>+C: 0x01
    	C-->>-CO: 下标=6
    	Note over CO, C: 输出高电平
    	end
    end
    
    loop 循环启动器
    Note over P,W: 上位机中记录此时的下标:CODE=3,VORC=6,CONST=6,RVAR=0,SAVE=0,WVAR=0
    	par 调用函数
    		C->>+P: 0x04
    		P-->>-C: 下标=4
    		Note over C,P: 毫秒级延时
  		and 传入形参
    		par 参数1
    		V->>+C: 0x01
    		C-->>-V: 下标=7
    		Note over V,C: 选择常数
    		CO->>+C: 0x14
    		C-->>-CO: 下标=7
    		Note over CO, C: 20ms延时
    		end
    	end
    	
        par 调用函数
            C->>+P: 0x03
            P-->>-C: 下标=5
            Note over C,P: 输出高低选择
        and 传入形参
            par 参数1
            V->>+C: 0x01
            C-->>-V: 下标=8
            Note over V,C: 选择常数
            CO->>+C: 0x05
            C-->>-CO: 下标=8
            Note over CO, C: 6号引脚

            and 参数2
            V->>+C:0x01
            C-->>-V: 下标=9
            Note over V,C: 选择常数
            CO->>+C: 0x00
            C-->>-CO: 下标=9
            Note over CO, C: 输出低电平
            end
        end
        
        par 调用函数
    		C->>+P: 0x04
    		P-->>-C: 下标=6
    		Note over C,P: 毫秒级延时
  		and 传入形参
    		par 参数1
    		V->>+C: 0x01
    		C-->>-V: 下标=10
    		Note over V,C: 选择常数
    		CO->>+C: 0x14
    		C-->>-CO: 下标=10
    		Note over CO, C: 20ms延时
    		end
    	end
    	
    	par 调用函数
            C->>+P: 0x03
            P-->>-C: 下标=7
            Note over C,P: 输出高低选择
        and 传入形参
            par 参数1
            V->>+C: 0x01
            C-->>-V: 下标=11
            Note over V,C: 选择常数
            CO->>+C: 0x05
            C-->>-CO: 下标=11
            Note over CO, C: 6号引脚

            and 参数2
            V->>+C:0x01
            C-->>-V: 下标=12
            Note over V,C: 选择常数
            CO->>+C: 0x01
            C-->>-CO: 下标=12
            Note over CO, C: 输出高电平
            end
        end
    	
    	par 调用函数
            C->>P: 0x01
            Note over C,P: 循环回溯
        and 传入形参
            par CODE
            P->>C: 下标=3
            and VORC
            P->>V: 下标=6
            and CONST
            P->>CO:下标=6
            and RVAR
            P->>R:下标=0
            and SAVE
            P->>S:下标=0
            and WVAR
            P->>W:下标=0
            end
        end
        Note over P,W: 将下标指针返回到循环启动器开始时的状态
    end

这里需要注意的是在这个例子中我们其实并没有输出值的,所以没有对输出值进行操作,5号的demo版暂时先不做又返回值的功能。

通过以上的序列图,我们就可以写出我们的报文了:

graph TB
	BUGUS[BUGUS 42 55 47 55 53]
	BUGUE[BUGUE 42 55 47 55 45]
	CODES[CODES 43 4f 44 45 53]
	CODEE[CODEE 43 4f 44 45 45]
	VORCS[VORCS 56 4f 52 43 53]
	VORCE[VORCE 56 4f 52 43 45]
	CONSTS[CONSTS 43 4f 4e 53 54 53]
	CONSTE[CONSTE 43 4f 4e 53 54 45]
	RVARS[RVARS 52 56 41 52 53]
	RVARE[RVARE 52 56 41 52 45]
	SAVES[SAVES 53 41 56 45 53]
	SAVEE[SAVEE 53 41 56 45 45]
	WVARS[WVARS 57 56 41 52 53]
	WVARE[WVARE 57 56 41 52 45]
	CODE[CODE 02 02 03 04 03 04 03 01]
	BUGUS-->CODES-->CODE-->CODEE
	VORC[VORC 01 01 01 01 01 01 01 01 01 01 01 01]
	CODEE-->VORCS-->VORC-->VORCE
	CONST[CONST 05 00 05 01 05 01 14 05 00 14 05 01 03 06 06 00 00 00]
	VORCE-->CONSTS-->CONST-->CONSTE
	RVAR[RVAR]
	CONSTE-->RVARS-->RVAR-->RVARE
	SAVE[SAVE]
	RVARE-->SAVES-->SAVE-->SAVEE
	WVAR[WVAR]
	SAVEE-->WVARS-->WVAR-->WVARE-->BUGUE

​ 将该报文通过串口发送到单片机,单片机即可进行工作运行。