用极海MCU ARM M0的APM32F03x实现I2C的主从模式的SMBUS通信

  • 1.SMBUS通信协议
    • 1.1 符号含义
    • 1.2 SMBus Read Byte
    • 1.3 SMBus Write Byte
  • 2.主从模式SMBUS通信软件实现
    • 2.1 实现架构
    • 2.2 主I2C2初始化
    • 2.3 从I2C1初始化
    • 2.4 I2C主器件主动读写操作处理过程
    • 2.5 从器件响应主器件而返回数据操作处理过程
    • 2.6 从I2C1的中断处理过程
    • 2.7 主I2C2的中断处理过程
    • 2.8 按键的中断处理过程
    • 2.9 主程序的处理过程
    • 2.10 完整的源代码请下载

1.SMBUS通信协议

1.1 符号含义

S (1 bit) : 起始位
Sr (1 bit) : 重复的起始位
P (1 bit) : 停止位
R/W# (1 bit) : Read/Write bit,读写位
A, N (1 bit) : 应答位
Address(7 bits): 地址位,7 位地址
Command Code (8 bits): 命令字节,一般用来选择芯片内部的寄存器
Data Byte (8 bits): 数据字节,8 位;如果是 16 位数据的话,用 2 个字节来表示。
Count (8 bits): 在 block 操作总,表示数据长度
[…]: 中括号表示 I2C 设备发送的数据,没有中括号表示 主机 发送的数据
#define SLAVEADDR0 0xB0 从机I2C地址

1.2 SMBus Read Byte

先发从机地址,发出芯片内部的寄存器地址,再读数据,读取设备寄存器地址储存的1个字节的数据。

1.3 SMBus Write Byte

先发从机地址,发出芯片内部的寄存器地址,再写数据,向设备寄存器地址写1个字节的数据。

2.主从模式SMBUS通信软件实现

2.1 实现架构

2.2 主I2C2初始化


/*!* @brief       I2C Init   ** @param       None** @retval      None** @note*/void I2C2Init(void){GPIO_Config_T gpioConfigStruct;I2C_Config_T i2cConfigStruct;/** Enable I2C related Clock */RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOB);RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_I2C2);RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SYSCFG);/** Free I2C_SCL and I2C_SDA */gpioConfigStruct.mode = GPIO_MODE_OUT;gpioConfigStruct.speed = GPIO_SPEED_50MHz;gpioConfigStruct.outtype = GPIO_OUT_TYPE_PP;gpioConfigStruct.pupd = GPIO_PUPD_NO;gpioConfigStruct.pin = GPIO_PIN_10;GPIO_Config(GPIOB, &gpioConfigStruct);    gpioConfigStruct.pin = GPIO_PIN_11;GPIO_Config(GPIOB, &gpioConfigStruct); GPIO_SetBit(GPIOB,GPIO_PIN_10);GPIO_SetBit(GPIOB,GPIO_PIN_11); /** Connect I2C to SCL */GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_10, GPIO_AF_PIN1);/** Connect I2C to SDA */GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_11, GPIO_AF_PIN1); /**  Config I2C2 GPIO */gpioConfigStruct.mode = GPIO_MODE_AF;gpioConfigStruct.speed = GPIO_SPEED_50MHz;gpioConfigStruct.outtype = GPIO_OUT_TYPE_OD;gpioConfigStruct.pupd = GPIO_PUPD_NO;gpioConfigStruct.pin = GPIO_PIN_10;GPIO_Config(GPIOB, &gpioConfigStruct);    gpioConfigStruct.pin = GPIO_PIN_11;GPIO_Config(GPIOB, &gpioConfigStruct);/**  Config I2C1 */  I2C_Reset(I2C2);RCM_ConfigI2CCLK(RCM_I2C1CLK_SYSCLK);i2cConfigStruct.ack = I2C_ACK_ENABLE;i2cConfigStruct.ackaddress = I2C_ACK_ADDRESS_7BIT;i2cConfigStruct.address1 = 0xA0;i2cConfigStruct.analogfilter = I2C_ANALOG_FILTER_ENABLE;i2cConfigStruct.digitalfilter = I2C_DIGITAL_FILTER_0;i2cConfigStruct.mode = I2C_MODE_SMBUSHOST;i2cConfigStruct.timing = 0xB0420F13;   //100K 48M  //0x1042F013;I2C_Config(I2C2,&i2cConfigStruct);/** Enable the I2C2 Interrupt */ I2C_EnableInterrupt(I2C2,I2C_INT_RXIE|I2C_INT_ADDRIE|I2C_INT_STOPIE);/** NVIC configuration */   NVIC_EnableIRQRequest(I2C2_IRQn,2); /** slave configuration*///I2C_EnableSlaveByteControl(I2C2);//I2C_EnableReload(I2C2);//I2C_EnableStretchClock(I2C2);/** Enable I2Cx */    I2C_Enable(I2C2);}

2.3 从I2C1初始化

//--------------------------------------------------------------------------------------------------------------------
// @brief       I2CInit
// @param       None
// @retval      None
// @note
//--------------------------------------------------------------------------------------------------------------------void I2CInit(void)
{GPIO_Config_T gpioConfigStruct;I2C_Config_T i2cConfigStruct;/** Enable I2C related Clock */RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOB);RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_I2C1);RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SYSCFG);/** Free I2C_SCL and I2C_SDA */gpioConfigStruct.mode = GPIO_MODE_OUT;gpioConfigStruct.speed = GPIO_SPEED_50MHz;gpioConfigStruct.outtype = GPIO_OUT_TYPE_PP;gpioConfigStruct.pupd = GPIO_PUPD_NO;gpioConfigStruct.pin = GPIO_PIN_6;GPIO_Config(GPIOB, &gpioConfigStruct);    gpioConfigStruct.pin = GPIO_PIN_7;GPIO_Config(GPIOB, &gpioConfigStruct); GPIO_SetBit(GPIOB,GPIO_PIN_6);GPIO_SetBit(GPIOB,GPIO_PIN_7); /** Connect I2C to SCL */GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_6, GPIO_AF_PIN1);/** Connect I2C to SDA */GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_7, GPIO_AF_PIN1); /**  Config I2C1 GPIO */gpioConfigStruct.mode = GPIO_MODE_AF;gpioConfigStruct.speed = GPIO_SPEED_50MHz;gpioConfigStruct.outtype = GPIO_OUT_TYPE_OD;gpioConfigStruct.pupd = GPIO_PUPD_NO;gpioConfigStruct.pin = GPIO_PIN_6;GPIO_Config(GPIOB, &gpioConfigStruct);    gpioConfigStruct.pin = GPIO_PIN_7;GPIO_Config(GPIOB, &gpioConfigStruct);/**  Config I2C1 */  I2C_Reset(I2C1);RCM_ConfigI2CCLK(RCM_I2C1CLK_SYSCLK);i2cConfigStruct.ack = I2C_ACK_ENABLE;i2cConfigStruct.ackaddress = I2C_ACK_ADDRESS_7BIT;i2cConfigStruct.address1 = SLAVEADDR0;  //0xB0;i2cConfigStruct.analogfilter = I2C_ANALOG_FILTER_ENABLE;i2cConfigStruct.digitalfilter = I2C_DIGITAL_FILTER_0;i2cConfigStruct.mode = I2C_MODE_SMBUSDEVICE;i2cConfigStruct.timing = 0xB0420F13;   //100K 48M   //0x1042F013;I2C_Config(I2C1,&i2cConfigStruct);/** Enable the I2C1 Interrupt */ I2C_EnableInterrupt(I2C1,I2C_INT_RXIE|I2C_INT_ADDRIE|I2C_INT_STOPIE);/** NVIC configuration */   NVIC_EnableIRQRequest(I2C1_IRQn,1); /** slave configuration*///I2C_EnableSlaveByteControl(I2C1);//I2C_EnableReload(I2C1);//I2C_EnableStretchClock(I2C1);/** Enable I2Cx */    I2C_Enable(I2C1);
}

2.4 I2C主器件主动读写操作处理过程

//----------------------------------------------------------------------------------------------------------
// I2C_MasterReadWrite I2C主器件主动读写操作
// 参数:   uSlaveAdd 器件地址
// 参数:   uCommandCode    读写指令或寄存器
// 参数:   uCommandData    读写的数据
// 参数:   uReadWrite      读写操作 0:写 、1:读
//----------------------------------------------------------------------------------------------------------
uint16_t I2C_MasterReadWrite(uint8_t uSlaveAdd,uint8_t uCommandCode,uint16_t uCommandData,uint8_t uReadWrite)
{uint8_t Recev1[4] = {0,0,0,0};//uint8_t Recev2 = 0x00;uint8_t i = 0x00;uint16_t uiCounter1 = 0x00;uint16_t uiInputValue = 0x00;uint8_t uAutoEndLen = 0x03;uint8_t uAutoRecLen = 0x01;uint8_t uMode = 0x00; //0:写1Byte;1:读1Byte;2:写1Word;3:读1Wordfor(i=0;i<=40;i++){uI2CData[i]=0;uI2C2Data[i]=0;}if((uCommandCode&0x80)==0x80)uAutoRecLen =2;    //字节操作elseuAutoRecLen =1;if(uReadWrite==0){  //写if((uCommandCode&0x80)==0x80){ //双字节操作uAutoEndLen =4;uMode=2;    //写1Word}else{  //写1Byte;uMode=0;   //写1Byte}}else {    //读if((uCommandCode&0x80)==0x80){ //双字节操作uMode=3;    //读1Word}else{  //读1ByteuMode=1;   //读1Byte}}//---------------------------------------------------------------I2CTimeout = I2CT_LONG_TIMEOUT; while(I2C_ReadStatusFlag(I2C2,I2C_FLAG_BUSY) == SET)   //IF BUSY{I2C2Init();if((I2CTimeout--) == 0) return 0;}//---------------------------------------------------------------/** I2C Send Configuration*///I2C_HandlingTransfer(I2C2,uSlaveAdd,2,I2C_RELOAD_MODE_SOFTEND,I2C_GENERATE_START_WRITE);/** Disable I2C interrupt  *///I2C_DisableInterrupt(I2C2,I2C_INT_RXIE|I2C_INT_ADDRIE|I2C_INT_STOPIE);/** I2C Send Configuration*/I2C_HandlingTransfer(I2C2,uSlaveAdd,uAutoEndLen,I2C_RELOAD_MODE_AUTOEND,I2C_GENERATE_START_WRITE);//---------------------------------------------------------------I2C_TxData(I2C2,uSlaveAdd);    //发地址//---------------------------------------------------------------uiCounter1 = 0x00;//If Write OKwhile(I2C_ReadStatusFlag(I2C2,I2C_FLAG_TXCF) == RESET && uiCounter1<I2CT_LONG_TIMEOUT){uiCounter1++;}//---------------------------------------------------------------I2C_TxData(I2C2,uCommandCode);   //发需要读/写的寄存号//---------------------------------------------------------------uiCounter1 = 0x00;while(I2C_ReadStatusFlag(I2C2,I2C_FLAG_TXCF) == RESET && uiCounter1<I2CT_LONG_TIMEOUT){uiCounter1++; //超时检测}//---------------------------------------------------------------if(uReadWrite==0){    //写入if(uMode==0){ //1ByteI2C_TxData(I2C2,uCommandData&0xFF);  //发数据1Byte//---------------------------------------------------------------uiCounter1 = 0x00;while(I2C_ReadStatusFlag(I2C2,I2C_FLAG_TXCF) == RESET && uiCounter1<I2CT_LONG_TIMEOUT){uiCounter1++;   //超时检测}//---------------------------------------------------------------}else if(uMode==2){   //1WordI2C_TxData(I2C2,uCommandData&0xFF);  //发Low Byte//---------------------------------------------------------------uiCounter1 = 0x00;while(I2C_ReadStatusFlag(I2C2,I2C_FLAG_TXCF) == RESET && uiCounter1<I2CT_LONG_TIMEOUT){uiCounter1++;  //超时检测}//---------------------------------------------------------------I2C_TxData(I2C2,((uCommandData>>8)&0xFF));    //发High Byte//---------------------------------------------------------------uiCounter1 = 0x00;while(I2C_ReadStatusFlag(I2C2,I2C_FLAG_TXCF) == RESET && uiCounter1<I2CT_LONG_TIMEOUT){uiCounter1++; //超时检测}//---------------------------------------------------------------}}else{ //读数据I2C_TxData(I2C2,uSlaveAdd|0x01);   //发地址+读标置位//---------------------------------------------------------------uiCounter1 = 0x00;while(I2C_ReadStatusFlag(I2C2,I2C_FLAG_TXCF) == RESET && uiCounter1<I2CT_LONG_TIMEOUT){uiCounter1++;  //超时检测}//---------------------------------------------------------------I2C_HandlingTransfer(I2C2,uSlaveAdd,uAutoRecLen,I2C_RELOAD_MODE_SOFTEND,I2C_GENERATE_START_READ);//---------------------------------------------------------------for(i=0;i<uAutoRecLen;i++){uiCounter1 = 0x00;//If I2C_FLAG_RXBNE OKwhile(I2C_ReadStatusFlag(I2C2,I2C_FLAG_RXBNE) == RESET && uiCounter1<I2CT_LONG_TIMEOUT){uiCounter1++;    //超时检测}Recev1[i]=I2C_RxData(I2C2); //读数据}//---------------------------------------------------------------}//---------------------------------------------------------------// I2C2 Generate Stop signal//I2C_EnableGenerateStop(I2C2);//---------------------------------------------------------------uiCounter1 = 0x00;//If I2C_FLAG_STOP OKwhile(I2C_ReadStatusFlag(I2C2,I2C_FLAG_STOP) == RESET && uiCounter1<I2CT_LONG_TIMEOUT){uiCounter1++;    //超时检测}//---------------------------------------------------------------/** I2C Clear Stop Flag */I2C_ClearIntFlag(I2C2,I2C_INT_FLAG_STOP); I2C_ConfigNumberOfBytes(I2C2, 1);/** I2C Enable Interrupt *///I2C_EnableInterrupt(I2C2,I2C_INT_RXIE|I2C_INT_ADDRIE|I2C_INT_STOPIE);//---------------------------------------------------------------uiInputValue=Recev1[1]<<8|Recev1[0];return uiInputValue;}

2.5 从器件响应主器件而返回数据操作处理过程

//----------------------------------------------------------------------------------------------------------
// I2C_SlaveSendData I2C从器件响应主器件而返回数据操作
// 参数:   *i2c 从I2C
// 参数:   uCommandCode    读写指令或寄存器
// 参数:   uCommandData    读写的数据
// 参数:   uReadWrite      读写操作 0:写 、1:读
//----------------------------------------------------------------------------------------------------------
void I2C_SlaveSendData(I2C_T *i2c)
{uint16_t uiCounter1 = 0x00;if(uSlaveSendFlag==1){uSlaveSendFlag =0;if((uI2CData[1]&0x80)==0x80)uSlaveSendLen =2;elseuSlaveSendLen =1;//---------------------------------------------------------------//   Send Frist Byteswitch(uI2CData[1]){case 0x01:   //单字节0x01寄存器I2C_TxData(i2c,0x11);break;case 0x02:   //单字节0x02寄存器I2C_TxData(i2c,0x12);break;case 0x03:   //单字节0x03寄存器I2C_TxData(i2c,0x13);break;case 0x04:   //单字节0x04寄存器I2C_TxData(i2c,0x14);break;case 0x81:   //双字节0x81寄存器低字节I2C_TxData(i2c,0x81);break;case 0x82:    //双字节0x82寄存器低字节I2C_TxData(i2c,0x82);break;case 0x83:    //双字节0x83寄存器低字节I2C_TxData(i2c,0x83);break;case 0x84:    //双字节0x84寄存器低字节I2C_TxData(i2c,0x84);break;default:I2C_TxData(i2c,0xFF);break;}  //---------------------------------------------------------------uiCounter1 = 0x00;while(I2C_ReadStatusFlag(i2c,I2C_FLAG_TXCF) == RESET && uiCounter1<48000){uiCounter1++;  //超时检测}//---------------------------------------------------------------if((uI2CData[1]&0x80)==0x80){ // Send Second Byteswitch(uI2CData[1]){case 0x81:   //双字节0x81寄存器高字节I2C_TxData(i2c,0x91);break;case 0x82:    //双字节0x82寄存器高字节I2C_TxData(i2c,0x92);break;case 0x83:    //双字节0x83寄存器高字节I2C_TxData(i2c,0x93);break;case 0x84:    //双字节0x84寄存器高字节I2C_TxData(i2c,0x94);break;default:I2C_TxData(i2c,0xFF);break;}  //---------------------------------------------------------------uiCounter1 = 0x00;while(I2C_ReadStatusFlag(i2c,I2C_FLAG_TXCF) == RESET && uiCounter1<48000){uiCounter1++;  //超时检测}//---------------------------------------------------------------}I2C_EnableGenerateStop(i2c);   //发停止信号P}}

2.6 从I2C1的中断处理过程

/*!* @brief       I2C interrupt service routine   ** @param       None** @retval      None** @note        This function need to put into I2C1_IRQHandler() in apm32f0xx_int.c*/
void  I2C_Isr(void)
{uint8_t udata;static uint16_t uiDir=0;static uint8_t uAddMatchFlag=0;if(I2C_ReadIntFlag(I2C1,I2C_INT_FLAG_ADDR) == SET){I2C_ConfigNumberOfBytes(I2C1, 1);I2C_ClearIntFlag(I2C1,I2C_INT_FLAG_ADDR);uAddMatchFlag=1;    //地址匹配标志置1udata = (uint8_t)I2C_RxData(I2C1);uiDir= (udata&0x01);if(uiDir==1){   // I2C1: slave enters transmitter mode.//udata=0xB0;}else{ // I2C1: slave enters receiver mode.uI2CRxPos=0;}}else if(I2C_ReadStatusFlag(I2C1,I2C_FLAG_RXBNE) == SET && uAddMatchFlag==1){/** I2C_ConfigNumberOfBytes is necessary*/I2C_ConfigNumberOfBytes(I2C1, 1);udata = (uint8_t)I2C_RxData(I2C1);uI2CData[uI2CRxPos]=udata;uI2CRxPos++;uI2CRxPos%=40;if(uI2CRxPos==3 && uI2CData[0]==SLAVEADDR0 && (uI2CData[0]|0x01)==uI2CData[2]){  //对本机的读指令uSlaveSendFlag = 1;//I2C_TxData(I2C1,0xFF);printf("%s\r\n",&uI2CData[1]); }else if(uI2CRxPos>2 && uI2CData[0]==SLAVEADDR0){    //对本机的写指令if((uI2CData[1]&0x80)==0 && uI2CRxPos==3){ //1Byte//--------------------------------------//请将数据写入相应的1Byte寄存器//...//--------------------------------------I2C_EnableGenerateStop(I2C1);    //发停止信号P}else if((uI2CData[1]&0x80)==0x80 && uI2CRxPos==4){ //1Word//--------------------------------------//请将数据写入相应的1Word寄存器//...//--------------------------------------I2C_EnableGenerateStop(I2C1);    //发停止信号P}}}else if(I2C_ReadIntFlag(I2C1,I2C_INT_FLAG_STOP) == SET && uAddMatchFlag==1){I2C_ClearIntFlag(I2C1,I2C_INT_FLAG_STOP);uAddMatchFlag =0;if(uI2CRxPos>0){printf("%s\r\n",&uI2CData[1]);   //串口输出I2C1收来的数据}uI2CRxPos=0;}}

2.7 主I2C2的中断处理过程

/*!* @brief       I2C interrupt service routine   ** @param       None** @retval      None** @note        This function need to put into I2C1_IRQHandler() in apm32f0xx_int.c*/
void  I2C2_Isr(void)
{uint8_t udata;static uint8_t uAdd2MatchFlag=0;    static uint8_t uI2C2RxPos=0;if(I2C_ReadIntFlag(I2C2,I2C_INT_FLAG_ADDR) == SET){I2C_ConfigNumberOfBytes(I2C2, 1);I2C_ClearIntFlag(I2C2,I2C_INT_FLAG_ADDR);uAdd2MatchFlag =1;uI2C2RxPos=0;}else if(I2C_ReadStatusFlag(I2C2,I2C_FLAG_RXBNE) == SET){#if(1)/** I2C_ConfigNumberOfBytes is necessary*/I2C_ConfigNumberOfBytes(I2C2, 1);udata = (uint8_t)I2C_RxData(I2C2);uI2C2Data[uI2C2RxPos]=udata;uI2C2RxPos++;uI2C2RxPos%=40;if(uI2C2RxPos==uSlaveSendLen) {I2C_EnableGenerateStop(I2C2);}#endif}else if(I2C_ReadIntFlag(I2C2,I2C_INT_FLAG_STOP) == SET){I2C_ClearIntFlag(I2C2,I2C_INT_FLAG_STOP);uAdd2MatchFlag =0;if(uI2C2RxPos>0){printf("%s\r\n",uI2C2Data);   //串口输出I2C2收来的数据}uI2C2RxPos =0;}}

2.8 按键的中断处理过程

/*!* @brief       BUTTON_KEY interrupt service routine   ** @param       None** @retval      None** @note        This function need to put into EINT0_1_IRQHandler()*              in apm32f0xx_int.c*/void APM_MINI_PB_I2C_Isr()
{//uint8_t uDataTx[]="Hello master\r\n";if(EINT_ReadStatusFlag(EINT_LINE1)==SET){EINT_ClearStatusFlag(EINT_LINE1);if(uButtonDownFlag==0){uButtonDownFlag = 1;uButtonCounter++;uButtonCounter%=5;//按键I2C主器件向从器件读写数据uSlaveReadData=I2C_MasterReadWrite(SLAVEADDR0,(0x00|uButtonCounter),0x8899,0x00); //写单字节(测试指令)//uSlaveReadData=I2C_MasterReadWrite(SLAVEADDR0,(0x00|uButtonCounter),0x8899,0x01);    //读单字节(测试指令)//uSlaveReadData=I2C_MasterReadWrite(SLAVEADDR0,(0x80|uButtonCounter),0x8899,0x00);    //写双字节(测试指令)//uSlaveReadData=I2C_MasterReadWrite(SLAVEADDR0,(0x80|uButtonCounter),0x8899,0x01);    //读双字节(测试指令)}}}

2.9 主程序的处理过程

/*!* @brief       Main program** @param       None** @retval      None** @note       */
int main(void)
{//uint16_t j=0;SystemClock_PLL_Init();    //PLL 初始化,将系统时钟调整到48MHzAPM_MINI_LEDInit(LED3);   //指示灯的初始化APM_MINI_PBInit(BUTTON_KEY1,BUTTON_MODE_EINT); //按键Key1的端口初始化APM_MINI_COMInit(COM1);   //串口1的初始化I2C2Init();    //主I2C初始化I2CInit(); //从I2C初始化//I2C_DATATX("TX=%s  Code = %d\r\n","test 4321",1);while(1){ /** Press the BUTTON_KEY1, slave will send data tomaster along with information that showed in serial port*///APM_MINI_LEDToggle(LED3);if(GPIO_ReadInputBit(GPIOA,GPIO_PIN_1)==BIT_SET){  //防按键重复检测到uButtonDownFlag = 0;}I2C_SlaveSendData(I2C1);    //从I2C返回主器件要求的数据}
}

2.10 完整的源代码请下载

https://download.csdn.net/download/kingpower2018/87458548?spm=1001.2014.3001.5503
源代码下载

用极海MCU ARM M0的APM32F03x实现I2C的主从模式的SMBUS通信相关推荐

  1. 极海推出APM32A系列车规级MCU

    极海宣布推出具有高效CPU处理性能.增强型存储空间.以及丰富连接功能的APM32A系列车规级MCU,以有效满足汽车电子多样化通信与车身控制应用开发需求,可广泛应用于车身控制.安全系统.信息娱乐系统.动 ...

  2. 国鼎代理极海APM32F030x8系列MCU手持式激光测距仪应用方案

    国鼎代理极海推出的工业级通用型APM32F030x8系列MCU,基于Arm® Cortex®-M0+内核,集成度高.可靠性好.扩展控制功能强,可满足手持式激光测距仪蓝牙通信.功耗调整以及多样化的测量需 ...

  3. 新品发布 | 极海半导体工业级互联型APM32F107/F105系列MCU,拓展通信外设助力产品应用创新

    近日,极海半导体正式发布基于Arm® Cortex®-M3内核的工业级互联型APM32F107/F105系列MCU新品,凭借丰富的系统资源.易用的架构设计和出色的外设功能,可满足高性能.低功耗.传输连 ...

  4. MCU极海 APM32F103VET6 兼容替代 STM32F103VET6

    MCU极海 APM32F103VET6 兼容替代 STM32F103VET6 APM32F103VET6产品概述 APM32F103xDxE系列MCU,基于32位Arm® Cortex®-M3内核,最 ...

  5. 智能、精准、节能丨极海APM32F103RCT7 LED车灯应用方案

    常见的汽车车灯有前照灯.后组合灯.雾灯.门灯.阅读灯.日间行车灯.转向灯.制动灯.氛围灯等等.伴随汽车智能化发展,车灯从传统的照明工具.功能安全件向电子化.智能化转变,同时驱动车灯不断提升价值.LED ...

  6. 为光伏发电效率保驾护航丨极海APM32F407功率优化器应用方案

    近年来,分布式光伏市场表现异常活跃,如何在面积受限的情况下提升发电效率与安全性是开启分布式光伏发电实现差异化竞争的关键所在.在光伏发电系统中,当光照不均匀.被遮挡时,或者因光伏组件特性不一致时导致的电 ...

  7. 极海APM微控制器基于IAR开发环境搭建与工程调试配置方法

    极海APM微控制器基于IAR开发环境搭建与工程调试配置方法 ✨本篇主要针对基于IAR for ARM版本:V9.30.1环境搭建和工程调试配置过程进行介绍,当然也同样适用于基于ARM架构芯片的开发使用 ...

  8. 【极海APM32替代笔记】低功耗模式配置及配置汇总

    [极海APM32替代笔记]低功耗模式配置及配置汇总 文章总结:(后续更新以相关文章为准) [STM32笔记]低功耗模式.WFI命令等进入不了休眠的可能原因(系统定时器SysTick一直产生中断) [S ...

  9. 双模加持丨极海半导体GW3323智能蓝牙手环应用方案

    在健康观念深入人心及消费升级的双重影响下,智能可穿戴设备的市场需求持续增长,智能蓝牙手环便是其中热门方向之一.根据Canalys数据显示,2022年Q2全球可穿戴腕带的出货量达到4170万台,其中中国 ...

最新文章

  1. 多传感器信息融合算法总结
  2. 《Effective C#》某些地方实在是对不起Effective这个词(I)
  3. java 关闭另一个jvm_JVM安全退出(如何优雅的关闭java服务)
  4. linux QT 结束当前进程_Qt编写控件属性设计器7-串口采集
  5. python从html拿到数据,python - 使用BeautifulSoup和Python从HTML文件中提取数据 - 堆栈内存溢出...
  6. python map 函数使用
  7. 三层架构学习的困难_TCP/IP协议栈-之-三层交换技术
  8. GitHub:现代科学取名工具
  9. 缺少tlqcu_qcu1.conf文件
  10. 什么是计算机的用户名和密码,电脑用户名是什么意思
  11. 拥有“中国诺贝尔奖”的未来论坛,会告诉我们怎样的未来? | 未来论坛 2017...
  12. 【HDFS】HDFS文件块大小(重点)
  13. 关于Windows Paint的基础图层透明背景的操作说明
  14. 读书的方法摘录——张五常
  15. 中鑫吉鼎|你知道自己理财期间这四个更重要吗
  16. 一次500行SQL的优化
  17. PostgreSQL中的两阶段提交
  18. 还在用通风放味除甲醛呢?专家教你三个小妙招,帮你轻松除甲醛!
  19. 深入浅出Dcoker学习摘要
  20. 百度PM·Star高校互联网产品设计大赛 我的作品——百度日历

热门文章

  1. #问题求解与编程# 实验二 D 比赛排名预测
  2. JSS-22 DC220V【时间继电器】
  3. pubwin2009三秒钟快速破解无需开卡登录
  4. 使用Wi-Fi实现ESP32与手机网络助手进行TCP数据收发
  5. nodejs解析zip文件
  6. 事件聚合器 - Caliburn.Micro 文档系列
  7. STM32F0项目进阶之实时时钟DS1307
  8. 欧尼酱讲JVM(14)——堆
  9. notepad++安装包
  10. 西门子HMI设备与V20变频器如何实现通讯?