2010-10-21 07:50 AM
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.2010-10-21 08:53 AM
I2C1 is on APB1, you don't enable the clock.
RCC->APB1ENR |= RCC_APB1RSTR_I2C1RST;2010-10-24 07:26 AM
2010-10-24 08:02 AM
hi
i tried that code too but still nothing on PB6,PB7. why? thanks. #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 */ #define I2C_EVENT_MASTER_BYTE_TRANSMITTED ((uint32_t)0x00070084) /* TRA, BUSY, MSL, TXE and BTF flags */ void setsystemclock(void); FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG); uint16_t Address=0,PageStatus0=0; void eeprom_write(char data,char address); 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 RCC->APB1ENR |= RCC_APB1RSTR_I2C1RST; //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(1) { GPIOA->ODR=0; eeprom_write((char)0x5,(char)0x15); 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 } void eeprom_write(char data,char address) { uint32_t i2c_flag=0; uint32_t flag1 = 0, flag2 = 0; /*flag1 = I2C1->SR1; flag2 = I2C1->SR2; flag2 = flag2 << 16; i2c_flag= (flag1 | flag2) & FLAG_Mask;*/ /* while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)) { } */ I2C1->CR1 |=I2C_CR1_START ; /* Get the last event value from I2C status register */ flag1 = I2C1->SR1; flag2 = I2C1->SR2; flag2 = flag2 << 16; i2c_flag= (flag1 | flag2) & FLAG_Mask; while(!(i2c_flag&I2C_EVENT_MASTER_MODE_SELECT ));/* BUSY, MSL and SB flag */ I2C1->DR =0;//EEprom Address address flag1 = I2C1->SR1; flag2 = I2C1->SR2; flag2 = flag2 << 16; i2c_flag= (flag1 | flag2) & FLAG_Mask; while(!(i2c_flag&I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));/* BUSY, MSL, ADDR, TXE and TRA flags */ I2C1->DR =address;//internal address flag1 = I2C1->SR1; flag2 = I2C1->SR2; flag2 = flag2 << 16; i2c_flag= (flag1 | flag2) & FLAG_Mask; while(!(i2c_flag&I2C_EVENT_MASTER_BYTE_TRANSMITTED ));/* BUSY, MSL, ADDR, TXE and TRA flags */ I2C1->DR =data;//data while(!(i2c_flag&I2C_EVENT_MASTER_BYTE_TRANSMITTED ));/* BUSY, MSL, ADDR, TXE and TRA flags */ I2C1->CR1 |= I2C_CR1_STOP; } 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; }2010-10-24 08:40 AM
i added the line you said but still i get nothing in PB6,PB7. why?
You have other bugs in your code. You must learn to debug your own code, and use the library until you are ready, as I'm not invested in dealing with the registers at this level. The part is complex, and you can waste hours/days at this level, for tasks that should take a few minutes to code. GPIOB->CRL=0XBB000000; Does that look right for setting up PB6/7 in AF open drain mode, and not interfering with PB0-5?
2010-10-24 09:00 AM
2010-10-24 01:27 PM
Here's how I'd write if I wasn't going to waste several man-days with register level tinkering. Attached also is a complete, compiling, Keil uVision 4 project built against the VL firmware package released by ST.
#include ''stm32F10x.h'' #include ''STM32vldiscovery.h'' #define I2C1_SLAVE_ADDRESS7 0xA0 // EEPROM I2C Address #define ClockSpeed 200000 // 200 KHz int main(void) { GPIO_InitTypeDef GPIO_InitStructure; I2C_InitTypeDef I2C_InitStructure; /* GPIOB Periph clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); /* I2C1 and I2C2 Periph clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); /* Configure I2C1 pins: SCL and SDA ----------------------------------------*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; // Open Drain, I2C bus pulled high externally GPIO_Init(GPIOB, &GPIO_InitStructure); /* Enable I2C1 -------------------------------------------------------------*/ I2C_Cmd(I2C1, ENABLE); /* I2C1 configuration ------------------------------------------------------*/ I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = I2C1_SLAVE_ADDRESS7; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = ClockSpeed; I2C_Init(I2C1, &I2C_InitStructure); /*----- Transmission Phase -----*/ /* Send I2C1 START condition */ I2C_GenerateSTART(I2C1, ENABLE); /* Test on I2C1 EV5 and clear it */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); /* Send EEPROM slave Address for write */ I2C_Send7bitAddress(I2C1, I2C1_SLAVE_ADDRESS7, I2C_Direction_Transmitter); /* Test on I2C1 EV6 and clear it */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); /* Send I2C1 EEPROM internal address */ I2C_SendData(I2C1, 0x00); /* Test on I2C1 EV8 and clear it */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); /* Send I2C1 EEPROM data */ I2C_SendData(I2C1, 0x05); /* Test on I2C1 EV8 and clear it */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); /* Send I2C1 STOP Condition */ I2C_GenerateSTOP(I2C1, ENABLE); while(1); // Do not exit return(0); // System will implode } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t* file, uint32_t line) { /* User can add his own implementation to report the file name and line number, ex: printf(''Wrong parameters value: file %s on line %d\r\n'', file, line) */ /* Infinite loop */ while (1) { } } #endif2010-10-24 10:43 PM
hi
first of all i would like to thank you very much for you help and effort . i understand what you mean by not using register values but when i try to compile such afile with IAR i get that almost everything is missing: and this is why i try it throw register value . i am probebly doing something basicly wrong .(maybe some librery should be included?) what is it? thank you again very much. main.c iccarm.exe C:\Documents and Settings\ezrab\Desktop\new ARM\main.c -o C:\Documents and Settings\ezrab\Desktop\ new ARM\Debug\Obj\ --debug --endian=little --cpu=Cortex-M3 -e --fpu=None --dlib_config C:\Program Files\IAR Systems\ Embedded Workbench 5.4\arm\INC\DLib_Config_Normal.h -I C:\Program Files\IAR Systems\Embedded Workbench 5.4\arm\INC\ST\ -I C:\Program Files\IAR Systems\Embedded Workbench 5.4\arm\INC\ -Ohs IAR ANSI C/C++ Compiler V5.41.0.51741/W32 for ARM Copyright (C) 1999-2009 IAR Systems AB. Time limited license: 11 days left Error[Pe020]: identifier ''GPIO_InitTypeDef'' is undefined C:\Documents and Settings\ezrab\Desktop\new ARM\main.c 9 Error[Pe020]: identifier ''I2C_InitTypeDef'' is undefined C:\Documents and Settings\ezrab\Desktop\new ARM\main.c 10 Warning[Pe223]: function ''RCC_APB2PeriphClockCmd'' declared implicitly C:\Documents and Settings\ezrab\Desktop\new ARM\main.c 13 Error[Pe020]: identifier ''RCC_APB2Periph_GPIOB'' is undefined C:\Documents and Settings\ezrab\Desktop\new ARM\main.c 13 Warning[Pe223]: function ''RCC_APB1PeriphClockCmd'' declared implicitly C:\Documents and Settings\ezrab\Desktop\new ARM\main.c 16 Error[Pe020]: identifier ''RCC_APB1Periph_I2C1'' is undefined C:\Documents and Settings\ezrab\Desktop\new ARM\main.c 16 Error[Pe020]: identifier ''GPIO_Pin_6'' is undefined C:\Documents and Settings\ezrab\Desktop\new ARM\main.c 19 Error[Pe020]: identifier ''GPIO_Pin_7'' is undefined C:\Documents and Settings\ezrab\Desktop\new ARM\main.c 19 Error[Pe020]: identifier ''GPIO_Speed_50MHz'' is undefined C:\Documents and Settings\ezrab\Desktop\new ARM\main.c 20 Error[Pe020]: identifier ''GPIO_Mode_AF_OD'' is undefined C:\Documents and Settings\ezrab\Desktop\new ARM\main.c 21 Warning[Pe223]: function ''GPIO_Init'' declared implicitly C:\Documents and Settings\ezrab\Desktop\new ARM\main.c 22 Warning[Pe223]: function ''I2C_Cmd'' declared implicitly C:\Documents and Settings\ezrab\Desktop\new ARM\main.c 25 Error[Pe020]: identifier ''I2C_Mode_I2C'' is undefined C:\Documents and Settings\ezrab\Desktop\new ARM\main.c 28 Error[Pe020]: identifier ''I2C_DutyCycle_2'' is undefined C:\Documents and Settings\ezrab\Desktop\new ARM\main.c 29 Error[Pe020]: identifier ''I2C_Ack_Enable'' is undefined C:\Documents and Settings\ezrab\Desktop\new ARM\main.c 31 Error[Pe020]: identifier ''I2C_AcknowledgedAddress_7bit'' is undefined C:\Documents and Settings\ezrab\Desktop\new ARM\main.c 32 Warning[Pe223]: function ''I2C_Init'' declared implicitly C:\Documents and Settings\ezrab\Desktop\new ARM\main.c 34 Warning[Pe223]: function ''I2C_GenerateSTART'' declared implicitly C:\Documents and Settings\ezrab\Desktop\new ARM\main.c 39 Warning[Pe223]: function ''I2C_CheckEvent'' declared implicitly C:\Documents and Settings\ezrab\Desktop\new ARM\main.c 42 Error[Pe020]: identifier ''I2C_EVENT_MASTER_MODE_SELECT'' is undefined C:\Documents and Settings\ezrab\Desktop\new ARM\main.c 42 Warning[Pe223]: function ''I2C_Send7bitAddress'' declared implicitly C:\Documents and Settings\ezrab\Desktop\new ARM\main.c 45 Error[Pe020]: identifier ''I2C_Direction_Transmitter'' is undefined C:\Documents and Settings\ezrab\Desktop\new ARM\main.c 45 Error[Pe020]: identifier ''I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED'' is undefined C:\Documents and Settings\ezrab\Desktop\new ARM\main.c 48 Warning[Pe223]: function ''I2C_SendData'' declared implicitly C:\Documents and Settings\ezrab\Desktop\new ARM\main.c 51 Error[Pe020]: identifier ''I2C_EVENT_MASTER_BYTE_TRANSMITTED'' is undefined C:\Documents and Settings\ezrab\Desktop\new ARM\main.c 54 Warning[Pe223]: function ''I2C_GenerateSTOP'' declared implicitly C:\Documents and Settings\ezrab\Desktop\new ARM\main.c 63 Warning[Pe111]: statement is unreachable C:\Documents and Settings\ezrab\Desktop\new ARM\main.c 67 Errors: 16 Warnings: 11 Error while running C/C++ Compiler Done. 16 error(s), 11 warning(s)2010-10-26 11:35 PM
please i just want to understand how to write like you do without getting all of these errors.
thanks.2010-10-27 08:49 AM
Try building the working projects supplied in the ST example/firmware source. Load the project, then build. Once you have a working template, you can then copy/clone the project to its own directory and modify it to meet your needs. This works for Keil uv4, would probably work with IAR too.
Once you understand the structure of a working project, and how it pulls in library and include files, you can create your own projects from scratch. The project file tells the compiler/IDE where to pull the include files from, and sets a couple of #defines used in the compilation. Check the options for the project, and the files within it.