cancel
Showing results for 
Search instead for 
Did you mean: 

STM8 I2C Busy Bit is always 1

christoph23
Associate II
Posted on April 28, 2015 at 11:00

Hello,

I work with the

STM8S105K6

and

have tried

several

examples

of

ST

here

.

SDA

and SCL

have a

4.7K

pull-up

.

The line is

currently connected

only

with a

oscilloscope

.

Manually

I can let

toggling

the

corresponding pins

but

with

I2C

pins

remain

at 3.3V

.

After a long

debugging

I noticed

then that

the

Busy

bit is

always set

consistently

in all examples

.

Since I can not

find the problem

I

would appreciate

help

much.

Here's an

example of my

mind, I

should be able to

see

the broadcast

address on the

oscilloscope

.

Here a lidle Example

int main(void){

 I2C_Init();

 while(1){

 I2C_7BitAdresse();

 }

}

 void I2C_Init(){

 CLK->CKDIVR = 0x01;

 I2C->CR2 |=1 <<7;

 I2C->CR2 ^=1 <<7;        //Reset periphial clock

 GPIOB->ODR |= 0x30;             //define SDA, SCL outputs, HiZ, Open drain, Fast

  GPIOB->DDR |= 0x30;       //Bits 4 und 5 als Output,20MHz

  GPIOB->CR2 |= 0x30;

 #ifdef FAST_I2C_MODE

  I2C->FREQR = 16;               // input clock to I2C - 16MHz

  I2C->CCRL = 15;                // 900/62.5= 15, (SCLhi must be at least 600+300=900ns!)

  I2C->CCRH = 0x80;              // fast mode, duty 2/1 (bus speed 62.5*3*15~356kHz)

  I2C->TRISER = 5;               // 300/62.5 + 1= 5  (maximum 300ns)

 #else

  I2C->FREQR = 8;                // input clock to I2C - 8MHz

  I2C->CCRL = 40;                // CCR= 40 - (SCLhi must be at least 4000+1000=5000ns!)

  I2C->CCRH = 0;                 // standard mode, duty 1/1 bus speed 100kHz

  I2C->TRISER = 9;               // 1000ns/(125ns) + 1  (maximum 1000ns)

 #endif

  I2C->OARL = 0xA0;              // own address A0;

  I2C->OARH |= 0x40;

  //I2C->ITR = 1;                // enable error interrupts

  I2C->CR2 |= 0x04;              // ACK=1, Ack enable

  I2C->CR1 |= 0x01;              // PE=1

}

 void I2C_7BitAdresse(){

  while(I2C->SR3 &1 <<1){ //Busy Bit pollen

  I2C->CR2 |= 2;                           // STOP=1, generate stop

    while((I2C->CR2 & 2));              // wait until stop is performed

 }

  I2C->SR1 |=1; //Start Sequenz

  while(!(I2C->SR1 &1));  //wait for Start Sequenz   

  while(!(I2C->SR1 &1<<7)); 

  I2C->DR = (uint8_t)(SlaveAdress << 1); // Send Adress

  while(!(I2C->SR1 & 2));

 }

2 REPLIES 2
jro
Associate III
Posted on May 05, 2015 at 10:33

Hi there

I'm using the STM8L, but if the hardware is similar then it looks as if you haven't enabled the peripheral clock:

CLK->PCKENR1 |= CLK_PCKENR1_I2C1; // or something like that...

If the peripheral isn't clocked none of the registers work!

Cheers

Jonathan

Maddi.Mike
Associate II
Posted on June 25, 2015 at 16:47

UPDATE!!

The problem turned out to be hardware. I am working on a prototype board and you know how EE's are. Us software guys always have to prove them wrong before they do anything. So I did not need the SWRST after all. Everything works great now.

I am having the same problem with the BSY bit. I am using a STM8S208C which enables all peripheral clocks by default. The master clock is 16MHz. I can't get the I2C device to clock out anything. In the init function shown below, you will notice a line between the ''DEBUG'' comments. That's what I had to do to get the BSY bit to reset to zero.

After the init, I try to send the address with:

   I2C->DR = 0x7C;

and I see no clock output on the scope.

Someone out there in STM8S land must have the I2C device working. Can you share your code?

void I2C_Init()

{

    // Set the input clock frequency (fmaster)

    I2C->FREQR = (u8)16;        // 16 MHz

    // Set the clock control register (CCR)

    I2C->CCRL = (u8)80;         // Provides an output clock of 100kHz...

    I2C->CCRH = (u8)0;          // ...at 50% duty cycle

    // Set the maximum rise time (1000 ns) + 1

    // 1000ns / clock Period + 1 = 0.000001 / (1/16000000) + 1 = 0.000001 / 0.0000000625 + 1 = 17

    I2C->TRISER = 17;

    // Enable the I2C device

    I2C->CR1 = I2C_CR1_PE;

    I2C->CR2 |= I2C_CR2_ACK;

// ***************** DEBUG ++++++++++++++++++++++++++++++++++++++++

I2C->CR2 |= I2C_CR2_SWRST;

// ***************** DEBUG ----------------------------------------

    // Set the start bit to enter master mode

    PCF8566_start();

}