[問題] Sate Machine寫法(已解)
開發平台(Platform): 32bit/16bit MCU Ansi C
額外使用到的函數庫(Library Used): 沒有任何LIB
問題(Question):
State Machine寫法
餵入的資料(Input):
預期的正確結果(Expected Output):
可以根據外面的狀態變化,可以自動跳到任何狀態.
錯誤結果(Wrong Output):
程式碼(Code):
我的宣告如下
enum m_state
{
idle,PFC_ON, PSU_wake, PSU_RUN,
};
enum m_state PSU_sate;
int main(void)
{
unsigned int i = 0;
// Disable the JTAG function
INIT();
// P_FC_O=1;
// P_FC_O=0;
Init_PM_I2C2();
PMADDR_check();
// ClearCommandData(); /* Clear commands RAM locations */
// WrTestCommandData();
Init_PM_REG();
InitTMR1();
//InitTMR2(); running at Init(); funciton
Init_TMR3(); //Warring Timer3 for PMBUS Don't change it
InitTMR5();
for(i=0;i<256;i++) //Black box rom test
{
Black_BOX.ROM.EEPROM[i]=i;
//P_Debug_O= ~P_Debug_O;
}
Self_Test();
while( 1 )
{
if(global_flags.ready_to_copy == 1) /* Buffer ready to be copied? */
{
global_flags.ready_to_copy = 0;
CopyBufferInRam();
}
if(PSU_sate==PFC_ON)
{
}
else if(PSU_sate==idle)
{
}
else if(PSU_sate==PSU_wake)
{
}
else if(PSU_sate==PSU_RUN)
{
}
if(P_47_AC_I==IO_Low)
{
}
if(IO_FLAG.ADCDONE==1) //When get ADC value , convert ADC value to PBBUS
Stack
{
convert_adc();
}
if(IO_FLAG.CONVERTDONE==1)
{
Check_UVOP();
}
}
while( 1 );
}
補充說明(Supplement):
希望達到下面這一個sate_machine
http://ppt.cc/c5yr
--
在臺灣,何謂R&D工程師?
1.Reverse and Decap :IC反向工程,去膠,打開封裝,拍照,複製電路佈局。
2.Resign and Die :沒死的就操到辭職,沒辭職的就操到死。
3.Rework and Debug :計畫永遠跟不上變化,變化永遠跟不上老闆的一句話!
4.Relax and Delay :太過於輕鬆(Relax),那麼就要有schedule delay的準備!
但是外派到大陸的臺灣郎,晚上是R (鴨)陪客戶,白天是D (豬)任人宰割!
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 101.12.169.253
※ 文章網址: http://www.ptt.cc/bbs/C_and_CPP/M.1403492236.A.BCE.html
※ 編輯: kingzero (101.12.169.253), 06/23/2014 11:09:43
→
06/23 11:15, , 1F
06/23 11:15, 1F
→
06/23 11:16, , 2F
06/23 11:16, 2F
→
06/23 11:16, , 3F
06/23 11:16, 3F
我沒有加洋蔥~~可能是你橘子加太多了.
→
06/23 11:17, , 4F
06/23 11:17, 4F
→
06/23 11:18, , 5F
06/23 11:18, 5F
→
06/23 11:22, , 6F
06/23 11:22, 6F
程式是我自己寫的,謝謝指教阿~~
→
06/23 11:37, , 7F
06/23 11:37, 7F
→
06/23 11:37, , 8F
06/23 11:37, 8F
我想這一個就是"眉角"吧,難怪我寫起來哪裡卡卡的.感謝提醒.
→
06/23 11:38, , 9F
06/23 11:38, 9F
→
06/23 11:39, , 10F
06/23 11:39, 10F
※ 編輯: kingzero (101.12.169.253), 06/23/2014 11:51:09
→
06/23 13:29, , 11F
06/23 13:29, 11F
謝謝樓上~~我剛剛試了一下.我的complier看來不支援C++語法.
參考這一篇
http://sourcemaking.com/design_patterns/chain_of_responsibility/cpp/1
連宣告都不會過.
class Base
{
// Base *next; // 1. "next" pointer in the base class
};
感謝你提供意見.
※ 編輯: kingzero (101.12.169.253), 06/23/2014 15:02:12
→
06/23 15:50, , 12F
06/23 15:50, 12F
→
06/23 15:53, , 13F
06/23 15:53, 13F
→
06/23 15:53, , 14F
06/23 15:53, 14F
回樓上..改成switch case的方式我是有想過.但是實際上面執行起來可能會讓我的速度變慢.
不是說這種寫法不好,而是我的CPU速度只有40Mhz(這算非常快速的了).一般而言大約30.
switch case 會compiler之後可能會變成幾十行的程式.可能會拖慢執行的時間.
一切都是可能啦.其實我可以做一個實驗就知道了.
兩種寫法看他的執行速度就知道了.
恩~~就這樣子辦.好了之後再把比較圖PO上來.
※ 編輯: kingzero (101.12.169.253), 06/23/2014 16:24:49
好啦...實驗做完了.
下面這一張是使用if else作的連續9個判斷的時間.循環一次需要4.62us
http://ppt.cc/fBNM
下面這幾張就很有趣了.
使用switch case作的,會有抖動.有的時候時間常有的時候時間短.
短的時候居然比if else短.長的時候居然比較長.
根if else比較
http://ppt.cc/Bpv9
比較短的時間 4.08us
http://ppt.cc/T4IS
比較長的時間 5.1us
http://ppt.cc/EMIY
程式如下
while(1)
{
if(global_flags.ready_to_copy == 1) /* Buffer ready to be copied? */
{
global_flags.ready_to_copy = 0;
CopyBufferInRam();
}
switch(PSU_state)
{
case POR:
PSU_state=RUN;
break;
case RUN:
PSU_state=CON_ADC;
P_Debug_O= ~P_Debug_O;
break;
case CON_ADC:
PSU_state=CHK_UVOP;
break;
case CHK_UVOP:
PSU_state=CHK_FAN;
break;
case CHK_FAN:
PSU_state=CHK_OT;
break;
case CHK_OT:
PSU_state=CHK_IO;
break;
case CHK_IO:
PSU_state=RUN;
break;
case shunt_Down:
break;
case Save_BlackBox:
break;
}
}
//----------------分段線
while(1)
{
if(global_flags.ready_to_copy == 1) /* Buffer ready to be copied? */
{
global_flags.ready_to_copy = 0;
CopyBufferInRam();
}
if(PSU_state==POR)
{
PSU_state=RUN;
}
else if(PSU_state==RUN)
{
PSU_state=CON_ADC;
P_Debug_O= ~P_Debug_O;
}
else if(PSU_state==CON_ADC)
{
PSU_state=CHK_UVOP;
}
else if(PSU_state==CHK_UVOP)
{
PSU_state=CHK_FAN;
}
else if(PSU_state==CHK_FAN)
{
PSU_state=CHK_OT;
}
else if(PSU_state==CHK_OT)
{
PSU_state=CHK_IO;
}
else if(PSU_state==CHK_IO)
{
PSU_state=RUN;
}
else if(PSU_state==shunt_Down)
{
}
else if(PSU_state==Save_BlackBox)
{
}
}
※ 編輯: kingzero (101.12.169.253), 06/23/2014 17:03:48
推
06/23 17:03, , 15F
06/23 17:03, 15F
→
06/23 17:05, , 16F
06/23 17:05, 16F
→
06/23 17:06, , 17F
06/23 17:06, 17F
推
06/23 17:12, , 18F
06/23 17:12, 18F
C語言ptr不會用來改變PC(Program Counter).你那裏有範例可以參考嗎?
如果有我可以測試看看.
goto 我想想看怎麼做到比較之後再回你.
但是比較來也是使用if指令,那這樣子跟if else有什麼區別?
推
06/23 17:28, , 19F
06/23 17:28, 19F
應該是其他中斷造成的.這不是整隻完成的程式,還有其他高優先權的硬體在動作.
可能是其他高優先權的硬體在執行吧.
但是如過這樣子說的話 switch case就不太合理了.
推
06/23 18:11, , 20F
06/23 18:11, 20F
→
06/23 18:12, , 21F
06/23 18:12, 21F
一樣的問題,沒有想到過如何撰寫.在組合語言裡面確實是這樣子做.
使用test 或 sub 或decz的命令來完成.
沒有想到怎麼寫的原因是不知道如何使用bit指令去判斷 enum
→
06/23 20:29, , 22F
06/23 20:29, 22F
→
06/23 20:29, , 23F
06/23 20:29, 23F
推
06/23 22:26, , 24F
06/23 22:26, 24F
CoR之前真的是沒有寫過,所以要查一下資料.但是我查了一下,好像都是C++的.
請問您那裏有有CoR使用C的範例嗎?
下面是google的C++語法
http://openhome.cc/Gossip/DesignPattern/ChainofResponsibility.htm
http://www.cnblogs.com/zhenyulu/articles/65850.html
→
06/23 22:26, , 25F
06/23 22:26, 25F
→
06/23 22:27, , 26F
06/23 22:27, 26F
推
06/23 22:52, , 27F
06/23 22:52, 27F
→
06/23 23:24, , 28F
06/23 23:24, 28F
這一點讓我延伸出另外一個問題.是否不同的CPU同樣的C code會有不同的結果.
我已經請我的同事那一段code換成8bit 32Mhz(16Mhz)的CPU試試看.
如果他的程度OK的話,應該今天會有結果.
推
06/23 23:42, , 29F
06/23 23:42, 29F
我也推一個組合語言真的是這樣子做的.只是組合根C的轉換就需要sense了.
→
06/24 00:17, , 30F
06/24 00:17, 30F
→
06/24 00:18, , 31F
06/24 00:18, 31F
→
06/24 00:18, , 32F
06/24 00:18, 32F
→
06/24 00:19, , 33F
06/24 00:19, 33F
→
06/24 00:19, , 34F
06/24 00:19, 34F
回老大..我還正在找CoR的C語言範例code.
※ 編輯: kingzero (101.8.11.95), 06/24/2014 11:13:58
補一下剛剛看到的有趣又生動的說明
http://www.kenming.idv.tw/a_euseu_aupaf_a_a_chain_of_responsibilit
※ 編輯: kingzero (101.8.11.95), 06/24/2014 11:22:41
推
06/24 12:45, , 35F
06/24 12:45, 35F
推
06/24 13:42, , 36F
06/24 13:42, 36F
→
06/24 14:00, , 37F
06/24 14:00, 37F
→
06/24 14:01, , 38F
06/24 14:01, 38F
我直接把結果貼上來啦
下面是switch case的圖 只花了7.02us
http://ppt.cc/xM1r
下面是if else的 花了9us
http://ppt.cc/9bis
結論~~看來超過5個的判斷應該要使用 switch case.速度比較快.
下面是我在網路上面看到的CoR寫法.
我有一個問題,如果是在同一個狀態下有三種以上的跳CoR可以處理嗎?
//2012-12-15
//author?@quanwei
typedef struct stack{
int data;
struct stack *pNext;
}STACK;
/*************************************/
//? Push(STACK *top,int elem)
//? STACK *top
// int elem
//? elem
//? ?
/*************************************/
STACK *Push(STACK *top,int elem){
STACK *stack = (STACK *)malloc(sizeof(STACK));
if(stack == NULL) printf("ERROR!");
stack->data = elem;
stack->pNext = top->pNext;
top->pNext= stack;
return top;
}
/*************************************/
//? Pop(STACK *top)
//? STACK *top
//?
//? ?
/**************************************/
int Pop(STACK *top){
if(top == NULL){
printf("The stack is already empty");
exit(1);
}
STACK *temp = top->pNext;
int elem = temp->data;
top->pNext = temp->pNext;
return (elem);
}
/*************************************/
//? GgtTop(STACK *top)
//? STACK *top
//?
//? ?
/**************************************/
int GetTop(STACK *top){
if(top == NULL){
// printf("The stack is already empty");
return 0;
}
return top->pNext->data;
}
/************** *******************/
void state_main(){
STACK *stack = (STACK *)malloc(sizeof(STACK)); //
STACK *top = stack;
top->pNext = NULL;
char ch = 'y';
int num;
while(ch == 'y'){
// printf("Input element");
// scanf("%d",&num);
fflush(stdin);
Push(top,num);
// printf("go on?(y/n)");
// scanf("%c",&ch);
fflush(stdin);
}
// printf("The top element of the stack is:%4d",GetTop(top));
// printf("now pop stack\n");
while(top->pNext!= NULL){
printf("%4d",Pop(top));
}
}
※ 編輯: kingzero (101.8.11.95), 06/24/2014 15:01:36
推
06/24 15:58, , 39F
06/24 15:58, 39F
老實說那怎麼用我還不知道.我問一下朋友.
→
06/24 16:55, , 40F
06/24 16:55, 40F
我也是第一次知道這一個東西.我試試看gist怎們操作吧.
下次改善~~
→
06/24 16:55, , 41F
06/24 16:55, 41F
※ 編輯: kingzero (101.8.11.95), 06/24/2014 18:00:18
→
06/24 22:03, , 42F
06/24 22:03, 42F
收到~~了解.我應該會用了.
先跟大家報告一下.我決定先用swith case做.先把其他的功能先完成.
再回來看這一個問題.
※ 編輯: kingzero (101.8.1.204), 06/25/2014 13:37:23
→
06/26 15:19, , 43F
06/26 15:19, 43F
→
06/26 15:20, , 44F
06/26 15:20, 44F
推
06/26 19:16, , 45F
06/26 19:16, 45F
→
06/26 23:15, , 46F
06/26 23:15, 46F
推
06/27 02:34, , 47F
06/27 02:34, 47F
推
06/27 19:56, , 48F
06/27 19:56, 48F
→
06/27 20:07, , 49F
06/27 20:07, 49F
※ 編輯: kingzero (115.82.184.179), 07/15/2014 11:35:37