2015-04-28 02:00 AM
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)); }2015-05-05 01:33 AM
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 Jonathan2015-06-25 07:47 AM
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(); }