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

📄 复件 (2) smbus.c

📁 c8051f020实现4个 产UART 口
💻 C
字号:

#include "all.h"

void smbus(void) interrupt 7 using 2     //SMBUS中断服务程序
{
	

    watch=SMB0STA;

	smbus_ms_cnt = 0;//无中断豪秒计数器,在SMBUS中断清0
	switch (watch)                    
                               			//SMBUS状态寄存器SMB0STA
    {                    
                                        
        case 0x08:                    	//主发送/接收:起始条件已发出.
			STA = 0;				//人工清除起始位STA
			iic_error_flag = 0;	//iic_error_flag=1说明SMBus有问题
			AA = 1;                
			iic_data_count = 0;
			SMB0DAT = slave_add;	//从地址+读/写标志送SMB0DAT,
			break;        
        
        case 0x10:                    		//主发送/接收:重复起始条件已发出。
			STA = 0;					//人工清除起始位STA
			AA = 1;            
			    
			SMB0DAT = slave_add;		//从地址+读/写标志送SMB0DAT

			iic_data_len = iic_data_len+iic_data_count;
			iic_buf_p = iic_buf_p - iic_data_count;
			iic_data_count = 0;
			break;

        case 0x18:                                	//主发送器:从地址+写标志已发出,收到ACK
              	if((slave_add&0xfe) == 0xa0)	//如果是存储器操作
			{
				//发送MEMORY地址高字节
				SMB0DAT = iic_ram_add;    // iic_ram_add>>8;
			}
			else
			{
				SMB0DAT = iic_ram_add;
			}

			iic_add_count = 1;
			write_start_num = 0;
    			break;        
    
        case 0x20: 									//主发送器:从地址+写标志已发出,收到NACK
			write_start_num++;
       		
			if(write_start_num>5)			//如果超过5次不成功则释放总线
	   		{
				STO = 1;
				sm_busy = 0;
				iic_error_flag = 1;
			}  
       		else							//确认查询重复,置位STO+STA。
			{
				STO = 1;
				STA = 1;
			}                

       		break;

        case 0x28:              //数据字节已发出,收到ACK,将下一字节装入SMB0DAT;
								//判断,如果是存储器操作,则判断是否发送完2个字节地址
			if((slave_add&0xfe) == 0xa0)
			{
				//发送MEMORY地址低字节
				//SMB0DAT = iic_ram_add;
				//iic_add_count = 0;
			//}
			//else
			//{
		    		switch(iic_data_len)
		    		{
					case 0x00:					//如果数据已经发送结束则释放总线    
						STO=1;
						sm_busy=0;                                        
						break;    

					default  :
						SMB0DAT = *iic_buf_p;
						iic_buf_p++;
						iic_data_count++;
						iic_data_len--;    
		         			break;
		    		}
			}

    	    	break;

        case 0x30:                      //主发送器:数据字节已发出,收到NACK,
             	write_start_num++;
             	if(write_start_num>5)	//如果超过5次不成功则释放总线 
	 	{
			STO=1;
			sm_busy=0;
			iic_error_flag=1;
		}
		else	 				//重试传输或置位STO
	 	{
			STO=1;
			STA=1;
		}
             	break;

        case 0x38:                               //主发送器:竞争失败,保存当前数据
		write_start_num++;

		if(write_start_num>5) 				//如果超过5次不成功则释放总线 
		{
			STO=1;
			sm_busy=0;
			iic_error_flag=1;
		}  
		else
		{
			STO=1;
			STA=1;
		}

		break;

        case 0x40:    
		read_start_num=0;                   //主接收器:从地址+读标志已发出,收到ACK,
		if(iic_data_len<2)					//如果只接收一个字节,清AA位(收到字节后发NACK),等待接收数据
		{
			AA=0;
		}          
		break;

        case 0x48:                               //主接收器:从地址+读标志已发出,收到NACK,
		read_start_num++;
		if(read_start_num>5)					//如果超过5次不成功则释放总线
		{
			STO=1;
			sm_busy=0;
			iic_error_flag=1;
		}
		else									//确认查询重复,置位STO+STA。
		{
			STO=1;
			STA=1;
		}
		break; 
			                               
        case 0x50:                                //主接收器:数据字节收到,ACK已发出;读SMB0DAT,等待
		//iic_data_buf[iic_data_count++]=SMB0DAT;
		*iic_buf_p = SMB0DAT;
		iic_buf_p++;
		iic_data_count++;
		iic_data_len--;

             if(iic_data_len<2)
		{
		 	AA=0;             //下一个字节,如下一个字节是最后字节,清除AA。
		}
		break;

        case 0x58:                                  //主接收器:数据字节收到,NACK已发出,置位STO。
             //iic_data_buf[iic_data_count++]=SMB0DAT; //读操作已经完成,读数据寄存器并且发出STOP.
		*iic_buf_p = SMB0DAT;
		iic_buf_p++;
		iic_data_count++;
		iic_data_len--;
		STO=1;sm_busy=0;                        //Free SMBus    
		break;

        default:									//Reset communication.
		STO=1;
		sm_busy=0;
		iic_error_flag=1;                   
		break;
    }

	SI=0;                                             //clear interrupt flag

	

}


⌨️ 快捷键说明

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