|
爱科技、爱创意、爱折腾、爱极致,我们都是技术控
您需要 登录 才可以下载或查看,没有账号?立即注册
x
最近玩了下STM32G030 感觉这波更新很多,好多外设都有焕然一新的感觉,时钟系统也大改了,玩起来还蛮有意思的。
关键是还挺便宜的,今天研究了下硬件IIC驱动,HAL库实在是又长又臭 不爱看,再加上DMA更乱了,就干脆直接寄存器硬怼吧。
研究了以后发现好像和STM32F030的硬件IIC是同一个核 那就一起都测试下吧。
网上关于STM32G系列的资料太少了 找啥都没有 吧自己研究结果共享下大家一起玩
相关阅读:
stm8的硬件IIC代码-寄存器版|http://bbs.mydigit.cn/read.php?tid=2540435
测试效果
检查外设是否响应-ACK
检查外设是否响应-NAK 已加入简单的错误处理防止nak以后卡死
读和写
以下是代码-G030下的
- #define FLAG_TIMEOUT ((uint32_t)0x1000)
- #define LONG_TIMEOUT ((uint32_t)(10 * FLAG_TIMEOUT))
- #define CR1_CLEAR_MASK ((uint32_t)0x00CFE0FF)
- //PA11 I2C_SCL
- //PA12 I2C_SDA
- void I2C_Init(void)
- {
- RCC->IOPENR |= RCC_IOPENR_GPIOAEN;
- RCC->APBENR1 |= RCC_APBENR1_I2C2EN;
- //SYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_RMP|SYSCFG_CFGR1_PA12_RMP;
-
- GPIOA->MODER &=~ (GPIO_MODER_MODE9|GPIO_MODER_MODE10|GPIO_MODER_MODE11|GPIO_MODER_MODE12);
- GPIOA->MODER |= GPIO_MODER_MODE11_1|GPIO_MODER_MODE12_1;
- GPIOA->OTYPER |= (GPIO_OTYPER_OT11|GPIO_OTYPER_OT12);
- GPIOA->OSPEEDR |= GPIO_OSPEEDR_OSPEED11|GPIO_OSPEEDR_OSPEED12;
- GPIOA->PUPDR&=~(GPIO_PUPDR_PUPD11|GPIO_PUPDR_PUPD12);
- GPIOA->PUPDR|= GPIO_PUPDR_PUPD11_0|GPIO_PUPDR_PUPD12_0;//pull-up
- GPIOA->AFR[1]&=~(GPIO_AFRH_AFSEL11|GPIO_AFRH_AFSEL12);
- GPIOA->AFR[1]|=(6<<3*4)|(6<<4*4);//PA11/12 AF6 IIC2
-
- I2C2->CR1 &= ((uint32_t)~((uint32_t)I2C_CR1_PE))&CR1_CLEAR_MASK;
- I2C2->CR1 &=~ I2C_CR1_ANFOFF;
- //400KHz<span id="kM0.15701809540889855">@64MHz</span>
- I2C2->TIMINGR = (0x17UL << I2C_TIMINGR_SCLL_Pos)|(0x9UL << I2C_TIMINGR_SCLH_Pos)|(0x2UL << I2C_TIMINGR_SDADEL_Pos)|(0x3UL << I2C_TIMINGR_SCLDEL_Pos)|(0x3UL << I2C_TIMINGR_PRESC_Pos);
- I2C2->CR1 = (0x1UL << I2C_CR1_DNF_Pos);
- I2C2->CR1 |= I2C_CR1_PE;
- }
- //返回1为失败 0为正常
- uint8_t IIC_Wait(uint32_t I2C_FLAG)
- {
- uint32_t Timeout;
- Timeout = LONG_TIMEOUT;
- //while(I2C_GetFlagStatus(I2C2, I2C_ISR_TXIS) == RESET)
- while((I2C2->ISR&I2C_FLAG)==0)
- {
- if((Timeout--) == 0)
- return 1;
- }
- if(I2C2->ISR&I2C_ISR_NACKF)
- {
- I2C2->ICR = I2C_ICR_NACKCF;
- return 1;//收到nak
- }
- return 0;
- }
- //0-ok
- //other error
- uint32_t I2C_Check_Device(uint8_t I2C_Addr)
- {
- uint32_t tmpreg;
- //if(IIC_Wait(I2C_ISR_BUSY))return 1;//总线忙
- tmpreg=I2C2->CR2;
- tmpreg&= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP));
- tmpreg|=I2C_Addr|I2C_CR2_START|I2C_CR2_STOP;
- I2C2->CR2 = tmpreg;
- tmpreg = IIC_Wait(I2C_ISR_STOPF);
- I2C2->ICR = I2C_ICR_STOPCF;
- return tmpreg;
- }
- //返回实际读取数量
- uint8_t IIC_Read(uint8_t Addr,uint8_t Reg,uint8_t Num,uint8_t* Data_Buff)
- {
- uint32_t tmpreg,Pointer=0;
- if(Num==0)return 0;
- tmpreg=I2C2->CR2;
- tmpreg&= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP));
- tmpreg|=Addr|I2C_CR2_START|(1<<16);//数量
- I2C2->CR2 = tmpreg;
- if(IIC_Wait(I2C_ISR_TXIS))return 0;
- //Send memory address
- I2C2->TXDR=Reg;
- if(IIC_Wait(I2C_ISR_TC))return 0;
-
- tmpreg=I2C2->CR2;
- tmpreg&= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP));
- tmpreg|=Addr|I2C_CR2_START | I2C_CR2_RD_WRN|I2C_CR2_AUTOEND|(Num<<16);
- I2C2->CR2 = tmpreg;
- while(Num)
- {
- if(IIC_Wait(I2C_ISR_RXNE))return Pointer;
- Data_Buff[Pointer]=I2C2->RXDR;
- Pointer++;
- Num--;
- }
- return Pointer;
- }
- void IIC_Write(uint8_t Addr,uint8_t Reg,uint8_t Num,uint8_t* Data_Buff)
- {
- uint32_t tmpreg,Pointer=0;
- if(Num==0)return;
- tmpreg=I2C2->CR2;
- tmpreg&= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP));
- tmpreg|=Addr|I2C_CR2_START|I2C_CR2_AUTOEND|((Num+1)<<16);//数量
- I2C2->CR2 = tmpreg;
- if(IIC_Wait(I2C_ISR_TXE))return;
- //Send memory address
- I2C2->TXDR=Reg;
- while(Num)
- {
- if(IIC_Wait(I2C_ISR_TXE))return;
- I2C2->TXDR=Data_Buff[Pointer];
- Pointer++;
- Num--;
- }
- IIC_Wait(I2C_ISR_TXE);
- return;
- }
- void IIC_Write_REG(uint8_t Addr,uint8_t Reg)
- {
- uint32_t tmpreg;
- tmpreg=I2C2->CR2;
- tmpreg&= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP));
- tmpreg|=Addr|I2C_CR2_START|I2C_CR2_AUTOEND|(1<<16);//数量
- I2C2->CR2 = tmpreg;
- if(IIC_Wait(I2C_ISR_TXE))return;
- //Send memory address
- I2C2->TXDR=Reg;
- IIC_Wait(I2C_ISR_TXE);
- return;
- }
- //返回实际读取数量
- uint8_t IIC_Read_Without_Reg_Addr(uint8_t Addr,uint8_t Num,uint8_t* Data_Buff)
- {
- uint32_t tmpreg,Pointer=0;
-
- tmpreg=I2C2->CR2;
- tmpreg&= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP));
- tmpreg|=Addr|I2C_CR2_START | I2C_CR2_RD_WRN|I2C_CR2_AUTOEND|(Num<<16);
- I2C2->CR2 = tmpreg;
- while(Num)
- {
- if(IIC_Wait(I2C_ISR_RXNE))return Pointer;
- Data_Buff[Pointer]=I2C2->RXDR;
- Pointer++;
- Num--;
- }
- return Pointer;
- }
- void IIC_Write_Without_Reg_Addr(uint8_t Addr,uint8_t Num,uint8_t* Data_Buff)
- {
- uint32_t tmpreg,Pointer=0;
- if(Num==0)return;
- tmpreg=I2C2->CR2;
- tmpreg&= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP));
- tmpreg|=Addr|I2C_CR2_START|I2C_CR2_AUTOEND|((Num)<<16);//数量
- I2C2->CR2 = tmpreg;
- while(Num)
- {
- if(IIC_Wait(I2C_ISR_TXE))return;
- I2C2->TXDR=Data_Buff[Pointer];
- Pointer++;
- Num--;
- }
- IIC_Wait(I2C_ISR_TXE);
- return;
- }
复制代码 STM32F0上的初始化
如果是TSSOP20的丐版 自己改下引脚到PA脚,然后全局Ctrl+H替换I2C2----->I2C1
- void IIC2_Init(void)
- {
- RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
- RCC->APB1ENR |= RCC_APB1ENR_I2C2EN;
-
-
- GPIOB->OTYPER|=GPIO_OTYPER_OT_11|GPIO_OTYPER_OT_10;//OD
- GPIOB->OSPEEDR|=GPIO_OSPEEDR_OSPEEDR11|GPIO_OSPEEDR_OSPEEDR10;//50M
- GPIOB->MODER&=~(GPIO_MODER_MODER11|GPIO_MODER_MODER10);
- GPIOB->PUPDR&=~(GPIO_PUPDR_PUPDR11|GPIO_PUPDR_PUPDR10);
- GPIOB->MODER|=GPIO_MODER_MODER11_1|GPIO_MODER_MODER10_1;//复用
- GPIOB->PUPDR|=GPIO_PUPDR_PUPDR11_0|GPIO_PUPDR_PUPDR10_0;//pull-up
- GPIOB->AFR[1]&=~(GPIO_AFRH_AFR11|GPIO_AFRH_AFR10);
- GPIOB->AFR[1]|=(1<<3*4)|(1<<2*4);//PB10/11 AF1 IIC
-
- //Disable I2Cx Peripheral
- I2C2->CR1 &= ((uint32_t)~((uint32_t)I2C_CR1_PE))&CR1_CLEAR_MASK;
- //EN AnalogFilter
- I2C2->CR1 &=~ I2C_CR1_ANFOFF;
- //Configure I2Cx: Timing
- I2C2->TIMINGR = 0x00210507;//381K<span id="kM0.5335161359873961">@48MHz</span>
- //Enable I2Cx Peripheral
- I2C2->CR1 |= I2C_CR1_PE;
- }
复制代码
|
打赏
-
查看全部打赏
|