I2C
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2010-10-21 7:50 AM
Posted on October 21, 2010 at 16:50
hi
i am tring to activate the I2C in order to External EEPROM i used this code but nothing is in the output on PB why? #include ''stm32F10x.h'' #define IWDG_WriteAccess_Enable ((uint16_t)0x5555) #define IWDG_Prescaler_32 ((uint8_t)0x03) #define KR_KEY_Reload ((uint16_t)0xAAAA) #define KR_KEY_Enable ((uint16_t)0xCCCC) /* I2C F/S mask */ #define CCR_FS_Set ((uint16_t)0x8000) #define I2C_AcknowledgedAddress_7bit ((uint16_t)0x4000) #define I2C_SLAVE_ADDRESS7 0xA0 /* I2C FLAG mask */ #define FLAG_Mask ((uint32_t)0x00FFFFFF) #define I2C_FLAG_BUSY ((uint32_t)0x00020000) #define I2C_EVENT_MASTER_MODE_SELECT ((uint32_t)0x00030001) /* BUSY, MSL and SB flag */ #define I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ((uint32_t)0x00070082) /* BUSY, MSL, ADDR, TXE and TRA flags */ void setsystemclock(void); FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG); ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT); uint16_t Address=0,PageStatus0=0; int main(void) { char byte_temp=0; setsystemclock(); //set system clock to 24Mhz RCC->APB2ENR |= RCC_APB2RSTR_AFIORST | RCC_APB2RSTR_IOPBRST |RCC_APB2RSTR_IOPARST ;//activate i2c ,port C ,port A, portB, clock and alternative clock enable. page 79 //GPIO configuration GPIOB->CRL=0XBB000000; GPIOA->CRL=0x333333; GPIOA->CRH=0x333333; //I2C Configuration I2C1->CR1=I2C_CR1_PE ;/*!<Peripheral Enable */ I2C1->CR2 = 24;// 24mhz/1000000 work on 2Mhz I2C1->CR1 &= ~I2C_CR1_PE; /* Disable the selected I2C peripheral to configure TRISE */ I2C1->TRISE =8;//24*300/1000 +1 I2C1->CCR =40|CCR_FS_Set; I2C1->CR1=I2C_CR1_PE ;/*!<Peripheral Enable */ // I2C1->CR1|=I2C_CR1_ACK; /*!<Acknowledge Enable */ I2C1->OAR1 =I2C_AcknowledgedAddress_7bit | I2C_SLAVE_ADDRESS7; /* Set I2Cx Own Address1 and acknowledged address */ while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)) { } I2C1->CR1 |=I2C_CR1_START ; I2C1->DR =0;//address I2C1->DR =0x5;//data GPIOA->ODR=0; while(1) { I2C1->DR =0x5; GPIOA->ODR^=0xff; } } void setsystemclock(void) { RCC->CR |= RCC_CR_HSEON; // Wait until it's ready while ((RCC->CR & RCC_CR_HSERDY) == 0) ; // Select PREDIV1 as PLL source and sett PLL mul to 3 (set bit 0) // for 8*3 = 24 MHz RCC->CFGR |= RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL_0; // Start PLL RCC->CR |= RCC_CR_PLLON; // Wait until it's ready while ((RCC->CR & RCC_CR_PLLRDY) == 0) ; // Select PLL as system clock RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_PLL; // Wait until PLL is used as system clock source while ((RCC->CFGR & RCC_CFGR_SWS) != 0x08) ; // Here we can check if PLL is used, and maybe disable HSI // Disable HSI RCC->CR &= ~RCC_CR_HSION; RCC->CFGR|=RCC_CFGR_MCO_2; //sys clock output } FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG) { FlagStatus bitstatus = RESET; __IO uint32_t i2creg = 0, i2cxbase = 0; /* Get the I2Cx peripheral base address */ i2cxbase = (uint32_t)I2Cx; /* Read flag register index */ i2creg = I2C_FLAG >> 28; /* Get bit[23:0] of the flag */ I2C_FLAG &= FLAG_Mask; if(i2creg != 0) { /* Get the I2Cx SR1 register address */ i2cxbase += 0x14; } else { /* Flag in I2Cx SR2 Register */ I2C_FLAG = (uint32_t)(I2C_FLAG >> 16); /* Get the I2Cx SR2 register address */ i2cxbase += 0x18; } if(((*(__IO uint32_t *)i2cxbase) & I2C_FLAG) != (uint32_t)RESET) { /* I2C_FLAG is set */ bitstatus = SET; } else { /* I2C_FLAG is reset */ bitstatus = RESET; } /* Return the I2C_FLAG status */ return bitstatus; } ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT) { uint32_t lastevent = 0; uint32_t flag1 = 0, flag2 = 0; ErrorStatus status = ERROR; /* Read the I2Cx status register */ flag1 = I2Cx->SR1; flag2 = I2Cx->SR2; flag2 = flag2 << 16; /* Get the last event value from I2C status register */ lastevent = (flag1 | flag2) & FLAG_Mask; /* Check whether the last event contains the I2C_EVENT */ if ((lastevent & I2C_EVENT) == I2C_EVENT) { /* SUCCESS: last event is equal to I2C_EVENT */ status = SUCCESS; } else { /* ERROR: last event is different from I2C_EVENT */ status = ERROR; } /* Return status */ return status; } thanks.
This discussion is locked. Please start a new topic to ask your question.
12 REPLIES 12
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2012-04-16 6:03 AM
Posted on April 16, 2012 at 15:03Sorry for digging out this old stuff, but I've got a problem with a digital potentiometer. I'm using it for a variable LP Filter. So my question is, when I use the source code as in your in examples, I can send some data Bytes on the Bus and the potentiometers give me Acknowledge, but the problem is, they don't change their values. I got it working a time ago, but changed my code slightly, but can't remember why. But is it right that the data is delivered without failure to the Pots when I get ACK by them? Best regards...
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2012-04-16 9:46 AM
Posted on April 16, 2012 at 18:46
I have no idea what digi-pot you're using, or the requirements it's documentation might express.
Make sure you are writing the correct register, perhaps try dumping out all the registers on this I2C device to confirm that they appear to be correct. The ACK simply means that the transmission protocol worked, and that the I2C device received the bits being sent. ie You got the part address correct, there is a part attached to the bus at this address. It does not mean you wrote the correct register for the digi-pot output, or that you have the part correctly configured. Review any documentation, or example code for the part. Google to see if anyone else uses the part, and perhaps how they programmed it.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Up vote any posts that you find helpful, it shows what's working..
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2012-05-04 11:11 PM
Posted on May 05, 2012 at 08:11
Hi Clive
how does your code look when using remap of the i2c1 on pins pb8 and pb9 (stm32f103ze).I placed a GPIO_PinRemapConfig(GPIO_Remap_I2C1, ENABLE); linejust before the port initialization which is also modified to pb8 and pb9 of course.Both I2C lines go low as soon as GPIO_Init is called. Any idea?When I declare the pins as inputs, the lines stay high. So I expect that something inside the STM32f103 or most probably me does wrong :)best regardsDani
- « Previous
-
- 1
- 2
- Next »