在嵌入式開發過程中,將IO寄存器中的某1位或幾位進行拉高(置1)、拉低(置0)是最常用,現以dsPIC33F芯片爲例,介紹一下這方面的編程技巧。
比如定義頭文件,如下:
ClrBitMaskW[]={0xFFFE,0xFFFD,0xFFFB,0xFFF7,
0xFFEF,0xFFDF,0xFFBF,0xFF7F,
0xFEFF,0xFDFF,0xFBFF,0xF7FF,
0xEFFF,0xDFFF,0xBFFF,0x7FFF};
SetBitMaskW[]={0x0001,0x0002,0x0004,0x0008,
0x0010,0x0020,0x0040,0x0080,
0x0100,0x0200,0x0400,0x0800,
0x1000,0x2000,0x4000,0x8000};
extern void LATABitClr( INT16U n);
extern void LATABitSet( INT16U n);
extern void LATBBitClr( INT16U n);
extern void LATBBitSet( INT16U n);
extern void LATCBitClr( INT16U n);
extern void LATCBitSet( INT16U n);
extern void LATDBitClr( INT16U n);
extern void LATDBitSet( INT16U n);
extern void LATEBitClr( INT16U n);
extern void LATEBitSet( INT16U n);
extern void LATFBitClr( INT16U n);
extern void LATFBitSet( INT16U n);
extern void LATGBitClr( INT16U n);
extern void LATGBitSet( INT16U n);
#endif
C語言文件,如下:
/********************************************************/
//A口位操作,n的取值範圍:0~15
void LATABitClr( INT16U n)
{
__asm__ volatile("mov.w #_ClrBitMaskW,w1");
__asm__ volatile("add.w w0,w0,w0");
__asm__ volatile("mov.w [w0+w1],w0");
__asm__ volatile("and.w LATA");
}
void LATABitSet( INT16U n)
{
__asm__ volatile("mov.w #_SetBitMaskW,w1");
__asm__ volatile("add.w w0,w0,w0");
__asm__ volatile("mov.w [w0+w1],w0");
__asm__ volatile("ior.w LATA");
}
/********************************************************/
//B口位操作,n的取值範圍:0~15
void LATBBitClr( INT16U n)
{
__asm__ volatile("mov.w #_ClrBitMaskW,w1");
__asm__ volatile("add.w w0,w0,w0");
__asm__ volatile("mov.w [w0+w1],w0");
__asm__ volatile("and.w LATB");
}
void LATBBitSet( INT16U n)
{
__asm__ volatile("mov.w #_SetBitMaskW,w1");
__asm__ volatile("add.w w0,w0,w0");
__asm__ volatile("mov.w [w0+w1],w0");
__asm__ volatile("ior.w LATB");
}
/********************************************************/
//C口位操作,n的取值範圍:0~15
void LATCBitClr( INT16U n)
{
__asm__ volatile("mov.w #_ClrBitMaskW,w1");
__asm__ volatile("add.w w0,w0,w0");
__asm__ volatile("mov.w [w0+w1],w0");
__asm__ volatile("and.w LATC");
}
void LATCBitSet( INT16U n)
{
__asm__ volatile("mov.w #_SetBitMaskW,w1");
__asm__ volatile("add.w w0,w0,w0");
__asm__ volatile("mov.w [w0+w1],w0");
__asm__ volatile("ior.w LATC");
}
/********************************************************/
//D口位操作,n的取值範圍:0~15
void LATDBitClr( INT16U n)
{
__asm__ volatile("mov.w #_ClrBitMaskW,w1");
__asm__ volatile("add.w w0,w0,w0");
__asm__ volatile("mov.w [w0+w1],w0");
__asm__ volatile("and.w LATD");
}
void LATDBitSet( INT16U n)
{
__asm__ volatile("mov.w #_SetBitMaskW,w1");
__asm__ volatile("add.w w0,w0,w0");
__asm__ volatile("mov.w [w0+w1],w0");
__asm__ volatile("ior.w LATD");
}
/********************************************************/
//E口位操作,n的取值範圍:0~15
void LATEBitClr( INT16U n)
{
__asm__ volatile("mov.w #_ClrBitMaskW,w1");
__asm__ volatile("add.w w0,w0,w0");
__asm__ volatile("mov.w [w0+w1],w0");
__asm__ volatile("and.w LATE");
}
void LATEBitSet( INT16U n)
{
__asm__ volatile("mov.w #_SetBitMaskW,w1");
__asm__ volatile("add.w w0,w0,w0");
__asm__ volatile("mov.w [w0+w1],w0");
__asm__ volatile("ior.w LATE");
}
/********************************************************/
//F口位操作,n的取值範圍:0~15
void LATFBitClr( INT16U n)
{
__asm__ volatile("mov.w #_ClrBitMaskW,w1");
__asm__ volatile("add.w w0,w0,w0");
__asm__ volatile("mov.w [w0+w1],w0");
__asm__ volatile("and.w LATF");
}
void LATFBitSet( INT16U n)
{
__asm__ volatile("mov.w #_SetBitMaskW,w1");
__asm__ volatile("add.w w0,w0,w0");
__asm__ volatile("mov.w [w0+w1],w0");
__asm__ volatile("ior.w LATF");
}
/********************************************************/
//G口位操作,n的取值範圍:0~15
void LATGBitClr( INT16U n)
{
__asm__ volatile("mov.w #_ClrBitMaskW,w1");
__asm__ volatile("add.w w0,w0,w0");
__asm__ volatile("mov.w [w0+w1],w0");
__asm__ volatile("and.w LATG");
}
void LATGBitSet( INT16U n)
{
__asm__ volatile("mov.w #_SetBitMaskW,w1");
__asm__ volatile("add.w w0,w0,w0");
__asm__ volatile("mov.w [w0+w1],w0");
__asm__ volatile("ior.w LATG");
}
/********************************************************/
可能有部分初學者對彙編語言不是很熟悉,現簡單介紹如下:
//A口位操作,n的取值範圍:0~15
void LATABitClr( INT16U n)
{
__asm__ volatile("mov.w #_ClrBitMaskW,w1"); //將數組ClrBitMaskW的首地址賦給寄存器w1
__asm__ volatile("add.w w0,w0,w0"); //w0=w0+w0即:w0=2*w0 注意:默認w0寄存器存放的是n的值
__asm__ volatile("mov.w [w0+w1],w0"); //將數組首地址往下偏移w0(w0=2n),並將地址的值取出來賦給w0即:取出對應數組的值 __asm__ volatile("and.w LATA"); //w0和寄存器LATA的值做‘與’操作,將結果賦給寄存器LATA 即:LATA&=w0
}