我在开å‘ä¸å°±é‡åˆ°è¿™ä¸ªé—®é¢˜ï¼Œæ»æ‰¾æ‰å‘现是用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关键å—的使用,如果没把æ¡,å®å¯ä¸ç”¨,交给编译系统自己去处ç†å¥½äº†ã€‚
|