Flag Clearing methods with codewarrior

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

Flag Clearing methods with codewarrior

4,523 次查看
sfb
Contributor I
Hi,
I am trying to use PIT module in MC9S12XDT512. I found S12PIT24B4CV1 document about it. But I couldn't understand that how to do flag clearing (without BSET) by codewarrior. When I looked at disassambled code I see that always BSET instructions for clear commands. Is there any way for clearing flag with MOV instruction (but without writing assembly).

(S12PIT24B4CV1)

13.5.3 Flag Clearing

A flag is cleared by writing a one to the flag bit. Always use store or move instructions to write a one in

certain bit positions. Do not use the BSET instructions. Do not use any C-constructs that compile to BSET

instructions. “BSET flag_register, #mask” must not be used for flag clearing because BSET is a

read-modify-write instruction which writes back the “bit-wise or” of the flag_register and the mask into

the flag_register. BSET would clear all flag bits that were set, independent from the mask.

For example, to clear flag bit 0 use: MOVB #$01,PITTF.

标签 (1)
0 项奖励
回复
4 回复数

890 次查看
Technoman64
Contributor III
Yes set the whole byte. When writing to the HCS(X)12 flag registers all bits that are 0 are ignored and only the bit(s) that are 1 clear the flag for that bit position.
 
For all other registers, memory locations all bit values are written.
0 项奖励
回复

890 次查看
sfb
Contributor I
Thanks. For example if I changed PORTB_B4 pin status BSET used but when I changed all of PORTB BSET didn't used. So when changing status flags should I change all byte instead of bit wise?
0 项奖励
回复

890 次查看
kef
Specialist I
sfb,
 
I don't know why you asked about PORTB. PORTB is like regular RAM variable, you can BCLR and BSET, do anything with PORTB. But flags that reset to zero when you write ones to them, they are just a little complicated. Technoman64 advices are good, but you may wish to bust some myths and get familiar with these flags..
 
 
Suppose you are using two ECT channels. One IC/OC channel is logically connected to bit1 of TFLG1, and another one to bit0 of TFLG1.
- Suppose both bits are set, TFLG1 reads as 0x03.
- You want to clear bit0. You do (bad code just for excercise:smileyhappy: TFLG1 |= 0x01;  
- We had 0x03; we bit-OR it with 0x01; we get 0x03; we write 0x03 to TFLG1. OOPS, it will clear both bits instead of just one bit! Is it clear? I hope it is.
 
 
CodeWarrior has macros and bitfield #defines for all registers, all register bits and flags. Be careful with flag bits defines. You can read from flag bits (flags bitfields actually), but you shouldn't use flag bitfields to clear flags. For example TFLG1_C0F bit. It expands to _TFLG1.Bits.C0F. You may read TFLG1_C0F as many times as you wish without any side effect. But, you can't write to TFLG1_C0F without affecting other TFLG1 bits. Let's see how:
 
1) Wrong line TFLG1_C5F=1 would make CPU read TFLG1 register; bit-OR it with (1<<5)=0x20; and finally write result of bit-ORing back to TFLG1. Of course this will clear all flags that were set at the time CPU read TFLG1.
 
2) Wrong line TFLG1_C5F=0 would make CPU read TFLG1 register; bit-AND it with ~(1<<5)=0xBF, then write result of bit-ANDing back to TFLG1. Funny result. TFLG1_C5F won't clear, but all other TFLG1 bits, that were set, will reset to zero.
 
 
 
I recommend reading M68HC11 Microcontrollers Reference Manual chapter 10.4.4 Tips for clearing Timer Flags
 
HC11 manual suggests clearing timer flags using two ways:
1) use load bit-mask to accumulator, then store accumulator to flag register. This corresponds to C 
 
    TFLG1=(1<<N); //where N is bit number.
 
2) use BCLR instruction with *inverse* bit-mask.  To clear bit5 you would need to BCLR  TFLG1,#$BF. In C this corresponds to
 
    TFLG1 &= (1<<N);
 
Let's try to decifier it.
- Suppose both bits are set, TFLG1 reads as 0x03.
- You want to clear bit0. You do TFLG1 &= 0x01;  
- We had 0x03; we bit-AND it with 0x01; we get 0x01; we write 0x01 to TFLG1. Bingo, TFLG1 &= 0x01  will clear only bit we specified. 
 
 
Hope it helps
0 项奖励
回复

890 次查看
Technoman64
Contributor III
Just use assigment instructions with c code and avoid logical operations.
 
For example
 
/* Correct method, this writes value directly to the register */
PITTF = 0x01;
 
/* Incorrect metoid, this will generate a bset instruction */
PITTF |= 0x01
0 项奖励
回复