0:20
welcome to controllers tech this is the
0:23
fourth video in the register programming
0:26
and today we will see how can we use i2c
0:30
using registers obviously
0:34
i am not going to use any hall related
0:37
and there is a lot of registers to cover
0:39
so this video will be a bit longer
0:42
let's start by creating the project in
0:47
create the project folder and give some
0:57
now choose the mcu here i am only going
1:02
and device startup files
1:07
here is our project now let's add the
1:12
first i am going to add a main function
1:15
and a while loop inside it
1:27
let's add some basic library files
1:30
these are basically the clock
1:32
configuration and the timer
1:36
i have already covered them in the first
1:47
let's include them in kyle also
2:04
include the header files in the main
2:13
this is it for basic setup now
2:17
let's write a function to configure the
2:21
before we go any further let's check the
2:23
reference manual first
2:32
this video will only cover the master
2:34
mode so let's check it out
2:38
here are the steps given to configure
2:41
in the master mode we need to set the
2:44
input clock in the cr2 register
2:47
configure the clock control register
2:51
configure the rise time register
2:54
and finally enable peripheral
2:57
then a start condition must be sent
3:04
then there is slave address transmission
3:07
and then the data transmission
3:09
we will cover them all one by one
3:13
we will start with the configuration
3:31
here are the steps that need to be
3:34
i have added some more steps for clock
3:46
let's start by enabling the i2c and gpio
3:54
to do so let's go to the rcc peripheral
3:57
clock enable register
4:04
here you see the i2c1 is the 21st bit
4:09
and to enable this clock we need to
4:11
write a 1 in the 21st position
4:26
i am using i2c1 and here are the sda
4:31
and sdl pins they are pb8
4:35
and pb9 so i need to enable the gp
4:49
which is located in our cca hb1enr
4:56
let's write a one to the first bit to
5:06
now we need to configure the pins
5:09
here first of all we will select the
5:12
alternate functions for the pins
5:15
this can be done in the modern register
5:19
as you know i am using pin number 8 and
5:22
so i need to write in mode 8 and mode 9
5:27
and to select alternate function i need
5:32
which is basically writing a 2 in the
5:35
and the 18th position
5:45
next we need to select the open drain
5:48
output in the o type register
6:00
here we will just write a one in the
6:03
for the pin pb8 and pb9
6:15
next select the high speed for the pins
6:22
again we need to write a 3 in the 16th
6:41
next select the pull-up for both the
6:50
in the pupdr register i need to write a
6:54
again in the 16th and 18th position
7:12
and now finally we will configure the
7:23
this can be done in the afr register but
7:26
we need to see what values we are going
7:36
as you can see here afrl register is
7:41
and if you are using pins 8 to 15 you
7:48
as i am using i2c1 i need to select
7:51
af4 let's go back to afrh register
8:03
here i need to write a 4 to the pins 8
8:06
9 which is basically the 0th and the 4th
8:21
here afr1 means the afrh register and in
8:26
case of aflo register
8:28
use afr0 that's all for the pins
8:34
now let's start the i2c part
8:37
first of all we will reset the i2c
8:41
this can be useful in re-initializing
8:43
the peripheral after the error
8:51
15th bit of cr1 register can be used
9:04
so we will first put the i2c in the
9:07
and then take it out of the reset
9:11
after the reset state we need to program
9:14
the peripheral input clock in the cr2
9:21
so what is the peripheral input clock
9:25
let's see the data sheet to understand
9:39
as you can see here the i2c1 is
9:42
connected to the apb1
9:44
which can run at 45 megahertz
9:51
and this is the clock setup that i am
9:54
as i have shown in my first video
9:58
the apb1 clock is running at 45
10:01
and that's my peripheral input clock for
10:10
here is the cr2 register and the first
10:13
five bytes are used for frequency
10:20
the maximum value can be 50 megahertz
10:23
as 2 megahertz these values are anyway
10:28
and so i just need to input 45 here
10:49
now the clock control register pay
10:53
as this will involve some calculations
11:10
here i am going to select the standard
11:12
mode so 15th bit will be zero
11:19
duty will also be zero as i am not using
11:24
and now the ccr value
11:28
in standard mode we can calculate ccr by
11:32
high formula or t low formula
11:37
i am going to use t high here
11:44
as you can see the t high is equal to
11:47
the rise time for clock plus the clock
11:51
and these values can be found in the
11:59
so basically the formula for ccr will
12:15
go to the i2c characteristics in the
12:18
and here you can find all the values for
12:25
i have the clock rise time of 1000
12:30
and clock high time of 4 microseconds
12:39
also time for pcl k1 can be found by 1
12:43
divide by the clock frequency
12:46
and finally the ccr value is 225
12:54
let's write 225 to the ccr
13:06
next is the calculation for the t rise
13:16
you can read the details here on the
13:30
but basically it comes to this formula
13:52
now we need to enable the i2c peripheral
14:06
we can do that by setting the bit zero
14:15
please note that this here should be bit
14:18
not 1. this is all for the configuration
14:23
now let's write a function for i2c start
14:34
here we first set the start bit and then
14:36
wait for the sb bit to set
14:39
this basically indicates that the start
14:42
condition is generated
14:48
let's see the registers start bit is bit
14:52
8 of the cr1 register
15:00
so write a one to the eighth bit
15:16
sb is the bit zero in the status
15:21
and if it is set it means that the start
15:26
so we will wait for the bit 0 to set in
15:36
now let's write a function for writing
15:57
the description is given here but you
15:59
will better understand it with this
16:06
so before writing the data we must check
16:09
for this particular event
16:10
which says that the txe bit must be 1 to
16:14
indicate that the buffer is empty
16:16
then we write the data and after we are
16:21
we check for event ev8 which says that
16:26
and btf bits must be one to indicate the
16:28
transfer has finished
16:35
so we will wait for the txe bit to set
16:39
and then wait for btf bit to set
17:02
in the status register 1 bit 2 is the
17:06
and bit 7 is the txe bit
17:26
let's first wait for the txe bit to set
17:39
then load the data into the data
17:42
and wait for byte transfer to finish
17:50
next another function for sending the
17:59
let's see the steps again
18:11
here after sending the slave address the
18:14
addr bit will be set to indicate that
18:16
the transfer is finished
18:19
and then we need to read the sr1 and sr2
18:22
registers to clear the addr bit
18:31
addr is the bit 1 in the status register
18:46
so here are the steps need to be
18:50
first send the address into the data
18:57
now wait for the addr bit to set
19:01
and then just read the sr1 and sr2
19:04
registers to clear the addr bit
19:12
and finally a function to stop the i2c
19:32
ninth bit of the cr1 register is the
19:39
and we will write a one to the ninth bit
19:42
in order to stop the i2c
19:45
this is basically all but i just want to
19:47
add one more function here
19:50
i2c write multi can be used when we want
19:53
to write more than one byte of data at a
19:57
here i am passing the size as the
19:59
parameter which is the number of bytes
20:03
we need to follow the same steps that we
20:05
did in the right function
20:07
but with little changes of course
20:14
let's take a look at that figure again
20:17
as you see here we can send multiple
20:21
but before sending the next data byte we
20:23
must perform the check for event eight
20:26
that means we must wait for the txe bit
20:30
and after sending the last data byte we
20:33
will wait for the btf bit to set
20:44
here first check if the txe bit
20:48
is set and before sending data
20:51
we need to perform the same check every
21:05
once the last data byte is sent wait for
21:10
that's all for the i2c setup
21:14
now let's see some working
21:18
first of all i will include the sysclock
21:22
timer configures usual
21:26
include the i2c config also
21:32
before going any forward let's see what
21:37
here i have is apcf 8574
21:40
which is used to drive the lcd displays
21:44
you can see the input pins right here we
21:47
have clock and data pins for the i2c
21:56
if you google the pin out for this
21:57
module you can see how the pins are
22:02
the numbering on the lcd here is exactly
22:05
the same as it is on the module
22:07
so we have the fourth pin connected to
22:12
6 to p2 and then from 11 to 14 are
22:15
connected to the p4 to p7
22:23
so here i cannot control the first three
22:28
fourth pin is p0 p1 p2
22:31
and then p4 to p7 also
22:39
i have some leds here and i will attach
22:59
notice here that i have first led
23:04
second to p1 then this one is p4
23:18
now connect the vcc to 5 volts
23:22
ground to ground clock to clock and data
23:29
let's send the start condition first
23:35
we need the address of the slave here
23:38
let's check the data sheet of the module
23:49
in my case pin a0 a1
23:52
and a2 are high so the address will be 0
23:55
4 e these pins are high by default
23:59
and if you have more than one module
24:01
attached to the same i2c
24:03
pins you can ground these pins to change
24:05
the address accordingly
24:12
as you can see the sequence here we send
24:16
then send the address then send the data
24:25
let's send the address 0 cross 4 e
24:29
i am going to write 0 cross 0 1 that
24:32
means i am setting the pin
24:33
p 0 only and send the stop
24:46
go to options and type in the frequency
25:01
and check reset and run let's flash it
25:12
you can see only the first led is on
25:16
so the code is working as expected
25:19
let's try to switch the led zero cross
25:24
only the second led should be on
25:27
as expected it works i don't have the
25:33
so i will turn on the fifth one
25:36
for that i will send zero cross one zero
25:46
i can turn on all of them by writing 0
25:58
things are working just fine here
26:01
let's try to have some more fun with it
26:07
i will put this in the while loop where
26:09
i will turn on one led at a time with a
26:12
delay of 300 milliseconds
26:30
so it's working fine but there is gap of
26:41
let's try to modify the code a little
27:09
and now we don't have any gap between
27:14
you can change delay here to make it
27:22
great it looks awesome now
27:29
this is it for this video you can
27:32
download the code from the link in the
27:36
leave comments in case of any doubt
27:39
you can mail me if you have any
27:43
keep watching be safe and have a nice