?? hdq.c
字號:
#include <msp430x14x.h>
#include "HDQ.h"
// 定義工作的狀態
enum
{
imWrite,
imWriteE,
imRead,
imReadE,
imDelay
};
// 定義全局變量
// 中斷服務程序的模式
static unsigned char ISRMode;
// 接收到的數據
static unsigned char Xfer;
// 發送數據的位數
static unsigned char BitCnt;
// 記錄時間戳
static unsigned int Ticks;
// Break及恢復
static void HDQBreak(void)
{
// 設置Break的時間
TACCR0 = TAR + tBreak * 2;
// 復位OUT0,使能中斷
TACCTL0 = OUTMOD_0 + CCIE;
// 設置中斷服務為延時模式
ISRMode = imDelay;
// 進入低功耗模式
_BIS_SR(LPM0_bits);
// 設置Break的恢復時間
TACCR0 += tBR;
// 設置OUT0,使能中斷
TACCTL0 = OUTMOD_0 + OUT + CCIE;
// 進入低功耗模式
_BIS_SR(LPM0_bits);
}
// HDQ總線的寫操作
static void HDQBasicWrite(unsigned char Data)
{
Xfer = Data;
// 復位OUT0
TACCTL0 = OUTMOD_0;
TACCR0 = TAR;
// 位開始的時間戳
Ticks = TACCR0;
// 設置低電平的時間
if (Xfer & 0x01)
// “1”
TACCR0 += tHW1;
else
// “0”
TACCR0 += tHW0;
// Toggle OUT0,中斷使能
TACCTL0 = OUTMOD_4 + CCIE;
// 設置傳輸的位數為8
BitCnt = 8;
// 中斷服務為寫模式
ISRMode = imWrite;
// 進入低功耗模式
_BIS_SR(LPM0_bits);
}
void HDQSetup(void)
{
// P1.1為輸出
P1DIR |= BIT1;
// 選擇TA0功能
P1SEL |= 0x02;
}
// HDQ的寫操作
void HDQWrite(unsigned char Addr, unsigned char Data)
{
// 選擇SMCLK為時鐘源,連續模式
TACTL = TASSEL_2 + MC_2;
// P1.1為輸出
P1DIR |= 0x02;
// 總線Break
HDQBreak();
// 發送地址,確保R/W比特為0
HDQBasicWrite(Addr | 0x80);
// 延時
// 設置時間
TACCR0 += tCYCH;
// 設置OUT0,中斷使能
TACCTL0 = OUTMOD_0 + OUT + CCIE;
// 設置中斷服務為延時模式
ISRMode = imDelay;
// 進入低功耗
_BIS_SR(LPM0_bits);
// 寫入數據
HDQBasicWrite(Data);
// P1.1為輸入
P1DIR &= ~0x02;
// 停止Timer_A
TACTL = 0;
}
// HDQ的讀操作
unsigned int HDQRead(unsigned char Addr)
{
// 選擇SMCLK為時鐘源,連續模式
TACTL = TASSEL_2 + MC_2;
// P1.1為輸出
P1DIR |= 0x02;
// 總線Break
HDQBreak();
// 發送地址
HDQBasicWrite(Addr);
// P1.1為輸入
P1DIR &= ~0x02;
// 設置數據為8位
BitCnt = 8;
// 設置中斷服務為讀模式
ISRMode = imRead;
// 在P1.1管腳捕獲下降沿
TACCTL0 = CM_2 + CCIS_0 + SCCI + CAP + CCIE;
// 設置超時時間
TACCR1 = TAR + tTO;
// 使能中斷
TACCTL1 = CCIE;
// 進入低功耗
_BIS_SR(LPM0_bits);
// 停止Timer_A
TACTL = 0;
// 判斷數據是否有效
if (BitCnt)
return 0xffff;
else
return Xfer;
}
void Init_CLK(void)
{
unsigned int i;
//將寄存器的內容清零
//XT2震蕩器開啟
//LFTX1工作在低頻模式
//ACLK的分頻因子為1
BCSCTL1 = 0X00;
do
{
// 清除OSCFault標志
IFG1 &= ~OFIFG;
for (i = 0x20; i > 0; i--);
}
while ((IFG1 & OFIFG) == OFIFG);
BCSCTL2 = 0X00;
//MCLK的時鐘源為TX2CLK,分頻因子為4
BCSCTL2 += SELM1 + DIVM_2;
//SMCLK的時鐘源為TX2CLK,分頻因子為4
BCSCTL2 += SELS + DIVS_2;
}
interrupt [TIMERA0_VECTOR] void Timer_A0_ISR(void)
{
switch (ISRMode)
{
case imWrite :
if (--BitCnt)
{
// 設置時間
TACCR0 = Ticks + tCYCH;
ISRMode = imWriteE;
}
else
{
// 設置OUT0,禁止中斷
TACCTL0 = OUTMOD_0 + OUT;
// 返回激活狀態
_BIC_SR(LPM0_bits);
}
break;
case imWriteE :
// 位開始時間戳
Ticks = TACCR0;
if ((Xfer >>= 1) & 0x01)
// “1”
TACCR0 += tHW1;
else
// “0”
TACCR0 += tHW0;
ISRMode = imWrite;
break;
case imRead :
// 停止超時
TACCTL1 = 0;
// 在位的中央采樣
TACCR0 += (tDW0 + tDW1) / 2;
// 捕獲模式
TACCTL0 &= ~CAP;
ISRMode = imReadE;
break;
case imReadE :
Xfer >>= 1;
// 檢查Timer_A的鎖存
if (TACCTL0 & SCCI)
Xfer |= 0x80;
if (--BitCnt)
{
// 捕獲模式
TACCTL0 |= CAP;
// 設置超時
TACCR1 = TAR + tTO;
// 使能中斷
TACCTL1 = CCIE;
// 讀模式
ISRMode = imRead;
}
else
{
// 設置OUT0,禁止中斷
TACCTL0 = OUTMOD_0 + OUT;
// 返回激活狀態
_BIC_SR(LPM0_bits);
}
break;
case imDelay :
// 禁止中斷
TACCTL0 &= ~CCIFG;
// 返回激活狀態
_BIC_SR(LPM0_bits);
break;
}
}
interrupt [TIMERA1_VECTOR] void Timer_A1_ISR(void)
{
if (TAIV == 0x02)
{
TACCTL0 = 0;
TACCTL1 = 0;
// 返回激活狀態
_BIC_SR(LPM0_bits);
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -