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

📄 smb_test1.c

📁 有价值的电子书
💻 C
📖 第 1 页 / 共 2 页
字号:
			SI = 0; 				// 释放总线
			DATA_READY = 0; 		// 等待有效数据。
			while (!DATA_READY); 	//
			DAC0L = 0; 				// DAC 低字节
			DAC0H = WORD; 			// DAC 高字节
			VALID_OP = 0; 			// 等待新的OP_CODE
			SI = 0; 				// 结束时释放总线
			break;
			// OP_CODE = WRITE_BUF – 等待有效数据字节,并将其存入DATA_BUF 数组。
			// 根据OP_CODE 的高4 位确定数组下标。
			case WRITE_BUF:
			SI = 0; 				// 释放总线
			index = (OP_CODE & 0xF0); 	// 用高4 位作为数组下标
			DATA_READY = 0; 		// 等待有效数据。
			while (!DATA_READY); 	//
			DATA_BUF[index] = WORD; // 将数据存入数组
			VALID_OP = 0; 			// 等待新的OP_CODE
			SI = 0; 				// 结束时释放总线
			break;
			// OP_CODE = READ_BUF – 读DATA_BUF 数组并将字节存入输出缓冲区。
			// 数组下标由OP_CODE 的高4 位决定。
			case READ_BUF:
			index = (OP_CODE & 0xF0); 	// 用高4 位作为数组下标
			WORD = DATA_BUF[index]; 	// 将索引字节存入输出缓冲区
			VALID_OP = 0; 				// 等待新的OP_CODE
			SI = 0; 					// 结束时释放总线
			break;
			}
	if (LOST){ 					// 如果LOST 被置位,说明器件在最近
		COMMAND = LOST_COMMAND; // 的竞争中失败。将保存值回装到
		WORD = LOST_WORD; 		// 传输变量并重试传输过程。
		OP_CODE = LOST_CODE;
		LOST = 0;
		STA = 1;
		}
	}
}
//--------------------------------------------------------------------
// SMBus 中断服务程序
//--------------------------------------------------------------------
void SMBUS_ISR (void) interrupt 7
{
switch (SMB0STA){ 			// SMBus 的状态码(SMB0STA 寄存器)
// 主发送器/接收器:起始条件已发出。
// 将从器件地址装入SMB0DAT。屏蔽R/W 位,因为所有传输过程都从
// 写OP_CODE 开始。
	case SMB_START:
	SMB0DAT = (COMMAND & 0xFE); // 装入待访问的从器件地址
	// 屏蔽R/W 位,因为第一次传输
	// 总是写OP_CODE。
	STA = 0; 				// 手动清除STA 位
	SI = 0; 				// 清除中断标志
	break;
	// 主发送器/接收器:重复起始条件已发出。
	// 该状态只出现在读操作,在发出OP_CODE 之后。将器件地址+ READ 装入SMB0DAT。
	case SMB_RP_START:
	SMB0DAT = COMMAND;
	STA = 0; 				// 手动清除STA 位
	SI = 0;
	break;
	// 主发送器:从地址+ WRITE 已发出。收到ACK。
	// 将OP_CODE 装入到SMB0DAT。
	case SMB_MTADDACK:
	SMB0DAT = OP_CODE;
	SI = 0; 				// 清除中断标志
	break;
	// 主发送器:从地址+ WRITE 已发出。收到NACK。
	// 从器件不响应。用ACK 查询重试。
	case SMB_MTADDNACK:
	STO = 1;
	STA = 1;
	SI = 0; 				// 清除中断标志
	break;
	// 主发送器:数据字节已发出。收到ACK。
	// 检查OP_CODE – 如果是读操作码,发出重复起始条件开始读。如果是写操作码,
	// 将WORD 装入SMB0DAT 以待传输。如果不是有效操作码,则有两种情况:
	// 1) 数据已发送,传输过程结束,或2) 这是一个错误。
	// 在任何一种情况,发出停止条件结束传输。
	case SMB_MTDBACK:
	switch (OP_CODE & 0x0F){ // 只检查低4 位
		// OP_CODE 为READ。发出重复起始条件。
		case READ_BUF:
		case READ_ADC:
		OP_CODE = 0; 		// 当前OP_CODE 不再有用
		STA = 1;
		break;
		// OP_CODE 为WRITE。将输出数据装入SMB0DAT。
		case WRITE_BUF:
		case WRITE_DAC:
		SMB0DAT = WORD;
		OP_CODE = 0; 		// 清除OP_CODE,使传输过程在下一次
		break; 				// 出现该状态时结束(在发出数据之后)。
		default: 			// 无有效OP_CODE。结束传输
		STO = 1;
		SM_BUSY = 0;
		break;
		}
	SI = 0;
	break;
	// 主发送器:数据字节已发出。收到NACK。
	// 用ACK 查询并重试传输。
	case SMB_MTDBNACK:
	STO = 1;
	STA = 1;
	SI = 0; 				// 清除中断标志
	break;
	// 主发送器:竞争失败。
	case SMB_MTARBLOST:
	LOST_COMMAND = COMMAND; //
	LOST_WORD = WORD; 		// 保存变量,以备总线空闲时使用
	LOST_CODE = OP_CODE; 	//
	LOST = 1; 				// 设置总线空闲时的重试标志
	SI = 0; 				// 清除中断标志
	break;
	// 主接收器:从地址+ READ 已发出。收到ACK。
	// 设置为在下一次传输后发送NACK,因为这将是最后(唯一)字节。
	case SMB_MRADDACK:
	AA = 0; 				// 在应答周期发送NACK
	SI = 0;
	break;
	// 主接收器:从地址+ READ 已发出。收到NACK。
	// 从器件不响应。重新发送重复起始条件。
	case SMB_MRADDNACK:
	STA = 1;
	SI = 0;
	break;
	// 主接收器:收到数据字节。ACK 已发出。
	// 该状态不应出现,因为AA 已在前一状态被清除。
	// 如果出现,发送停止条件。
	case SMB_MRDBACK:
	STO = 1;
	SM_BUSY = 0;
	SI = 0;
	break;
	// 主接收器:收到数据字节。NACK 已发出。
	// 读操作完成。读数据寄存器并发送停止条件。
	case SMB_MRDBNACK:
	WORD = SMB0DAT;
	STO = 1;
	SM_BUSY = 0;
	AA = 1; 					// 为下一次传输设置AA
	SI = 0;
	break;
	// 从接收器:竞争失败,收到通用呼叫地址。
	// 置位LOST 标志以备总线空闲时重试。本次传输失败。
	case SMB_SRGARBLOST:
	// 从接收器:竞争失败,收到自己的从地址+ WRITE。
	// 置位LOST 标志以备总线空闲时重试。
	// 置位STO 位以退出主方式
	case SMB_SROARBLOST:
	LOST_COMMAND = COMMAND; 	//
	LOST_WORD = WORD; 			// 保存变量,以备总线空闲时使用
	LOST_CODE = OP_CODE; 		//
	LOST = 1; 					// 总线空闲时重试。
	SI = 0;
	break;
	// 从接收器:收到自己的从地址+ WRITE。ACK 已发出。本次传输失败。
	case SMB_SROADACK:
	// 从接收器:收到通用呼叫地址。ACK 已发出。
	case SMB_SRGADACK:
	SI = 0;
	break;
	// 从接收器:在收到通用呼叫地址+ WRITE 之后收到数据字节。
	// ACK 已发出。本次传输失败。
	case SMB_SRGDBACK:
	// 从接收器:在收到自己的从地址+ WRITE 之后收到数据字节。ACK 已发出。
	// 根据所收到的OP_CODE 或数据进行相应操作。
	case SMB_SRODBACK:
	if (!VALID_OP){ 			// 如果VALID_OP=0,该字节为OP_CODE。
		OP_CODE = SMB0DAT; 		// 保存OP_CODE
		VALID_OP = 1; 			// 下一字节不是OP_CODE
	}
	else{
		DATA_READY = 1; 		// 收到有效数据。
		WORD = SMB0DAT; 		// 在OP_CODE 处理程序中处理
		SI = 0;}
	break;
	// 从接收器:被作为从器件访问时收到数据字节。NACK 已发出。
	// 该状态不应出现,因为作为从器件AA 不会被清除。本次失败,进入下一状态。
	case SMB_SRODBNACK:
	// 从接收器:被作为通用呼叫地址访问时收到数据字节。NACK 已发出。
	// 该状态不应出现,因为作为从器件AA 不会被清除。
	case SMB_SRGDBNACK:
	AA = 1;
	SI = 0;
	break;
	// 从接收器:被作为从器件访问时收到停止条件或重复起始条件。
	case SMB_SRSTOP:
	SI = 0;
	break;
	// 从发送器:收到自己的从地址+ READ。ACK 已发出。
	// 将待输出数据装入到SMB0DAT。
	case SMB_STOADACK:
	SMB0DAT = WORD;
	SI = 0;
	break;
	// 从发送器:作为主器件竞争失败。收到自己的从地址+ READ。ACK 已发出。
	case SMB_STOARBLOST:
	LOST_COMMAND = COMMAND; 		//
	LOST_WORD = WORD; 				// 保存变量,以备总线空闲时使用
	LOST_CODE = OP_CODE; 			//
	LOST = 1; 						// 总线空闲时重试
	SI = 0;
	break;
	// 从发送器:收到数据字节。收到ACK。失败。
	case SMB_STDBACK:
	// 从发送器:收到数据字节。收到NACK。失败。
	case SMB_STDBNACK:
	// 从发送器:最后数据字节已发送。收到ACK。无需任何操作。
	case SMB_STDBLAST:
	SI = 0;
	break;
	// 所有其它状态码无效。通信复位。
	default:
	STO = 1;
	SM_BUSY = 0;
	break;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -