📄 复件 (2) smbus.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 + -