zoukankan      html  css  js  c++  java
  • mpu6050

    今天有点时间,来说说MPU6050吧,MPU-6050为全球首例整合性6轴运动处理组件,整合了3轴陀螺仪、3轴加速器,并含可藉由第二个I2C端口连接其他厂牌之加速器、磁力传感器、或其他传感器的数位运动处理(DMP: Digital Motion Processor)硬件加速引擎,由主要I2C端口以单一数据流的形式,向应用端输出完整的9轴融合演算技术InvenSense的运动处理资料库,可处理运动感测的复杂数据,降低了运动处理运算对操作系统的负荷,并为应用开发提供架构化的API。其与MCU通信是通过I2C,今天是用STM32F401进行读取MPU6050的数据,MPU6050模块的电源我是用的3.3V,另外SCL和SDA两个脚分别接一个3.3K或2K的上拉电阻,先写好底层驱动I2C(由于STM32的硬件I2C不太稳定,此次用的是软件仿真I2C)

    #include "i2c.h" #define  I2C_Direction_Transmitter      ((uint8_t)0x00) #define  I2C_Direction_Receiver         ((uint8_t)0x01)

    #define SCL_H         GPIOB->BSRRL = GPIO_Pin_6 /* GPIO_SetBits(GPIOB , GPIO_Pin_6)   */ #define SCL_L         GPIOB->BSRRH  = GPIO_Pin_6 /* GPIO_ResetBits(GPIOB , GPIO_Pin_6) */

    #define SDA_H         GPIOB->BSRRL = GPIO_Pin_7 /* GPIO_SetBits(GPIOB , GPIO_Pin_7)   */ #define SDA_L         GPIOB->BSRRH  = GPIO_Pin_7 /* GPIO_ResetBits(GPIOB , GPIO_Pin_7) */

    #define SCL_read      GPIOB->IDR  & GPIO_Pin_6 /* GPIO_ReadInputDataBit(GPIOB , GPIO_Pin_6) */ #define SDA_read      GPIOB->IDR  & GPIO_Pin_7 /* GPIO_ReadInputDataBit(GPIOB , GPIO_Pin_7) */

    static void I2C_delay(void) {     volatile int i = 7;     while (i)         i--; }

    static bool I2C_Start(void) {     SDA_H;     SCL_H;     I2C_delay();     if (!SDA_read)         return false;     SDA_L;     I2C_delay();     if (SDA_read)         return false;     SDA_L;     I2C_delay();     return true; }

    static void I2C_Stop(void) {     SCL_L;     I2C_delay();     SDA_L;     I2C_delay();     SCL_H;     I2C_delay();     SDA_H;     I2C_delay(); }

    static void I2C_Ack(void) {     SCL_L;     I2C_delay();     SDA_L;     I2C_delay();     SCL_H;     I2C_delay();     SCL_L;     I2C_delay(); }

    static void I2C_NoAck(void) {     SCL_L;     I2C_delay();     SDA_H;     I2C_delay();     SCL_H;     I2C_delay();     SCL_L;     I2C_delay(); }

    static bool I2C_WaitAck(void) {     SCL_L;     I2C_delay();     SDA_H;     I2C_delay();     SCL_H;     I2C_delay();     if (SDA_read) {         SCL_L;         return false;     }     SCL_L;     return true; }

    static void I2C_SendByte(uint8_t byte) {     uint8_t i = 8;     while (i--) {         SCL_L;         I2C_delay();         if (byte & 0x80)             SDA_H;         else             SDA_L;         byte <<= 1;         I2C_delay();         SCL_H;         I2C_delay();     }     SCL_L; }

    static uint8_t I2C_ReceiveByte(void) {     uint8_t i = 8;     uint8_t byte = 0;

        SDA_H;     while (i--)   {         byte <<= 1;         SCL_L;         I2C_delay();         SCL_H;         I2C_delay();         if (SDA_read)    {             byte |= 0x01;         }     }     SCL_L;     return byte; }

    void i2cInit(void) {     GPIO_InitTypeDef gpio;     RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOB, ENABLE);

        gpio.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;     gpio.GPIO_Speed = GPIO_Speed_2MHz;     gpio.GPIO_Mode=GPIO_Mode_OUT;   gpio.GPIO_OType= GPIO_OType_OD;   gpio.GPIO_PuPd=GPIO_PuPd_UP;        GPIO_Init(GPIOB, &gpio); }

    bool i2cWriteBuffer(uint8_t addr, uint8_t reg, uint8_t len, uint8_t * data)    //µÚÒ»¸ö²ÎÊýÊÇÆ÷¼þµØÖ· reg±íʾҪ¶ÁÈ¡µÃÊý¾ÝµÄ¼Ä´æÆ÷µØÖ· lenÊÇÊý¾Ý³¤¶È  *dataÊÇ´æ´¢¶Á³öÊý¾ÝµÄÖ¸Õë {     int i;     if (!I2C_Start())         return false;     I2C_SendByte(addr << 1 | I2C_Direction_Transmitter);     // ×îºóһλΪ·¢ËÍ»òÕß½ÓÊÕµÄÑ¡Ôñ±ê־λ     if (!I2C_WaitAck()) {         I2C_Stop();         return false;     }     I2C_SendByte(reg);     I2C_WaitAck();     for (i = 0; i < len; i++) {         I2C_SendByte(data[i]);         if (!I2C_WaitAck()) {             I2C_Stop();             return false;         }     }     I2C_Stop();     return true; }

    bool i2cWrite(uint8_t addr, uint8_t reg, uint8_t data) {     if (!I2C_Start())         return false;     I2C_SendByte(addr << 1 | I2C_Direction_Transmitter);     if (!I2C_WaitAck()) {         I2C_Stop();         return false;     }     I2C_SendByte(reg);     I2C_WaitAck();     I2C_SendByte(data);     I2C_WaitAck();     I2C_Stop();     return true; }

    bool i2cRead(uint8_t addr, uint8_t reg, uint8_t len, uint8_t* buf) {     if (!I2C_Start())         return false;     I2C_SendByte(addr << 1 | I2C_Direction_Transmitter);     if (!I2C_WaitAck()) {         I2C_Stop();         return false;     }     while (len)         //½«len³¤¶ÈµÄÕâô¶à×ֽڷŵ½*bufÀï  {     I2C_SendByte(reg);     I2C_WaitAck();     I2C_Start();     I2C_SendByte(addr << 1 | I2C_Direction_Receiver);     I2C_WaitAck();

            *buf = I2C_ReceiveByte();         if (len == 1)             I2C_NoAck();         else             I2C_Ack();         buf++;         len--;         reg++;     }     I2C_Stop();     return true; }

    uint16_t i2cGetErrorCounter(void) {     // TODO maybe fix this, but since this is test code, doesn't matter.     return 0; }

    u8 i2cRead_Reg(uint8_t addr, uint8_t reg) {  u8 a;     if (!I2C_Start())         return false;     I2C_SendByte(addr << 1 | I2C_Direction_Transmitter);     if (!I2C_WaitAck()) {         I2C_Stop();         return false;     }     I2C_SendByte(reg);     I2C_WaitAck();     I2C_Start();     I2C_SendByte(addr << 1 | I2C_Direction_Receiver);     I2C_WaitAck();     a = I2C_ReceiveByte();     I2C_NoAck();     I2C_Stop();     return a; }

    运用MPU6050得根据其寄存器手册来写代码,芯片的默认地址为0X68,下面是MPU的代码:

    uint8_t  mpu6050_buffer[14];      S_INT16_XYZ  GYRO_OFFSET,ACC_OFFSET;     u8 GYRO_OFFSET_OK = 1;  u8 ACC_OFFSET_OK = 1; S_INT16_XYZ  MPU6050_ACC_LAST,MPU6050_GYRO_LAST;   /**************************ʵÏÖº¯Êý******************************************** //½«iic¶ÁÈ¡µ½µÃÊý¾Ý·Ö²ð,·ÅÈëÏàÓ¦¼Ä´æÆ÷    ¼ÓËٶȺͽÇËÙ¶È·Ö±ð¶ÁÈ¡200¸öÈ»ºóȡƽ¾ùÖµ×÷Ϊ³õʼÎó²î  Ëã³öÎó²îºó¾Í²»ÔÙÔËÐмÆËãÎó²îµÄ²¿·Ö *******************************************************************************/ void MPU6050_Dataanl(void)        //ÿִÐÐÒ»´Î¶Áȡһ×éÊý¾Ý   µÚÒ»¸ö200´ÎºóËãÒ»´Îƽ¾ùÖµ×÷ΪÁãÆ®Ö®ºó¾Í²»×Ô¶¯ËãÁãÆ®ÁË {  MPU6050_ACC_LAST.X=((((int16_t)mpu6050_buffer[0]) << 8) | mpu6050_buffer[1]) - ACC_OFFSET.X;   //¼õÈ¥µÄÁãÆ®ÊǵÚÒ»¸ö200msÄÚËã³öµÄ  MPU6050_ACC_LAST.Y=((((int16_t)mpu6050_buffer[2]) << 8) | mpu6050_buffer[3]) - ACC_OFFSET.Y;  MPU6050_ACC_LAST.Z=((((int16_t)mpu6050_buffer[4]) << 8) | mpu6050_buffer[5]) - ACC_OFFSET.Z;  //Ìø¹ýζÈADC  MPU6050_GYRO_LAST.X=((((int16_t)mpu6050_buffer[8]) << 8) | mpu6050_buffer[9]) - GYRO_OFFSET.X;  MPU6050_GYRO_LAST.Y=((((int16_t)mpu6050_buffer[10]) << 8) | mpu6050_buffer[11]) - GYRO_OFFSET.Y;  MPU6050_GYRO_LAST.Z=((((int16_t)mpu6050_buffer[12]) << 8) | mpu6050_buffer[13]) - GYRO_OFFSET.Z;   // if((MPU6050_ACC_LAST.X/8192.0>1.5)||(MPU6050_ACC_LAST.X/8192.0<-1.5))  MPU6050_ACC_LAST.X=0; // if((MPU6050_ACC_LAST.Y/8192.0>1.5)||(MPU6050_ACC_LAST.Y/8192.0<-1.5))  MPU6050_ACC_LAST.Y=0; // if((MPU6050_ACC_LAST.Z/8192.0>1.5)||(MPU6050_ACC_LAST.Z/8192.0<-1.5))  MPU6050_ACC_LAST.Z=0;

     if(!GYRO_OFFSET_OK)  {   static int32_t tempgx=0,tempgy=0,tempgz=0;   static uint8_t cnt_g=0;  // LED1_ON;   if(cnt_g==0)   {    GYRO_OFFSET.X=0;    GYRO_OFFSET.Y=0;    GYRO_OFFSET.Z=0;    tempgx = 0;    tempgy = 0;    tempgz = 0;    cnt_g = 1;    return;   }   tempgx+= MPU6050_GYRO_LAST.X;   tempgy+= MPU6050_GYRO_LAST.Y;   tempgz+= MPU6050_GYRO_LAST.Z;   if(cnt_g==200)   {    GYRO_OFFSET.X=tempgx/cnt_g;    GYRO_OFFSET.Y=tempgy/cnt_g;    GYRO_OFFSET.Z=tempgz/cnt_g;    cnt_g = 0;    GYRO_OFFSET_OK = 1;   // EE_SAVE_GYRO_OFFSET();//±£´æÊý¾Ý    return;   }   cnt_g++;  }  if(!ACC_OFFSET_OK)  {   static int32_t tempax=0,tempay=0,tempaz=0;   static uint8_t cnt_a=0; //  LED1_ON;   if(cnt_a==0)   {    ACC_OFFSET.X = 0;    ACC_OFFSET.Y = 0;    ACC_OFFSET.Z = 0;    tempax = 0;    tempay = 0;    tempaz = 0;    cnt_a = 1;    return;   }   tempax+= MPU6050_ACC_LAST.X;   tempay+= MPU6050_ACC_LAST.Y;  // tempaz+= MPU6050_ACC_LAST.Z;   if(cnt_a==200)   {    ACC_OFFSET.X=tempax/cnt_a;    ACC_OFFSET.Y=tempay/cnt_a;    ACC_OFFSET.Z=tempaz/cnt_a;    cnt_a = 0;    ACC_OFFSET_OK = 1;  //  EE_SAVE_ACC_OFFSET();//±£´æÊý¾Ý    return;   }   cnt_a++;    } }

    /**************************ʵÏÖº¯Êý******************************************** //½«iic¶ÁÈ¡µ½µÃÊý¾Ý·Ö²ð,·ÅÈëÏàÓ¦¼Ä´æÆ÷,¸üÐÂMPU6050_Last *******************************************************************************/ void MPU6050_READ(void)       { // u8 i;  //i2cRead(devAddr,MPU6050_RA_ACCEL_XOUT_H,14,mpu6050_buffer);  mpu6050_buffer[0]=i2cRead_Reg(devAddr,  MPU6050_RA_ACCEL_XOUT_H);  mpu6050_buffer[1]=i2cRead_Reg(devAddr,  MPU6050_RA_ACCEL_XOUT_L);

     mpu6050_buffer[2]=i2cRead_Reg(devAddr,  MPU6050_RA_ACCEL_YOUT_H);  mpu6050_buffer[3]=i2cRead_Reg(devAddr,  MPU6050_RA_ACCEL_YOUT_L);

     mpu6050_buffer[4]=i2cRead_Reg(devAddr,  MPU6050_RA_ACCEL_ZOUT_H);  mpu6050_buffer[5]=i2cRead_Reg(devAddr,  MPU6050_RA_ACCEL_XOUT_L);

     mpu6050_buffer[6]=i2cRead_Reg(devAddr,  MPU6050_RA_TEMP_OUT_H);  mpu6050_buffer[7]=i2cRead_Reg(devAddr,  MPU6050_RA_TEMP_OUT_L);

     mpu6050_buffer[8]=i2cRead_Reg(devAddr,  MPU6050_RA_GYRO_XOUT_H);  mpu6050_buffer[9]=i2cRead_Reg(devAddr,  MPU6050_RA_GYRO_XOUT_L);

     mpu6050_buffer[10]=i2cRead_Reg(devAddr,  MPU6050_RA_GYRO_YOUT_H);  mpu6050_buffer[11]=i2cRead_Reg(devAddr,  MPU6050_RA_GYRO_YOUT_L);

     mpu6050_buffer[12]=i2cRead_Reg(devAddr,  MPU6050_RA_GYRO_ZOUT_H);  mpu6050_buffer[13]=i2cRead_Reg(devAddr,  MPU6050_RA_GYRO_ZOUT_L);

    }

    /**************************ʵÏÖº¯Êý******************************************** *º¯ÊýÔ­ÐÍ:  u8 IICwriteBit(u8 dev, u8 reg, u8 bitNum, u8 data) *¹¦¡¡¡¡ÄÜ:     ¶Á ÐÞ¸Ä Ð´ Ö¸¶¨É豸 Ö¸¶¨¼Ä´æÆ÷Ò»¸ö×Ö½Ú ÖеÄ1¸öλ ÊäÈë dev  Ä¿±êÉ豸µØÖ· reg    ¼Ä´æÆ÷µØÖ· bitNum  ÒªÐÞ¸ÄÄ¿±ê×Ö½ÚµÄbitNumλ data  Ϊ0 ʱ£¬Ä¿±ê뽫±»Çå0 ·ñÔò½«±»ÖÃλ ·µ»Ø   ³É¹¦ Ϊ1 ʧ°ÜΪ0 *******************************************************************************/ void IICwriteBit(u8 dev, u8 reg, u8 bitNum, u8 data){  u8 b;  i2cRead(dev, reg, 1, &b);  b = (data != 0) ? (b | (1 << bitNum)) : (b & ~(1 << bitNum));  i2cWrite(dev, reg, b); } /**************************ʵÏÖº¯Êý******************************************** *º¯ÊýÔ­ÐÍ:  u8 IICwriteBits(u8 dev,u8 reg,u8 bitStart,u8 length,u8 data) *¹¦¡¡¡¡ÄÜ:     ¶Á ÐÞ¸Ä Ð´ Ö¸¶¨É豸 Ö¸¶¨¼Ä´æÆ÷Ò»¸ö×Ö½Ú ÖеĶà¸öλ ÊäÈë dev  Ä¿±êÉ豸µØÖ· reg    ¼Ä´æÆ÷µØÖ· bitStart  Ä¿±ê×Ö½ÚµÄÆðʼλ length   볤¶È data    ´æ·Å¸Ä±äÄ¿±ê×Ö½ÚλµÄÖµ ·µ»Ø   ³É¹¦ Ϊ1 ʧ°ÜΪ0 *******************************************************************************/ void IICwriteBits(u8 dev,u8 reg,u8 bitStart,u8 length,u8 data) {    u8 b,mask;  i2cRead(dev, reg, 1, &b);   mask = (0xFF << (bitStart + 1)) | 0xFF >> ((8 - bitStart) + length - 1);  data <<= (8 - length);  data >>= (7 - bitStart);  b &= mask;  b |= data;  i2cWrite(dev, reg, b); } /**************************ʵÏÖº¯Êý******************************************** *º¯ÊýÔ­ÐÍ:  void MPU6050_setClockSource(uint8_t source) *¹¦¡¡¡¡ÄÜ:     ÉèÖà MPU6050 µÄʱÖÓÔ´ * CLK_SEL | Clock Source * --------+-------------------------------------- * 0       | Internal oscillator * 1       | PLL with X Gyro reference * 2       | PLL with Y Gyro reference * 3       | PLL with Z Gyro reference * 4       | PLL with external 32.768kHz reference * 5       | PLL with external 19.2MHz reference * 6       | Reserved * 7       | Stops the clock and keeps the timing generator in reset *******************************************************************************/ void MPU6050_setClockSource(uint8_t source){  IICwriteBits(devAddr, MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_CLKSEL_BIT, MPU6050_PWR1_CLKSEL_LENGTH, source);   } /** Set full-scale gyroscope range. * @param range New full-scale gyroscope range value * @see getFullScaleRange() * @see MPU6050_GYRO_FS_250 * @see MPU6050_RA_GYRO_CONFIG * @see MPU6050_GCONFIG_FS_SEL_BIT * @see MPU6050_GCONFIG_FS_SEL_LENGTH */ void MPU6050_setFullScaleGyroRange(uint8_t range) {  IICwriteBits(devAddr, MPU6050_RA_GYRO_CONFIG, MPU6050_GCONFIG_FS_SEL_BIT, MPU6050_GCONFIG_FS_SEL_LENGTH, range); }

    /**************************ʵÏÖº¯Êý******************************************** *º¯ÊýÔ­ÐÍ:  void MPU6050_setFullScaleAccelRange(uint8_t range) *¹¦¡¡¡¡ÄÜ:     ÉèÖà MPU6050 ¼ÓËٶȼƵÄ×î´óÁ¿³Ì *******************************************************************************/ void MPU6050_setFullScaleAccelRange(uint8_t range) {  IICwriteBits(devAddr, MPU6050_RA_ACCEL_CONFIG, MPU6050_ACONFIG_AFS_SEL_BIT, MPU6050_ACONFIG_AFS_SEL_LENGTH, range); } /**************************ʵÏÖº¯Êý******************************************** *º¯ÊýÔ­ÐÍ:  void MPU6050_setSleepEnabled(uint8_t enabled) *¹¦¡¡¡¡ÄÜ:     ÉèÖà MPU6050 ÊÇ·ñ½øÈë˯Ãßģʽ enabled =1   ˯¾õ enabled =0   ¹¤×÷ *******************************************************************************/ void MPU6050_setSleepEnabled(uint8_t enabled) {  IICwriteBit(devAddr, MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_SLEEP_BIT, enabled); }

    /**************************ʵÏÖº¯Êý******************************************** *º¯ÊýÔ­ÐÍ:  void MPU6050_setI2CMasterModeEnabled(uint8_t enabled) *¹¦¡¡¡¡ÄÜ:     ÉèÖà MPU6050 ÊÇ·ñΪAUX I2CÏßµÄÖ÷»ú *******************************************************************************/ void MPU6050_setI2CMasterModeEnabled(uint8_t enabled) {  IICwriteBit(devAddr, MPU6050_RA_USER_CTRL, MPU6050_USERCTRL_I2C_MST_EN_BIT, enabled); }

    /**************************ʵÏÖº¯Êý******************************************** *º¯ÊýÔ­ÐÍ:  void MPU6050_setI2CBypassEnabled(uint8_t enabled) *¹¦¡¡¡¡ÄÜ:     ÉèÖà MPU6050 ÊÇ·ñΪAUX I2CÏßµÄÖ÷»ú *******************************************************************************/ void MPU6050_setI2CBypassEnabled(uint8_t enabled) {  IICwriteBit(devAddr, MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_I2C_BYPASS_EN_BIT, enabled); }

    void MPU6050_setDLPF(uint8_t mode) {  IICwriteBits(devAddr, MPU6050_RA_CONFIG, MPU6050_CFG_DLPF_CFG_BIT, MPU6050_CFG_DLPF_CFG_LENGTH, mode); } /**************************ʵÏÖº¯Êý******************************************** *º¯ÊýÔ­ÐÍ:  void MPU6050_initialize(void) *¹¦¡¡¡¡ÄÜ:     ³õʼ»¯  MPU6050 ÒÔ½øÈë¿ÉÓÃ״̬¡£ *******************************************************************************/ u8 MPU6050_INIT(void) { //  I2C2_Write_1Byte(0xd0,0x19,0x07);//1khz //  I2C2_Write_1Byte(0xd0,0x1a,0x03);//44hzÂ˲¨ //  I2C2_Write_1Byte(0xd0,0x1b,0x00);//gyro 250du/s //  I2C2_Write_1Byte(0xd0,0x1c,0x08);//acc +-4g //  I2C2_Write_1Byte(0xd0,0x24,13);//400khz //  I2C2_Write_1Byte(0xd0,0x6a,0x00);//mst_en=0 //  I2C2_Write_1Byte(0xd0,0x6b,0x00);//sleep=0  MPU6050_REST();  delay_ms(10);  MPU6050_REST();  MPU6050_setClockSource(MPU6050_CLOCK_PLL_XGYRO); //ÉèÖÃʱÖÓ  0x6b   0x01  delay_ms(5);  MPU6050_setFullScaleGyroRange(MPU6050_GYRO_FS_2000);//ÍÓÂÝÒÇ×î´óÁ¿³Ì +-2000¶ÈÿÃë  delay_ms(5);  MPU6050_setFullScaleAccelRange(MPU6050_ACCEL_FS_4); //¼ÓËٶȶÈ×î´óÁ¿³Ì +-4G  delay_ms(5);  MPU6050_setDLPF(MPU6050_DLPF_BW_42);  delay_ms(5);  MPU6050_setSleepEnabled(0); //½øÈ빤×÷״̬  delay_ms(5);  MPU6050_setI2CMasterModeEnabled(0);  //²»ÈÃMPU6050 ¿ØÖÆAUXI2C  delay_ms(5);  MPU6050_setI2CBypassEnabled(1);  //Ö÷¿ØÖÆÆ÷µÄI2CÓë MPU6050µÄAUXI2C Ö±Í¨¡£¿ØÖÆÆ÷¿ÉÒÔÖ±½Ó·ÃÎÊHMC5883L  delay_ms(5);  return 0;  // //ÅäÖÃMPU6050 µÄÖжÏģʽ ºÍÖÐ¶ÏµçÆ½Ä£Ê½  // IICwriteBit(devAddr, MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_INT_LEVEL_BIT, 0);  // IICwriteBit(devAddr, MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_INT_OPEN_BIT, 0);  // IICwriteBit(devAddr, MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_LATCH_INT_EN_BIT, 1);  // IICwriteBit(devAddr, MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_INT_RD_CLEAR_BIT, 1);  // //¿ªÊý¾Ýת»»Íê³ÉÖÐ¶Ï  //    IICwriteBit(devAddr, MPU6050_RA_INT_ENABLE, MPU6050_INTERRUPT_DATA_RDY_BIT, 1); }

    void MPU6050_REST(void) {      IICwriteBit(devAddr,MPU6050_RA_PWR_MGMT_1,7,1); }

    下面就将数据通过串口1打印出来:  for(a=0;a<14;a++)
      {
       printf("mpu6050_buffer[%d] is %d   ",a ,mpu6050_buffer[a]);
      delay_ms(10);
      }

    小弟也是刚刚玩,希望各位有兴趣的可以交流,欢迎大家指正!谢谢
  • 相关阅读:
    为什么 PCB 生产时推荐出 Gerber 给工厂?
    Fedora Redhat Centos 有什么区别和关系?
    【KiCad】 如何给元件给元件的管脚加上划线?
    MCU ADC 进入 PD 模式后出现错误的值?
    FastAdmin 生产环境升级注意
    EMC EMI 自行评估记录
    如何让你的 KiCad 在缩放时不眩晕?
    KiCad 5.1.0 正式版终于发布
    一次单片机 SFR 页引发的“事故”
    java基础之集合
  • 原文地址:https://www.cnblogs.com/victoryichun/p/3933067.html
Copyright © 2011-2022 走看看