你的浏览器版本过低,可能导致网站不能正常访问!为了你能正常使用网站功能,请使用这些浏览器。
STM8自学笔记(推荐STM8很好的入门电子书)
基于STM8的DALI (数字可寻址调光协议)
分享STM8 风驰光盘的资料,是完整的(包括原理图+例程+PDF注释)
《无刷直流电机控制应用 基于STM8S系列单片机》
STM8S库函数中文参考 小软件
【资料分享】STM8L的智能手持血糖监测设备的源码
基于STM8S207工程模板
【培训资料】STM8系列PPT培训资料
STM8S 直流电机例程及相关资料
无刷直流电机控制应用+基于STM8S系列单片机---电子书
/*==========================================================================================================
函数功能: 本函数是I2C总线通信接收和发送作业不间断循环调用运行函数。
备注: ▲.注意:本函数为消息任务队列函数,要在主函数中不间断循环调用运行。
▲.当I2C总线工作于从机方式时,I2C总线中断总是处于使能状态,以便
I2C总线处于随时接收数据状态。
==========================================================================================================*/
void CommI2cCircleFunc (void)
{
#ifdef DEBUG
unsigned char i; // 循环计数器变量
unsigned char j;
unsigned char hex_data[2];
unsigned char *ptr;
#endif
unsigned char i; // 循环计数器变量
CommI2cDataStru *pI2c; // 指向I2C总线通讯收发数据处理变量的指针
pI2c = &gstvI2c; // 取I2C总线通讯收发数据处理变量的首个地址
#ifdef PreCommI2cUseSingleMasterMode // “I2C总线工作于单主机方式”的条件编译
if ( (gbitI2c.Error == SET) // 如果I2C总线通讯收发作业发生错误,
&& ( ! CommI2cBusBusy( )) ) // 且I2C总线收发器处于空闲状态?
{
if (pI2c->Cycle > cI2cErrorMax) // 检查重新启动收发作业错误次数是否大于最大值?
{
pI2c->Cycle = 0x00; // I2C总线的重新启动收发作业发生错误次数清0
gbitI2c.Error = CLEAR; // 清除“通讯收发作业发生错误”标志
gbitI2c.Busy = CLEAR; // 清除“I2C总线〖忙〗”标志
#ifdef _SYSTEM_ERROR_MANAGE_H_
sys_error_type |= SYS_ERROR_TYPE_IS_GENERAL; // 置【普通】错误类型消息任务标志位
sys_error_value = SYS_ERROR_COMM_I2CBUS ; // 置“I2C总线通信收发作业”错误代码值
#endif
}
else
{
pI2c->Cycle++; // I2C的重新启动收发作业发生错误次数值+1
gbitI2c.Error = CLEAR; // 清除“通讯收发作业发生错误”标志
CommI2cBusAgain( ); // 重新启动I2C总线前一个通讯收发作业操作
}
}
// 通讯任务时间超时计时处理,用以处理I2C总线直处于“BUSY”状态。
if (gbitI2c.OverS == SET)
{
if (RtcSecByteOverflow(pI2c->OverS)) // 如果通讯任务时间计时秒表时间已溢出?
{
I2CCR2 = (u8)( ((0<<i2cSTART)| // 禁止 START 信号(起始条件)
(0<<i2cSTOP )|(0<<i2cACKEN)| // 禁止 STOP 信号(停止条件),使能 ACK 应答
(0<<i2cPOS )|(1<<i2cRST ) ));// 应答的位置=当前字节,复位I2C模块
CLKPECR1 &= (u8)(~((1<<clkI2C ))); // 禁止I2C外设时钟
I2CCR1 = (u8)( ((0<<i2cEN )|(0<<i2cGCEN )| // 禁止I2C模块,禁止广播呼叫
(0<<i2cCKTEN) )); // 禁止时钟延展
MFH_PIN_CFG_OUTH_I2cScl; // 设置I2C时钟引脚为推挽输出,并为H电平(释放 SCL)
MFH_PIN_CFG_OUTH_I2cSda; // 设置I2C数据引脚为推挽输出,并为H电平(释放 SDA)
for (i=0; i<9; i++) // 发送 9 个 SCL 时钟脉冲;在此过程中,SDA 为高电平,以复位从设备
{
DelayUs(1);
MFH_PIN_OUT_CLRL_I2cScl;
DelayUs(1);
MFH_PIN_OUT_SETH_I2cScl;
}
CLKPECR1 |= (u8)( ((1<<clkI2C ))); // 使能I2C外设时钟
CommI2cInit( ); // 重新初始化I2C总线
}
}
#endif // “PreCommI2cUseSingleMasterMode”
}
#ifdef __cplusplus
} // extern "C" 链接指示符作用域结束
#endif
/*
************************************************************************************************************
本C语言源程序文件到此结束
************************************************************************************************************
*/
两线串行总线接口(I2C)
------------------------------------------------------------------------------------------------*/
// I2CCR1(I2C_CR1)——— I2C控制寄存器1
#define i2cEN 0 // I2C启动/停止使能位
#define i2cGCEN 6 // 广播呼叫使能位
#define i2cCKTEN 7 // 时钟延展禁止位
// I2CCR2(I2C_CR2)——— I2C控制寄存器2
#define i2cSTART 0 // 起始位状态
#define i2cSTOP 1 // 结束位状态
#define i2cACKEN 2 // 应答使能位
#define i2cPOS 3 // 应答的位置
#define i2cRST 7 // 软件复位
// I2CARL(I2C_OARL)——— I2C(从机)地址低位寄存器
#define i2cADD0 0 // I2C从机地址位0
#define i2cADD1 1 // I2C从机地址位1
#define i2cADD2 2 // I2C从机地址位2
#define i2cADD3 3 // I2C从机地址位3
#define i2cADD4 4 // I2C从机地址位4
#define i2cADD5 5 // I2C从机地址位5
#define i2cADD6 6 // I2C从机地址位6
#define i2cADD7 7 // I2C从机地址位7
#define i2cADD17 1 // I2C从机地址位1~7
// I2CARH(I2C_OARH)——— I2C(从机)地址高位寄存器
#define i2cADD8 1 // I2C从机地址位8
#define i2cADD9 2 // I2C从机地址位9
#define i2cCFG 6 // 地址模式配置
#define i2cMODE 7 // 寻址模式
#define i2cADD89 1 // I2C从机地址位8~9
// I2CSR1(I2C_SR1)——— I2C状态寄存器1
#define i2cSTAF 0 // 起始位(主模式)
#define i2cADDTR 1 // 地址已被发送(主模式)/地址匹配(从模式)
#define i2cTXC 2 // 字节发送结束
#define i2cADD10 3 // 10位头序列已发送(主模式)
#define i2cSTODF 4 // 停止条件检测位(从模式)
#define i2cRXNE 6 // 接收数据寄存器非空
#define i2cDRE 7 // 发送数据寄存器空
// I2CSR2(I2C_SR2)——— I2C状态寄存器2
#define i2cBERR 0 // 总线错误
#define i2cARLO 1 // 仲裁失败(主模式)
#define i2cACKF 2 // 应答失败
#define i2cOVF 3 // 溢出标志位
#define i2cWUF 5 // 从停机(Halt)模式唤醒标志
// I2CSR3(I2C_SR3)——— I2C状态寄存器3
#define i2cMSF 0 // 主/从机模式标志位
#define i2cBSY 1 // 总线忙标志
#define i2cRXTX 2 // 接收器/发送器,0:接收,1:发送
#define i2cGCF 4 // 广播呼叫头序列(从模式)
// I2CICR(I2C_ITR)——— I2C中断控制寄存器
#define i2cERRIE 0 // 错误中断使能位
#define i2cEVTIE 1 // 事件中断使能位
#define i2cBUFIE 2 // 缓冲中断使能位
// I2CCCRL(I2C_CCRL)——— I2C时钟控制低位寄存器
#define i2cCS0 0 // 预分频器时钟选择位0
#define i2cCS1 1 // 预分频器时钟选择位1
#define i2cCS2 2 // 预分频器时钟选择位2
#define i2cCS3 3 // 预分频器时钟选择位3
#define i2cCS4 4 // 预分频器时钟选择位4
#define i2cCS5 5 // 预分频器时钟选择位5
#define i2cCS6 6 // 预分频器时钟选择位6
#define i2cCS7 7 // 预分频器时钟选择位7
// I2CCCRH (I2C_CCRH)——— I2C时钟控制高位寄存器
#define i2cCS8 0 // 预分频器选择控制位8
#define i2cCS9 1 // 预分频器选择控制位9
#define i2cCSA 2 // 预分频器选择控制位10
#define i2cCSB 3 // 预分频器选择控制位11
#define i2cDUTY 6 // 快速模式下的占空比
#define i2cSFM 7 // 标准/快速模式选择位
__IO_REG8_BIT(I2CCR2 , 0x5211, __READ_WRITE, __BITS_I2C_CR2 );// I2C控制寄存器2
__IO_REG8_BIT(I2CFR , 0x5212, __READ_WRITE, __BITS_I2C_FREQR );// I2C频率寄存器
__IO_REG8_BIT(I2CARL , 0x5213, __READ_WRITE, __BITS_I2C_OARL );// I2C(从机)地址低位寄存器
__IO_REG8_BIT(I2CARH , 0x5214, __READ_WRITE, __BITS_I2C_OARH );// I2C(从机)地址高位寄存器
__IO_REG8 (I2CDR , 0x5216, __READ_WRITE );// I2C数据寄存器
__IO_REG8_BIT(I2CSR1 , 0x5217, __READ, __BITS_I2C_SR1 );// I2C状态寄存器1
__IO_REG8_BIT(I2CSR2 , 0x5218, __READ_WRITE, __BITS_I2C_SR2 );// I2C状态寄存器2
__IO_REG8_BIT(I2CSR3 , 0x5219, __READ, __BITS_I2C_SR3 );// I2C状态寄存器3
__IO_REG8_BIT(I2CICR , 0x521A, __READ_WRITE, __BITS_I2C_ITR );// I2C中断控制寄存器
__IO_REG8 (I2CCCRL , 0x521B, __READ_WRITE );// I2C比特率低位寄存器
__IO_REG8_BIT(I2CCCRH , 0x521C, __READ_WRITE, __BITS_I2C_CCRH );// I2C比特率高位寄存器
__IO_REG8_BIT(I2CTRISER , 0x521D, __READ_WRITE, __BITS_I2C_TRISER );// I2CTRISE寄存器
__IO_REG8 (I2CPECR , 0x521E, __READ_WRITE );// I2C包错误检查寄存器
case cI2cMrxAddrAck: // SLA+R 已发送,接收到 ACK
{
MFHI2cBusRdataAck( ); // 在接收之后发出 ACK 脉冲
MFHI2cIntEventOnn( ); // 使能缓冲中断
break;
}
改为:
case cI2cMrxAddrAck: // SLA+R 已发送,接收到 ACK
{
if (pI2c->RxSize <= 1) // 如果只接收1个字节?
{
MFHI2cBusRdatNack( ); // 在接收之后发出 NOT ACK
MFHI2cBusNackStop( ); // 发出 STOP 信号(结束条件),没有 ACK 脉冲
}
else
{
MFHI2cBusRdataAck( ); // 在接收之后发出 ACK 脉冲
}
MFHI2cIntEventOnn( ); // 使能缓冲中断
break;
}
以避免只接收1个字节时,发生溢出错误。