Dear Sir, I have a problem about the union and bitfiled. I always suffer a strange problem in my system. After I check the M51 file, I start to doubt that it is the bitfield and union problem in compile stage. please see my code as below, I declare the union and macros in header file.
Question: Please see the line 1198, I call the macro Drv_ClearRxEnd(). At C:0x1AE3, it calls the C:269D. At C:0x269E ANL A,#IRCON2(0xBF) I don't know why to use the SFR register(IRCON2) to clear it.
Could you give me some clues? Thank you.
In Header file: typedef union{ U8 u8IsrStatus; struct{ U8 cc_tx_start:1; //set by ISR, clear by SW //LSB U8 cc_tx_end:1; //set by ISR, clear by SW U8 busbusy:1; //set by ISR, clear by SW U8 HardResetSignaling:1; U8 CableResetSignaling:1; U8 cc_rx_start:1; //set by ISR, clear by SW U8 cc_rx_end:1; //set by ISR, clear by SW U8 pluginout:1; //set and clear by ISR //MSB }Bits; }ISR_STATUS; extern ISR_STATUS volatile sISR_Status; #define Drv_GetCableRst() (sISR_Status.Bits.CableResetSignaling) #define Drv_GetHardRst() (sISR_Status.Bits.HardResetSignaling) #define Drv_GetRxEnd() (sISR_Status.Bits.cc_rx_end) #define Drv_ClearRxStart() {sISR_Status.Bits.cc_rx_start=0;} #define Drv_ClearRxEnd() {sISR_Status.Bits.cc_rx_end=0;} #define Drv_ClearRxStart() {WRITE_SFR_REG(LCD_LN0_4,0xBB);WRITE_SFR_REG(LCD_LN0_4,0xBB);sISR_Status.Bits.cc_rx_start=0;WRITE_SFR_REG(LCD_LN0_4,0xBB);WRITE_SFR_REG(LCD_LN0_4,0xBB);} #define Drv_ClearRxEnd() {WRITE_SFR_REG(LCD_LN0_4,0xBC);WRITE_SFR_REG(LCD_LN0_4,0xBC);sISR_Status.Bits.cc_rx_end=0;WRITE_SFR_REG(LCD_LN0_4,0xBC);WRITE_SFR_REG(LCD_LN0_4,0xBC);} In M51 file: C:0x1A72 900368 MOV DPTR,#sISR_Status(0x0368) C:0x1A75 E0 MOVX A,@DPTR C:0x1A76 F5B4 MOV LCD_LN0_4(0xB4),A C:0x1A78 E0 MOVX A,@DPTR C:0x1A79 F5B4 MOV LCD_LN0_4(0xB4),A 1179: WRITE_SFR_REG(LCD_LN0_4,0xFD);WRITE_SFR_REG(LCD_LN0_4,0xFD); 1180: #endif 1181: 1182: C:0x1A7B 75B4FD MOV LCD_LN0_4(0xB4),#0xFD C:0x1A7E 75B4FD MOV LCD_LN0_4(0xB4),#0xFD 1183: if(Drv_GetRxEnd() && !Drv_GetHardRst() && !Drv_GetCableRst()) C:0x1A81 E0 MOVX A,@DPTR C:0x1A82 20E603 JB 0xE0.6,C:1A88 C:0x1A85 021C5F LJMP C:1C5F C:0x1A88 E0 MOVX A,@DPTR C:0x1A89 30E303 JNB 0xE0.3,C:1A8F C:0x1A8C 021C5F LJMP C:1C5F C:0x1A8F E0 MOVX A,@DPTR C:0x1A90 30E403 JNB 0xE0.4,C:1A96 C:0x1A93 021C5F LJMP C:1C5F 1184: { 1185: DEBUG_PRLRX(0xAF); 1186: 1187: #if PRINTF_MSG_HEADER_RX C:0x1A96 75B5AF MOV LCD_LN0_5(0xB5),#0xAF ......Omit....... 1198: Drv_ClearRxEnd(); C:0x1ADD 1226A1 LCALL L?0396(C:26A1) C:0x1AE0 900368 MOV DPTR,#sISR_Status(0x0368) C:0x1AE3 12269D LCALL L?0395(C:269D) 1199: Drv_ClearRxStart(); 1200: 1201: C:0x1AE6 75B4BB MOV LCD_LN0_4(0xB4),#S1RELH(0xBB) C:0x1AE9 75B4BB MOV LCD_LN0_4(0xB4),#S1RELH(0xBB) C:0x1AEC E0 MOVX A,@DPTR C:0x1AED 54DF ANL A,#0xDF C:0x1AEF F0 MOVX @DPTR,A C:0x1AF0 75B4BB MOV LCD_LN0_4(0xB4),#S1RELH(0xBB) C:0x1AF3 75B4BB MOV LCD_LN0_4(0xB4),#S1RELH(0xBB) C:0x26A1 75B4BC MOV LCD_LN0_4(0xB4),#0xBC C:0x26A4 75B4BC MOV LCD_LN0_4(0xB4),#0xBC C:0x26A7 22 RET C:0x269D E0 MOVX A,@DPTR C:0x269E 54BF ANL A,#IRCON2(0xBF) C:0x26A0 F0 MOVX @DPTR,A C:0x26A1 75B4BC MOV LCD_LN0_4(0xB4),#0xBC C:0x26A4 75B4BC MOV LCD_LN0_4(0xB4),#0xBC C:0x26A7 22 RET
I don't know why to use the SFR register(IRCON2) to clear it.
It doesn't. The disassembler just referred to IRCON2 as a possible interpration of the raw value 0xBF. Whatever your undisclosed "strange problem" might be: this is has nothing to do with it.
Thanks for your reply. After I change the declaration as below, the system is more stable and I don't see the problem happened. Could I use union in 8051? Or should I do anything for union? Thanks.
typedef union{ U8 u8IsrStatus; struct{ U8 cc_tx_start:1; //set by ISR, clear by SW //LSB U8 cc_tx_end:1; //set by ISR, clear by SW U8 busbusy:1; //set by ISR, clear by SW U8 HardResetSignaling:1; U8 CableResetSignaling:1; U8 cc_rx_start:1; //set by ISR, clear by SW U8 cc_rx_end:1; //set by ISR, clear by SW U8 pluginout:1; //set and clear by ISR //MSB }Bits; }ISR_STATUS; Change to.... typedef struct{ U8 u8IsrStatus; struct{ U8 cc_tx_start; //set by ISR, clear by SW //LSB U8 cc_tx_end; //set by ISR, clear by SW U8 busbusy; //set by ISR, clear by SW U8 HardResetSignaling; U8 CableResetSignaling; U8 cc_rx_start; //set by ISR, clear by SW U8 cc_rx_end; //set by ISR, clear by SW U8 pluginout; //set and clear by ISR //MSB }Bits; }ISR_STATUS;
Your code could be a lot easier to follow:
You have made two major changes there: 1. Changing 'Bits' from a bitfield to a "plain" structure; 2. Changing 'ISR_Status' from a union to a structure.
"I don't see the problem happened"
I'm still not clear what actual "problem" you were having?
"Could I use union in 8051?"
Keil C51 certainly supports unions.
Whether its support of bitfields is particularly effecient is another question.
If you're after efficiency in grouping this collection of bits, then use a bit-addressable object:
http://www.keil.com/support/man/docs/c51/c51_le_bitaddrobj.htm