最近调STM8,用I2C在从机模式下与主机通讯,采用中断模式。但是复位之后老是运行几次就死掉,貌似程序在中断里出不来,然后I2C就挂了。Debug查看寄存器,发现状态寄存器的值跟库里面定义的任何一个EVENT都不符合,搞了两天了,不知道什么问题,头疼。。。 |
从零开始操作STM8寄存器(风驰iCreate奉献)
【中文资料】初学STM8库函数的中文帮助软件
绝对经典的中文STM8学习手册,淘宝上学习板资料,友情大放送!
【原创教程】风驰iCreate独家开源STM8 27个例程和10多万字的pdf教程
STM8的LCD1602 4线驱动,为什么不工作
【精华资料】由零开始开发STM8
STM8S 的触摸库是如何在主程序中查询键的呢、
【精华资料】STM8的C语言编程1-14讲完整版
【精品教程】STM8系列单片机入门教程系列
STM8 第一次进中断不准【悬赏问答】
RE:STM8S103F3P6 I2C Slave问题
void I2C_SlaveInit(void)
{
I2C_DeInit();
/*
* 将I2C配置为:
* 波特率 = 100K
* 从地址0x40
* 使能接收和发送
* 使能接收中断
*/
I2C_Init(100000, I2C_SLAVE_ADDRES, I2C_DUTYCYCLE_2, I2C_ACK_CURR, I2C_ADDMODE_7BIT, 16);
I2C_ITConfig((I2C_IT_TypeDef)(I2C_IT_ERR | I2C_IT_EVT | I2C_IT_BUF), ENABLE);
I2C_Cmd(ENABLE);
}
INTERRUPT_HANDLER(I2C_IRQHandler, 19)
{
/* In order to detect unexpected events during development,
it is recommended to set a breakpoint on the following instruction.
*/
/* Read SR2 register to get I2C error */
if ((I2C->SR2) != 0)
{
/* Clears SR2 register */
// i2c.Event=I2C->SR2;
I2C->SR2 = 0;
/* Set LED2 */
// STM_EVAL_LEDOn(LED2);
}
i2c.Event = I2C_GetLastEvent();
switch (i2c.Event)
{
/******* Slave transmitter ******/
/* check on EV1 */
case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:
I2C_SendData(i2c.Slave_Buffer_Tx[i2c.Tx_Idx]);
i2c.Tx_Idx++;
break;
/* check on EV3 */
case I2C_EVENT_SLAVE_BYTE_TRANSMITTING:
break;
/******* Slave receiver **********/
/* check on EV1*/
case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:
i2c.Rx_Add_MATCHED=1;
break;
/* Check on EV2*/
case I2C_EVENT_SLAVE_BYTE_RECEIVED:
if(i2c.Rx_Add_MATCHED==1)
{
i2c.Rx_Add_MATCHED=0;
i2c.Tx_Idx=I2C_ReceiveData(); //确定修改或者读寄存器地址
}
else
{
i2c.Slave_Buffer_Tx[i2c.Tx_Idx] = I2C_ReceiveData();
i2c.Tx_Idx++;
}
break;
/* Check on EV4 */
case (I2C_EVENT_SLAVE_STOP_DETECTED):
/* write to CR2 to clear STOPF flag */
I2C->CR2 |= I2C_CR2_ACK;
break;
default:
break;
}
}
/**********************************************************/
发现进入中断卡死;从示波器看到 主机给103从机发送数据后没有ACK应答返回导致通信停止。。。。。。。。。
新东西出现
/**********************************************************/
INTERRUPT_HANDLER(I2C_IRQHandler, 19)
{
static u8 sr1;
static u8 sr2;
static u8 sr3;
// save the I2C registers configuration
sr1 = I2C->SR1;
sr2 = I2C->SR2;
sr3 = I2C->SR3;
/* Communication error? */
if (sr2 & (I2C_SR2_WUFH | I2C_SR2_OVR |I2C_SR2_ARLO |I2C_SR2_BERR))
{
I2C->CR2|= I2C_CR2_STOP; // stop communication - release the lines
I2C->SR2= 0; // clear all error flags
}
/* More bytes received ? */
if ((sr1 & (I2C_SR1_RXNE | I2C_SR1_BTF)) == (I2C_SR1_RXNE | I2C_SR1_BTF))
{
I2C_byte_received(I2C->DR);
}
/* Byte received ? */
if (sr1 & I2C_SR1_RXNE)
{
I2C_byte_received(I2C->DR);
}
/* NAK? (=end of slave transmit comm) */
if (sr2 & I2C_SR2_AF)
{
I2C->SR2 &= ~I2C_SR2_AF; // clear AF
I2C_transaction_end();
}
/* Stop bit from Master (= end of slave receive comm) */
if (sr1 & I2C_SR1_STOPF)
{
I2C->CR2 |= I2C_CR2_ACK; // CR2 write to clear STOPF
I2C_transaction_end();
}
/* Slave address matched (= Start Comm) */
if (sr1 & I2C_SR1_ADDR)
{
I2C_transaction_begin();
}
/* More bytes to transmit ? */
if ((sr1 & (I2C_SR1_TXE | I2C_SR1_BTF)) == (I2C_SR1_TXE | I2C_SR1_BTF))
{
I2C->DR = I2C_byte_write();
}
/* Byte to transmit ? */
if (sr1 & I2C_SR1_TXE)
{
I2C->DR = I2C_byte_write();
}
//GPIOD->ODR^=1;
}
/*********************************/
在初始化不变情况从官网再找到这代码测试可以返回应答;
{
MessageBegin = TRUE;
}
void I2C_transaction_end(void)
{
//Not used in this example
}
void I2C_byte_received(u8 u8_RxData)
{
if (MessageBegin == TRUE && u8_RxData < MAX_BUFFER) {
u8_MyBuffp= &u8_My_Buffer[u8_RxData];
MessageBegin = FALSE;
}
else if(u8_MyBuffp < &u8_My_Buffer[MAX_BUFFER])
*(u8_MyBuffp++) = u8_RxData;
}
u8 I2C_byte_write(void)
{
if (u8_MyBuffp < &u8_My_Buffer[MAX_BUFFER])
return *(u8_MyBuffp++);
else
return 0x00;
}