2023-12-13 04:56 PM
I want to use two STM32F401xx MCU in proteus. One of them is to be a master and the other is to be a slave.
This is my code for the master:
#include <stdint.h>
#include <stdio.h>
uint8_t temp=0;
void begin();
void end(void);
void Write (uint8_t);
void star(void);
void address(uint8_t addr);
uint8_t value = 0x00 ;
void main() {
begin();
star();
address(0x08);
Write(0x01);
end();
}
void begin(){
//join I2C as a master mode
RCC_APB1ENR |= (1<<21); // enable I2C CLOCK
RCC_AHB1ENR |= (1<<1); // Enable GPIOB CLOCK
// Configure the I2C PINs for ALternate Functions
//PB8 and PB9 are connected to I2C1_SCL and I2C1_SDA
GPIOB_MODER |= (1<<16)|(1<<18);
GPIOB_OTYPER |= ((1<<8) | (1<<9));
GPIOB_OSPEEDR |= ((3<<16) | (3<<18));
GPIOB_PUPDR |= ((1<<16) | (1<<18));
GPIOB_AFRH |= ((4<<0) | (4<<4));
// Reset the I2C
I2C1_CR1 |= (1<<15); //I2C Peripheral under reset state -->page.493 manual
I2C1_CR1 &= ~(1<<15); //I2C Peripheral not under reset -->page.493 manual
// Program the peripheral input clock in I2C_CR2 Register in order to generate correct timings
I2C1_CR2 |= (42 <<0); // PCLK1 FREQUENCY in MHz
I2C1_CCR |= (210<<0); // Configure the clock control registers
I2C1_TRISE = 43; // Configure the rise time register
I2C1_CR1 |= (1<<0); // Enable I2C
}
void star(void){
//Generate a start condition
I2C1_CR1 |= (1<<8); // Generate START
while (!(I2C1_SR1 & (1<<0))); // Wait for SB bit to set to 1
}
void address(uint8_t addr){
I2C1_DR = addr; // send the address
while (!(I2C1_SR1 & (1<<1)));// wait until the address recieved success
temp = I2C1_SR1 | I2C1_SR2; //clear ADDR
}
void end(void) {
I2C1_CR1 |= (1<<9);//stop generation
// Wait until the STOP condition is complete
while (I2C1_SR2 & (1<<0)); //Cleared by hardware after detecting a Stop condition on the bus
// Clear the STOP bit
I2C1_CR1 &= ~(1<<9);
}
void Write (uint8_t dat)
{
while (!(I2C1_SR1 & (1<<7))); // wait for TXE bit to set
I2C1_DR = dat ; // wait for BTF bit to set
while (!(I2C1_SR1 & (1<<2))); //waiting while BTF=0 but when BTF=1; Data byte transfer succeeded
}
code for the slave:
#include <stdint.h>
#include <stdio.h>
uint8_t temp=0;
uint8_t state =0x00;
void begin(uint8_t addr);
void end(void);
uint8_t Read ();
void main() {
RCC_AHB1ENR |= (1<<0); // Enable GPIOA CLOCK
GPIOA_MODER |=(1<<0);//set pin 0 as output
begin(0x08);
state = Read();
end();
if (state == 0x01){
GPIOA_ODR |=(1<<0);//set 1 for pin 0
}
}
void begin(uint8_t addr){
RCC_APB1ENR |= (1<<21); // enable I2C CLOCK -
RCC_AHB1ENR |= (1<<1); // Enable GPIOB CLOCK
// Configure the I2C PINs for ALternate Functions
//PB8 and PB9 are connected to I2C1_SCL and I2C1_SDA
GPIOB_MODER |= (2<<16) | (2<<18);
GPIOB_OTYPER |= (1<<8) | (1<<9);
GPIOB_OSPEEDR |= (3<<16) | (3<<18);
GPIOB_PUPDR |= (1<<16) | (1<<18);
GPIOB_AFRH |= (4<<0) | (4<<4);
I2C1_CR2 |= (42 <<0); // PCLK1 FREQUENCY in MHz
I2C1_CCR |= (210<<0); // Configure the clock control registers
I2C1_TRISE = 43; // Configure the rise time register
I2C1_CR1 |= (1<<0); // Enable I2C
//join I2C bus as a slave mode
I2C1_OAR1 = addr;//own address interface
I2C1_CR1 |= (1<<0); // Enable I2C
I2C1_CR1 |= (1<<10); // Enable the ACK ,indicate that a byte is received
}
void end(void) {
I2C1_CR1 |= (1<<9);//stop generation
// Wait until the STOP condition is complete
while (I2C1_SR2 & (1<<0)); //Cleared by hardware after detecting a Stop condition on the bus
// Clear the STOP bit
I2C1_CR1 &= ~(1<<9)
}
uint8_t Read (){
uint8_t receivedData = 0;
I2C1_CR1 &= ~(1<<10); // clear the ACK bit
temp = I2C1_SR1 | I2C1_SR2; // read SR1 and SR2 to clear the ADDR bit.... EV6 condition
I2C1_CR1 |= (1<<9); // Stop I2C
while (!(I2C1_SR1 & (1<<6))); // wait for RxNE to set
receivedData = I2C1_DR; // Read the data from the DATA REGISTER
return receivedData;
}
when i run the simulation there is nothing happened , the LED still off and PB8 , PB9 haven`t change , i want to know , if there any problem in my provided code, I followed the datasheet and manual of STM32F401xx to write this simple driver. is this the correct address will be passed to begin(addr) ?
and this is the simulation connection in proteus:
2023-12-13 11:18 PM
Hello,
You can start with using HAL or LL then if all worked fine, inspire from it to access directly to the registers.
And frankly, if I was you, I don't rely on this kind of simulation.
I suggest to run your tests on a real HW!
2023-12-14 04:45 AM
"i want to know , if there any problem in my provided code"
So what have you done to investigate & debug your code?
You're using Proteus - so you have both software & hardware debug facilities available to you...
https://www.labcenter.com/tutorials/
https://www.youtube.com/@LabcenterElectronicsLtd