#4. STM32F4 I2C Using Registers || Master mode || NO HAL ||

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hello everyone welcome to controllers tech this is the fourth video in the register programming and today we will see how can we use i2c with stm32 using registers obviously i am not going to use any hall related code here and there is a lot of registers to cover so this video will be a bit longer let's start by creating the project in kyle id create the project folder and give some name to the project [Music] now choose the mcu here i am only going to add the core and device startup files [Music] here is our project now let's add the main file first i am going to add a main function and a while loop inside it let's add some basic library files these are basically the clock configuration and the timer configuration files i have already covered them in the first two videos let's include them in kyle also [Music] include the header files in the main file this is it for basic setup now let's write a function to configure the i2c before we go any further let's check the reference manual first [Music] this video will only cover the master mode so let's check it out here are the steps given to configure the i2c in the master mode we need to set the input clock in the cr2 register configure the clock control register configure the rise time register and finally enable peripheral then a start condition must be sent then there is slave address transmission and then the data transmission we will cover them all one by one we will start with the configuration part here are the steps that need to be followed i have added some more steps for clock and gpio configuration also let's start by enabling the i2c and gpio clocks [Music] to do so let's go to the rcc peripheral clock enable register here you see the i2c1 is the 21st bit and to enable this clock we need to write a 1 in the 21st position [Music] now the gpio clocks i am using i2c1 and here are the sda and sdl pins they are pb8 and pb9 so i need to enable the gp iob clock which is located in our cca hb1enr register so let's write a one to the first bit to enable the gpio b clock now we need to configure the pins here first of all we will select the alternate functions for the pins this can be done in the modern register as you know i am using pin number 8 and 9 so i need to write in mode 8 and mode 9 and to select alternate function i need to write a 1 and a 0 which is basically writing a 2 in the 16th and the 18th position [Music] next we need to select the open drain output in the o type register [Music] here we will just write a one in the eighth and ninth bit for the pin pb8 and pb9 [Music] next select the high speed for the pins again we need to write a 3 in the 16th and 18th position [Music] next select the pull-up for both the [Music] pins in the pupdr register i need to write a 1 again in the 16th and 18th position [Music] and now finally we will configure the alternate functions this can be done in the afr register but before that we need to see what values we are going to use as you can see here afrl register is used for pins 0 to 7 and if you are using pins 8 to 15 you need to use a frh register as i am using i2c1 i need to select af4 let's go back to afrh register here i need to write a 4 to the pins 8 and 9 which is basically the 0th and the 4th bits here afr1 means the afrh register and in case of aflo register use afr0 that's all for the pins configuration now let's start the i2c part first of all we will reset the i2c this can be useful in re-initializing the peripheral after the error or any locked state 15th bit of cr1 register can be used for his purpose [Music] so we will first put the i2c in the reset state and then take it out of the reset after the reset state we need to program the peripheral input clock in the cr2 register so what is the peripheral input clock here let's see the data sheet to understand that as you can see here the i2c1 is connected to the apb1 which can run at 45 megahertz and this is the clock setup that i am using right now as i have shown in my first video the apb1 clock is running at 45 megahertz and that's my peripheral input clock for the i2c1 here is the cr2 register and the first five bytes are used for frequency the maximum value can be 50 megahertz and minimum as 2 megahertz these values are anyway in megahertz and so i just need to input 45 here [Music] now the clock control register pay attention here as this will involve some calculations [Music] here i am going to select the standard mode so 15th bit will be zero [Music] duty will also be zero as i am not using the fast mode and now the ccr value in standard mode we can calculate ccr by either using the t high formula or t low formula i am going to use t high here as you can see the t high is equal to the rise time for clock plus the clock high duration and these values can be found in the data sheet so basically the formula for ccr will become like this go to the i2c characteristics in the data sheet and here you can find all the values for your device i have the clock rise time of 1000 nanoseconds and clock high time of 4 microseconds which is 4 000 nanoseconds also time for pcl k1 can be found by 1 divide by the clock frequency and finally the ccr value is 225 let's write 225 to the ccr register next is the calculation for the t rise you can read the details here on the reference manual but basically it comes to this formula and we got the t rise as 46. [Music] let's update it now we need to enable the i2c peripheral we can do that by setting the bit zero of the cr1 register please note that this here should be bit 0 not 1. this is all for the configuration now let's write a function for i2c start [Music] here we first set the start bit and then wait for the sb bit to set this basically indicates that the start condition is generated [Music] let's see the registers start bit is bit 8 of the cr1 register [Music] so write a one to the eighth bit [Music] sb is the bit zero in the status register one and if it is set it means that the start condition generated so we will wait for the bit 0 to set in the sr1 register [Music] now let's write a function for writing the data to the i2c device [Music] the description is given here but you will better understand it with this figure here so before writing the data we must check for this particular event which says that the txe bit must be 1 to indicate that the buffer is empty then we write the data and after we are finished writing we check for event ev8 which says that the txe and btf bits must be one to indicate the transfer has finished [Music] so we will wait for the txe bit to set then send the data and then wait for btf bit to set in the status register 1 bit 2 is the btf bit and bit 7 is the txe bit let's first wait for the txe bit to set then load the data into the data register and wait for byte transfer to finish next another function for sending the slave address let's see the steps again here after sending the slave address the addr bit will be set to indicate that the transfer is finished and then we need to read the sr1 and sr2 registers to clear the addr bit addr is the bit 1 in the status register 1. so here are the steps need to be followed first send the address into the data register now wait for the addr bit to set and then just read the sr1 and sr2 registers to clear the addr bit [Music] and finally a function to stop the i2c [Music] [Music] ninth bit of the cr1 register is the stop bit and we will write a one to the ninth bit in order to stop the i2c this is basically all but i just want to add one more function here i2c write multi can be used when we want to write more than one byte of data at a time here i am passing the size as the parameter which is the number of bytes we want to write we need to follow the same steps that we did in the right function but with little changes of course let's take a look at that figure again as you see here we can send multiple data bytes but before sending the next data byte we must perform the check for event eight that means we must wait for the txe bit to set and after sending the last data byte we will wait for the btf bit to set [Music] here first check if the txe bit is set and before sending data we need to perform the same check every [Music] time [Music] once the last data byte is sent wait for the btf bit to set that's all for the i2c setup now let's see some working first of all i will include the sysclock config and timer configures usual include the i2c config also before going any forward let's see what device i have here i have is apcf 8574 which is used to drive the lcd displays you can see the input pins right here we have clock and data pins for the i2c [Music] if you google the pin out for this module you can see how the pins are actually connected the numbering on the lcd here is exactly the same as it is on the module so we have the fourth pin connected to p0 5 to p1 6 to p2 and then from 11 to 14 are connected to the p4 to p7 so here i cannot control the first three pins of this module fourth pin is p0 p1 p2 and then p4 to p7 also i have some leds here and i will attach them to this module notice here that i have first led connected to p0 second to p1 then this one is p4 p5 p6 and p7 now connect the vcc to 5 volts ground to ground clock to clock and data to data let's send the start condition first we need the address of the slave here let's check the data sheet of the module [Music] in my case pin a0 a1 and a2 are high so the address will be 0 cross 4 e these pins are high by default and if you have more than one module attached to the same i2c pins you can ground these pins to change the address accordingly [Music] as you can see the sequence here we send the start first then send the address then send the data and finally stop [Music] let's send the address 0 cross 4 e i am going to write 0 cross 0 1 that means i am setting the pin p 0 only and send the stop let's build it go to options and type in the frequency here [Music] select the st link and check reset and run let's flash it [Music] you can see only the first led is on so the code is working as expected let's try to switch the led zero cross zero two means only the second led should be on as expected it works i don't have the led three and four so i will turn on the fifth one for that i will send zero cross one zero i can turn on all of them by writing 0 cross ff things are working just fine here let's try to have some more fun with it i will put this in the while loop where i will turn on one led at a time with a delay of 300 milliseconds [Music] so it's working fine but there is gap of two leds and you can see it let's try to modify the code a little and now we don't have any gap between the leds you can change delay here to make it look a bit better great it looks awesome now this is it for this video you can download the code from the link in the description leave comments in case of any doubt you can mail me if you have any suggestions keep watching be safe and have a nice day ahead
Info
Channel: Controllers Tech
Views: 5,927
Rating: undefined out of 5
Keywords: stm32, stm32f4, f103, discovery, nucleo, register, based, programming, hal, i2c, pcf, 8574, led, example, tutorial
Id: usvAIEdp_I8
Channel Id: undefined
Length: 27min 56sec (1676 seconds)
Published: Sun Oct 11 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.