⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hdq.c

📁 430单片机的一些列子程序
💻 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 + -