基於C語言的編碼器(光耦)程式設計之C程式碼解析(二)
阿新 • • 發佈:2018-12-14
程式碼需要一個.c文件和一個.h文件。
.h文件主要配置編碼器相關引數
#define OptoKnobNumber 2 /* 旋鈕個數配置 */ #define _01_SHIFT_BIT_ 0x01 /* 移動位數值 */ #define _02_SHIFT_BIT_ 0x02 /* 移動位數值 */ #define _01_GET_BIT_ 0x01 /* 獲取位數值 */ #define _034b_OptoKnob_CW_WAVE_ 0x034b /*11 01 00 10 11 正向旋轉波形*/ #define _0387_OptoKnob_CCW_WAVE_ 0x0387 /*11 10 00 01 11 反向旋轉波形*/ #define _3f_Knob_MaxValue_ 0x3f /* 最大檔位配置 */ #define _00_Knob_MinValue_ 0x00 /* 最小檔位配置 */ /* 旋鈕名稱配置 */ enum Opto_name { optoname_AC = 0, optoname_WIND = 1, }; /* 旋鈕引數結構體配置 */ typedef struct { enum Opto_name name; uint16 OptoE1_Value; /* E1腳電平快取位元組 */ uint16 OptoE2_Value; /* E2腳電平快取位元組*/ uint16 OptoGroup_PreValue; /* 當前E1、E2腳電平組合快取位元組*/ uint16 OptoGroup_OldValue; /* 上一次E1、E2腳電平組合快取位元組*/ uint16 OptoShift_Value; /* 多次E1、E2腳電平組合快取位元組 */ sint8 Opto_Value; /* 旋鈕檔位位元組 */ uint8 Opto_Sync; /* 旋鈕同步位元組 */ }Opto_Struct;
.c文件主要設計相關函式
1、初始化旋鈕結構體函式void OptoKnob_ParaInit(void);
void OptoKnob_ParaInit(void) { enum Opto_name Opto_id; for(Opto_id = 0u; Opto_id < OptoKnobNumber; Opto_id++) { OptoKnob_Struct[Opto_id].name = Opto_id; OptoKnob_Struct[Opto_id].OptoE1_Value = 0x0000; OptoKnob_Struct[Opto_id].OptoE2_Value = 0x0000; OptoKnob_Struct[Opto_id].OptoGroup_PreValue = 0x0000; OptoKnob_Struct[Opto_id].OptoGroup_OldValue = 0x0000; OptoKnob_Struct[Opto_id].OptoShift_Value = 0x0000; OptoKnob_Struct[Opto_id].Opto_Value = 0x00; OptoKnob_Struct[Opto_id].Opto_Sync = 0x00; } }
2、所有旋鈕服務函式void OptoKnob_ServiceAll(void);
void OptoKnob_ServiceAll(void)
{
enum Opto_name Opto_id;
for(Opto_id = 0u; Opto_id < OptoKnobNumber; Opto_id++)
{
OptoKnob_Service(Opto_id);
}
}
3、單個旋鈕處理函式static void OptoKnob_Service(enum Opto_name name);
static void OptoKnob_Service(enum Opto_name name) { Opto_Struct* StructP = &OptoKnob_Struct[name]; StructP->OptoE1_Value <<= _01_SHIFT_BIT_; /* 產生最低位快取當前E1電平 */ StructP->OptoE2_Value <<= _01_SHIFT_BIT_; /* 產生最低位快取當前E2電平 */ OptoKnob_GetPort[StructP->name](StructP); /* 獲取電平值*/ /* 組合E1、E2電平 E1、E2的前後關係會影響旋鈕轉動的波形序列 這裡注意一下*/ StructP->OptoGroup_PreValue = ((StructP->OptoE1_Value&0x01)<<_01_GET_BIT_ ) | (StructP->OptoE2_Value&_01_GET_BIT_ ); /* 電平組合發生改變 */ if(StructP->OptoGroup_PreValue != StructP->OptoGroup_OldValue) { /* 上一次電平組合更新為當前的電平組合*/ StructP->OptoGroup_OldValue = StructP->OptoGroup_PreValue; /* 記錄電平組合序列 */ StructP->OptoShift_Value |= StructP->OptoGroup_PreValue; switch(StructP->OptoShift_Value & 0x03ff) /* 取10位資料 */ { case _034b_OptoKnob_CW_WAVE_: StructP->Opto_Value++; if(StructP->Opto_Value > _3f_Knob_MaxValue_ ) { StructP->Opto_Value = _00_Knob_MinValue_; } StructP->Opto_Sync = 1; break; case _0387_OptoKnob_CCW_WAVE_: StructP->Opto_Value--; if(StructP->Opto_Value < _00_Knob_MinValue_) { StructP->Opto_Value = _3f_Knob_MaxValue_; } StructP->Opto_Sync = 1; break; default: break; } /* 產生最低2位記錄下一次改變電平組合 */ StructP->OptoShift_Value <<= _02_SHIFT_BIT_; } }
4、電平獲取函式 static void OptoKnob_AC(Opto_Struct* Knob); static void OptoKnob_WIND(Opto_Struct* Knob);
/*這段程式碼看不懂就算了,我為了方便才這麼做,這程式碼就是多個旋鈕時的選擇函式,總之這些函式功能就是獲取2個埠的電平值,你自己寫個可以返回埠電平的函式就可以了*/
static void OptoKnob_AC(Opto_Struct* Knob);
static void OptoKnob_WIND(Opto_Struct* Knob);
typedef void (*OptoKnob_getport)(Opto_Struct*);
OptoKnob_getport OptoKnob_GetPort[]=
{
OptoKnob_AC,
OptoKnob_WIND,
};
static void OptoKnob_AC(Opto_Struct* StructP)
{
if(((P1&BIT7) >> 7) != 0x00)
{
StructP->OptoE1_Value |= 0x01;
}
else
{
StructP->OptoE1_Value &= ~0x01;
}
if(((P1&BIT6) >> 6) != 0x00)
{
StructP->OptoE2_Value |= 0x01;
}
else
{
StructP->OptoE2_Value &= ~0x01;
}
}
static void OptoKnob_WIND(Opto_Struct* StructP)
{
if(((P9&BIT6) >> 6) != 0x00)
{
StructP->OptoE1_Value |= 0x01;
}
else
{
StructP->OptoE1_Value &= ~0x01;
}
if(((P9&BIT4) >> 4) != 0x00)
{
StructP->OptoE2_Value |= 0x01;
}
else
{
StructP->OptoE2_Value &= ~0x01;
}
}