如何修复STM32F334K8T6上I2C传输的代码?(不起作用)
几天来,我一直在研究使用I2C控制多个I/O扩展器的操作 我研究了文档并提出了一些代码(我不与HAL合作,因为我对理解寄存器感兴趣)如何修复STM32F334K8T6上I2C传输的代码?(不起作用),stm32,i2c,stm32f3,Stm32,I2c,Stm32f3,几天来,我一直在研究使用I2C控制多个I/O扩展器的操作 我研究了文档并提出了一些代码(我不与HAL合作,因为我对理解寄存器感兴趣) #包括“main.h” #包括“stdio.h” //功能 /***时钟和计时器部分***/ //系统时钟设置 int systemClockInit(){ //开始时钟序列 /* 1-运行HSE+等待准备就绪 2-配置PLL 3-EN PLL+等待就绪 4-设置闪存等待周期 5套母线分压器 6-切换到PLL模式 7-禁用HSI(可选) */ //身体 int w
#包括“main.h”
#包括“stdio.h”
//功能
/***时钟和计时器部分***/
//系统时钟设置
int systemClockInit(){
//开始时钟序列
/*
1-运行HSE+等待准备就绪
2-配置PLL
3-EN PLL+等待就绪
4-设置闪存等待周期
5套母线分压器
6-切换到PLL模式
7-禁用HSI(可选)
*/
//身体
int waitCounter=0;
//&-位“和”->1&1=1或=0(比较位)
//运行HSE时钟(HSEON-16位)
//1打开16位上的1
RCC->CR |=(1 CR和(1 0x1000){
//清孔钻头
//(替换1-0/0-1位和-清除16位,保存其他)
RCC->CR&=~(1 CFGR |)=(0x1 CR&=~(1 CR&=~(1)设置零等待周期
闪存->ACR |=(0x00 CFGR |=(0x00 AFR[0]|=(0x04 OSpeder&=~GPIO_OSpeder_OSpeder6;//AF(PB6)
GPIOB->ospeder&=~GPIO\u ospeder\u ospeder7;//AF(PB7)
RCC->APB1ENR |=RCC_APB1ENR_I2C1EN;//EN i2c时钟
//I2C总线设置
//RCC->APB1RSTR |=(1 CR1 |=(0 CR1 |=(1计时r |=0x00506682;//I2C计时(0x2000090E)
I2C1->CR1 |=(1 CR1 |=(1 CR1 |=(1 ISR&15);//在总线不忙时等待
I2C1->CR2 |=(0x4 CR2 |=(1 CR2 |=(0x20 CR2 |=(1 ISR&1)和字节计数器){
I2C1->TXDR=0x03;//发送字节#1
字节计数器++;
返回;
}
否则如果((I2C1->ISR&1)和字节计数器==1){
I2C1->TXDR=0x0;//发送字节#2
字节计数器++;
返回;
}
否则如果((I2C1->ISR&1)和字节计数器==3){
I2C1->TXDR=0x01;//发送字节#3
字节计数器++;
返回;
}
否则如果((I2C1->ISR&1)和字节计数器==4){
I2C1->TXDR=0xf8;//发送字节#4
字节计数器++;
返回;
}
}
总线频率APB1=24MHz(计时器必须运行)
I2C频率100kHz,主模式
我只想向地址为0x20的设备发送4个字节
您能帮我找到错误吗?不要使用幻数。没有人会分析此类代码。至少使用带有人类可读定义的CMSIS标题。
#include "main.h"
#include "stdio.h"
// Functions
/*** Clock and timers sections ***/
// System clock settings
int systemClockInit() {
// Start clock sequence
/*
1 - RUN HSE + WAIT ready
2 - Configure PLL
3 - EN PLL + WAIT ready
4 - Set flash wait cycles
5 - Set bus divider
6 - Switch to PLL mode
7 - Disable HSI (Optional)
*/
// Body
int waitCounter = 0;
// & - bit "AND" -> 1 & 1 = 1 or = 0 (Compare bits)
// Run HSE clock (HSEON - 16bit)
// 1 << 16 -> turn on 1 on 16 bit
RCC->CR |= (1 << 16);
// HSEREADY wait
for(waitCounter = 0; ; waitCounter++) {
if(RCC->CR & (1 << 17)) { break; } // If HSE success enabled
if(waitCounter > 0x1000) {
// Clear HSEON bit
// (Replace 1 - 0 / 0 - 1, bit and - clear 16 bit, save other)
RCC->CR &= ~(1 << 16);
return 1;
}
}
// Configure PLL
// 24mHz (x3)
RCC->CFGR |= (0x1 << 18) // PLL x3 (0x1 = 0001), 18 - start PLLMULL sector
| (0x01 << 16); // Enable PLL src on HSE clock
// Enable PLL
RCC->CR |= (1 << 24); // 24 bit - PLLON
// PLL enable WAIT
for(waitCounter = 0; ; waitCounter++) {
if(RCC->CR & (1 << 25)) { break; } // If PLL success enabled
if(waitCounter > 0x1000) {
RCC->CR &= ~(1 << 16); // Disable HSE
RCC->CR &= ~(1 << 24); // Disable PLL
return 2;
}
}
// Set flash wait counter and bus divider
// Core frequency = 24mHz -> set zero wait cycles
FLASH->ACR |= (0x00 << 0); // 0x00 = 000, 0 latency position sector
// Set bus dividers
RCC->CFGR |= (0x00 << 11) // PPRE2 divider disabled (000)
// For < 36mHz
| (0x00 << 8) // APB1 divider disabled (000)
// Wait reconnect to PLL
RCC->CFGR |= (0x02 << 0);
while((RCC->CFGR & 0x08) != (0x02 << 2)) {} // 0x08 - RCC_CFGR_SWS_MSK (00001100). 0x02 - 00000010 - PLL selected sysclk, 2 - SWS bits position
// Disabled HSI clock
RCC->CR &= ~(1 << 0); // Disabled HSI
// Return 0 (Success)
return 0;
}
void I2C_Init(void);
void I2C_Start(void);
void I2C_WriteData(void);
// Main function
int main(void)
{
// System Clock init
systemClockInit();
//printf("State: %d", state);
RCC->AHBENR |= (1 << 17) | (1 << 18); // PORTA and PORTB clock enabled
// Configure ms timer
#define coreFrequency 24000000 // 72mHz core frequency
SysTick_Config(coreFrequency / 1000);
I2C_Init();
I2C_Start();
// Loop
while (1)
{
I2C_WriteData();
}
}
void I2C_Init(void) {
RCC->AHBENR |= RCC_AHBENR_GPIOBEN; // PORT B clock EN
// I2C pins settings
GPIOB->OTYPER |= GPIO_OTYPER_OT_6 | GPIO_OTYPER_OT_7; // Open-Drain PB6, PB7
GPIOB->AFR[0] |= (0x04 << 16); // AF4 (PORTB)
GPIOB->OSPEEDR &= ~GPIO_OSPEEDER_OSPEEDR6; // AF (PB6)
GPIOB->OSPEEDR &= ~GPIO_OSPEEDER_OSPEEDR7; // AF (PB7)
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; // EN i2c clock
// I2C bus settings
//RCC->APB1RSTR |= (1 << 21); // I2C reset
I2C1->CR1 |= (0 << 0); // I2C peripheral disabled
I2C1->CR1 |= (1 << 12); // I2C analog filter disabled
I2C1->TIMINGR |= 0x00506682; // I2C timing (0x2000090E)
I2C1->CR1 |= (1 << 17); // Clock stretching disabled
I2C1->CR1 |= (1 << 1); // Enable TXIS interrupt
I2C1->CR1 |= (1 << 0); // I2C peripheral enabled
}
void I2C_Start(void) {
while(I2C1->ISR & 15); // wait untin bus not busy
I2C1->CR2 |= (0x4 << 16); // 4 bytes (NBYTE)
I2C1->CR2 |= (1 << 25); // AUTOEND EN
I2C1->CR2 |= (0x20 << 0); // Slave address
I2C1->CR2 |= (1 << 13); // Set START
}
void I2C_WriteData(void) {
static int byteCounter = 0;
if((I2C1->ISR & 1) && !byteCounter) {
I2C1->TXDR = 0x03; // send byte #1
byteCounter++;
return;
}
else if((I2C1->ISR & 1) && byteCounter == 1) {
I2C1->TXDR = 0x0; // send byte #2
byteCounter++;
return;
}
else if((I2C1->ISR & 1) && byteCounter == 3) {
I2C1->TXDR = 0x01; // send byte #3
byteCounter++;
return;
}
else if((I2C1->ISR & 1) && byteCounter == 4) {
I2C1->TXDR = 0xf8; // send byte #4
byteCounter++;
return;
}
}