我在开å‘ä¸å°±é‡åˆ°è¿™ä¸ªé—®é¢˜ï¼Œæ»æ‰¾æ‰å‘现是用using引起的寄å˜å™¨åˆ‡æ¢é—®é¢˜ã€‚
网上看到梦游网å‹æ€»ç»“的。感觉就是大家å‰é¢çš„总结似的,呵呵
二ã€using的用法,usingå¯ä»¥ä¿®é¥°ä»»ä½•å‡½æ•°ï¼Œä¸è¿‡ä¸ªäººå»ºè®®åªç”¨æ¥ä¿®é¥°ä¸æ–函数;简å•çš„说,“usingâ€ä¼šæŒ‡å®šå·¥ä½œå¯„å˜å™¨ç»„,由于ä¸æ–函数一般都是比较紧急的事情,有时一æ¡è¯å¥éƒ½ä¼šæ–¤æ–¤è®¡è¾ƒï¼Œæ‰€ä»¥ä½¿ç”¨using切æ¢å¯„å˜å™¨ç»„å¯ä»¥çœåŽ»ä¸€äº›åŽ‹æ ˆçš„动作,由于51åªæœ‰ä¸¤çº§ä¸æ–,åŒçº§ä¸æ–ä¸èƒ½è¢«æ‰“æ–ï¼Œå› æ¤ï¼Œæˆ‘们å¯ä»¥åŒçº§ä¸æ–设æˆåŒæ ·çš„寄å˜å™¨ç»„,从æŸç§æ„义上æ¥è¯´ï¼Œæœ‰ä¸€ç»„寄å˜å™¨æ˜¯å¤šä½™çš„。åŒæ—¶ä¸ªäººå»ºè®®ä¸æ–函数应该使用using这个关键å—。 三ã€ä¸æ–ä¸è°ƒç”¨å‡½æ•°ï¼Œé¦–å…ˆè¦è®¨è®ºä¸æ–函数ä¸è°ƒç”¨å‡½æ•°çš„å¿…è¦æ€§ï¼Œå‰å¤©åœ¨è®ºå›ä¸Šæˆ‘和别人争论过这个问题,现在我还是这个观点:有些情况ä¸æ–ä¸è°ƒç”¨å‡½æ•°è¿˜æ˜¯å¿…è¦çš„,这个时候是ä¸æ˜¯è¯¥è°ƒç”¨å‡½æ•°ï¼Œå…¶å®žå’Œæ™®é€šå‡½æ•°å·®ä¸å¤šï¼Œé¦–先是这个函数如果调用多次,或者è¦å¸¦ä¸€äº›å‚æ•°ä»€ä¹ˆçš„å°±æ›´åŠ å¿…è¦çš„ï¼›å‰å¤©æœ‰äººè·Ÿæˆ‘å«åŠ²ï¼Œè¯´å‡å¦‚åªè°ƒç”¨ä¸€æ¬¡ä¸”æ— å‚æ•°æ— è¿”å›žçš„å‡½æ•°è¦ç›´æŽ¥å†™ï¼Œå› ä¸ºå¦‚æžœç”¨å‡½æ•°ï¼Œè‡³å°‘ä¼šå¢žåŠ CALLå’ŒRET两æ¡è¯å¥ï¼Œæˆ‘ä¸æ•¢è‹ŸåŒï¼Œæˆ‘是实际调试å‘çŽ°çš„ï¼Œå½“ä½ ç¨‹åºæ¯”较å¤æ‚æ—¶ï¼Œä½ å°†é‚£éƒ¨å•ç‹¬æ‹‰å‡ºæ¥åšæˆå‡½æ•°ï¼Œå¯èƒ½ä»£ç 和时间都会更好。 å››ã€ä¸æ–ä¸è°ƒç”¨çš„函数最好ä¸è¦è¢«ä¸æ–å¤–çš„å…¶å®ƒå‡½æ•°è°ƒç”¨ï¼Œå› ä¸ºä¼šå‡ºçŽ°â€œé‡å¤è°ƒç”¨â€çš„è¦å‘Šï¼Œæœ‰æ—¶è¿™ç§è°ƒç”¨æ˜¯å¾ˆè‡´å‘½çš„,有人说这个函数å¯ä»¥ç”¨reentrantæ¥ä¿®é¥°ï¼Œæ˜¯çš„,的确å¯ä»¥è¿™æ ·è§£å†³ï¼Œä¸è¿‡ä¸ªäººä¸å»ºè®®è¿™ä¹ˆåšï¼Œä¹Ÿè®¸è¿™æ ·ä¼šè·Ÿä½ å‡å°‘å¾ˆå¤šå †æ ˆç©ºé—´ï¼Œå¹¶ä¸”æ•´ä¸ªç¨‹åºçš„优化è¦å·®å¾ˆå¤šï¼Œä¸ªäººå»ºè®®å‡ºçŽ°è¿™ç§æƒ…况就把这个函数写两é,分æˆä¸¤ä¸ªå‡½æ•°åˆ†åˆ«è°ƒç”¨ã€‚ 五ã€ä¸æ–调用了函数,会出现一些莫å其妙的问题,一些数æ®ä¸å¯¹ï¼ˆæˆ‘现在é‡åˆ°è¿™ä¸ªé—®é¢˜ï¼‰å…¶å®žä¸€èˆ¬æ˜¯å› 为汇编ä¸ä½¿ç”¨äº†ç»å¯¹å¯„å˜å™¨å¼•èµ·çš„,有人说ä¸æ–函数使用那个寄å˜å™¨ç»„,被ä¸æ–调用的函数就使用哪个寄å˜å™¨ç»„(我认为好å‚考C51.PDF:Functions called from an interrupt procedure must function with the same register bank as the interrupt procedure. When the NOAREGS directive is not explicitly specified, the compiler may generate absolute register accesses using the register bank selected (by the using attribute or by the REGISTERBANK control) for that function. Unpredictable results may occur when a function assumes a register bank other than the one currently selected. Refer to “Register Bank Access†on page 124 for more information.ï¼‰ï¼Œæˆ‘è®¤ä¸ºè¿™æ ·ä¸å¥½ï¼š è¿™æ ·ä¼šå¢žåŠ é¢å¤–的消耗,使用usingä¼šå¢žåŠ ä¸€ä¸‹è¯å¥ï¼š PUSH PSW MOV PSW, #XX .... POP PSW æ›´é‡è¦çš„是,使用using的函数ä¸èƒ½æœ‰è¿”回值(这个地方有问题,应该å¯ä»¥æœ‰è¿”回值,下文说是ä¸èƒ½ä¸èƒ½è¿”回bit类型的值),这是致命伤(所以这ä¸æ˜¯è‡´å‘½ä¼¤ï¼Œå¯ä»¥ä½¿ç”¨using解决这个问题) 个人推è的方法有两ç§ï¼š 1ã€ä½¿ç”¨â€œ#pragma NOAREGSâ€ç¦æ¢ä½¿ç”¨ç»å¯¹å¯„å˜å™¨ 2ã€ä½¿ç”¨â€œ#pragme RB(x)â€æ¥æŒ‡å®šæœ¬æ–‡ä»¶çš„工作寄å˜å™¨ç»„ å…ã€ä¸€èˆ¬è¯´æ¥ï¼Œè¦æ±‚ä¸æ–函数尽å¯èƒ½çš„çŸï¼Œä½†ä¹Ÿæœ‰ç‰¹æ®Šæƒ…况,有些å‰/åŽå°çš„系统ä¸ï¼Œå°±ä¼šæŠŠå¾ˆå¤šç›¸å¯¹é‡è¦çš„事情放到定时ä¸æ–(这个定时ä¸æ–类似实时æ“作系统ä¸çš„时钟节æ‹ï¼‰åŽ»åšï¼Œè€Œä¸”程åºå¾ˆé•¿ã€‚我å•ç‹¬æ出æ¥è¿™ç‚¹æ˜¯æƒ³å‘Šè¯‰å¤§å®¶ï¼Œä¸æ–函数也是一个函数而已,åªè¦ç³»ç»Ÿæœ‰å¿…è¦ï¼Œå¯ä»¥åšä¸€äº›çœ‹ä¼¼ä¸åˆç†çš„事情,该出手时就出手,就åƒgotoè¯å¥ä¸€æ ·ã€‚ 转自http://www.**/blog/hotchip/,请大家去他的åšå®¢ä¸æ”¯æŒä»–,里é¢æœ‰ä¸é”™çš„æ–‡ç« ã€‚æ‹¬å·ä¸æ˜¯æˆ‘çš„ç†è§£ 关于using: 举个例åæ¥è¯´ï¼š 定义一个函数 void func(unsigned char i) { ... } 有如下一个ä¸æ–函数 void int_0(void) interrupt 0 using 1 { .... } 在默认状æ€ä¸‹,func使用寄å˜å™¨ç»„0(BANK0),那么当int_0调用func时是å¦å˜åœ¨å½“ä¼ é€’å‚æ•°æ—¶ä¼šé€ æˆå‚æ•°ä¼ é€’é”™è¯¯ï¼Ÿ 如果在ä¸æ–æœåŠ¡å‡½æ•°ISRä¸ä½¿ç”¨å¯„å˜å™¨,那么必须处ç†å¥½using的使用问题: 1ã€ä¸æ–æœåŠ¡å‡½æ•°ä½¿ç”¨using指定与主函数ä¸åŒçš„寄å˜å™¨ç»„(主函数一般使用Register bank 0)。 2ã€ä¸æ–优先级相åŒçš„ISRå¯ç”¨using指定相åŒçš„寄å˜å™¨ç»„,但优先级ä¸åŒçš„ISR必须使用ä¸åŒçš„寄å˜å™¨ç»„,在ISRä¸è¢«è°ƒç”¨çš„函数也è¦ä½¿ç”¨using指定与ä¸æ–函数相åŒçš„寄å˜å™¨ç»„ã€‚ï¼ˆåº”è¯¥æ˜¯è¿™æ ·çš„ï¼‰ 3ã€å¦‚æžœä¸ç”¨using指定,在ISRçš„å…¥å£,C51默认选择寄å˜å™¨ç»„0,这相当于ä¸æ–æœåŠ¡ç¨‹åºçš„å…¥å£é¦–先执行指令: MOV PSW #0 这点ä¿è¯äº†,没使用using指定的高优先级ä¸æ–。å¯ä»¥ä¸æ–使用ä¸åŒçš„寄å˜å™¨ç»„的低优先级ä¸æ–。 4ã€ä½¿ç”¨using关键å—ç»™ä¸æ–指定寄å˜å™¨ç»„,è¿™æ ·ç›´æŽ¥åˆ‡æ¢å¯„å˜å™¨ç»„而ä¸å¿…进行大é‡çš„PUSHå’ŒPOPæ“作,å¯ä»¥èŠ‚çœRAM空间,åŠ é€ŸMCU执行时间。寄å˜å™¨ç»„的切æ¢,总的æ¥è¯´æ¯”较容易出错,è¦å¯¹å†…å˜çš„使用情况有比较清晰的认识,å…¶æ£ç¡®æ€§è¦ç”±ä½ 自己æ¥ä¿è¯ã€‚特别在程åºä¸æœ‰ç›´æŽ¥åœ°å€è®¿é—®çš„时候,一定è¦å°å¿ƒè°¨æ…Žï¼è‡³äºŽâ€œä»€ä¹ˆæ—¶å€™è¦ç”¨åˆ°å¯„å˜å™¨ç»„切æ¢â€,一ç§æƒ…å†µæ˜¯ï¼šå½“ä½ è¯•å›¾è®©ä¸¤ä¸ªï¼ˆæˆ–ä»¥ä¸Šï¼‰ä½œä¸šåŒæ—¶è¿è¡Œ,而且它们的现场需è¦ä¸€äº›éš”离的时候,就会用上了。在ISR或使用实时æ“作系统RTOSä¸,寄å˜å™¨éžå¸¸æœ‰ç”¨ã€‚ 寄å˜å™¨ç»„使用的原则: 1ã€8051的最低32个å—节分æˆ4组8寄å˜å™¨ã€‚分别为寄å˜å™¨R0到R7。寄å˜å™¨ç»„ç”±PSW的低两ä½é€‰æ‹©ã€‚在ISRä¸,MCUå¯ä»¥åˆ‡æ¢åˆ°ä¸€ä¸ªä¸åŒçš„寄å˜å™¨ç»„。对寄å˜å™¨ç»„的访问ä¸å¯ä½å¯»å€,C51编译器规定使用using或ç¦æ¢ä¸æ–的函数(#pragma disable)å‡ä¸èƒ½è¿”回bit类型的值。 2ã€ä¸»ç¨‹åºï¼ˆmain函数)使用一组,如bank 0;低ä¸æ–优先级的所有ä¸æ–å‡ä½¿ç”¨ç¬¬äºŒç»„,如bank 1;高ä¸æ–优先级的所有ä¸æ–å‡ä½¿ç”¨å†å¦å¤–一组,如bank 2。显然,åŒçº§åˆ«çš„ä¸æ–使用åŒä¸€ç»„寄å˜å™¨ä¸ä¼šæœ‰é—®é¢˜,å› ä¸ºä¸ä¼šå‘生ä¸æ–嵌套;而高优先级的ä¸æ–则è¦ä½¿ç”¨ä¸Žä½Žä¼˜å…ˆçº§ä¸æ–ä¸åŒçš„一组,å› ä¸ºæœ‰å¯èƒ½å‡ºçŽ°åœ¨ä½Žä¼˜å…ˆçº§ä¸æ–ä¸å‘生高优先级ä¸æ–的情况。编译器会自动判æ–何时å¯ä½¿ç”¨ç»å¯¹å¯„å˜å™¨å˜å–。 3ã€åœ¨ISRä¸è°ƒç”¨å…¶å®ƒå‡½æ•°,必须和ä¸æ–使用相åŒçš„寄å˜å™¨ç»„。当没用NOAREGS命令åšæ˜Žç¡®çš„声明,编译器将使用ç»å¯¹å¯„å˜å™¨å¯»å€æ–¹å¼è®¿é—®å‡½æ•°é€‰å®šï¼ˆå³ç”¨using或REGISTERBANK指定)的寄å˜å™¨ç»„,当函数å‡å®šçš„和实际所选的寄å˜å™¨ç»„ä¸åŒæ—¶,将产生ä¸å¯é¢„知的结果,从而å¯èƒ½å‡ºçŽ°å‚æ•°ä¼ é€’é”™è¯¯,返回值å¯èƒ½ä¼šåœ¨é”™è¯¯çš„寄å˜å™¨ç»„ä¸ã€‚ 举一例å:当需è¦åœ¨ä¸æ–内和ä¸æ–外调用åŒä¸€ä¸ªå‡½æ•°,å‡å®šæŒ‰ç…§ç¨‹åºçš„æµç¨‹æŽ§åˆ¶,ä¸ä¼šå‡ºçŽ°å‡½æ•°çš„递归调用现象,è¿™æ ·çš„è°ƒç”¨ä¼šä¸ä¼šå‡ºçŽ°é—®é¢˜ï¼Ÿè‹¥ç¡®å®šä¸ä¼šå‘生é‡å…¥æƒ…况,则有以下两ç§æƒ…况: 1ã€å¦‚æžœISR和主程åºä½¿ç”¨åŒä¸€å¯„å˜å™¨ç»„(主程åºç¼ºçœä½¿ç”¨BANK 0,è‹¥ISR没有使用using为其指定寄å˜å™¨åŒº,则缺çœä¹Ÿä½¿ç”¨BANK 0),则ä¸éœ€å…¶ä»–设置。 2ã€å¦‚æžœISR和主程åºä½¿ç”¨ä¸åŒçš„寄å˜å™¨ç»„(主程åºç¼ºçœä½¿ç”¨BANK 0,ISR使用using指定了其他BANK),则被调用函数必须放在: #pragma NOAREGS #pragma AREGS 控制å‚数对ä¸,指定编译器ä¸è¦å¯¹è¯¥å‡½æ•°ä½¿ç”¨ç»å¯¹å¯„å˜å™¨å¯»å€æ–¹å¼;或者也å¯åœ¨Options->C51,选ä¸â€œDon't use absolute register accessesâ€,使所有代ç å‡ä¸ä½¿ç”¨ç»å¯¹å¯„å˜å™¨å¯»å€æ–¹å¼ï¼ˆè¿™æ ·,执行效率将ç¨æœ‰é™ä½Žï¼‰ã€‚ä¸è®ºä»¥ä¸Šçš„哪一ç§æƒ…况,编译器å‡ä¼šç»™å‡ºé‡å…¥è¦å‘Š,需手工更改OVERLAYå‚æ•°,åšé‡å…¥è¯´æ˜Žã€‚ 3ã€è¿˜æœ‰ä¸€ç§åŠžæ³•ï¼šå¦‚果被调用函数的代ç ä¸æ˜¯å¾ˆé•¿,还是将该函数å¤åˆ¶ä¸€ä»½,用ä¸åŒçš„函数å代替,è¿™ç§æƒ…况适åˆROM有足够多余的空间。 å› æ¤,对using关键å—的使用,如果没把æ¡,å®å¯ä¸ç”¨,交给编译系统自己去处ç†å¥½äº†ã€‚
|