我拿到的開發(fā)板實(shí)際板載的MCU是GD32F310G8,QFN28pin封裝,基于ARM CORTEX M4內(nèi)核,主頻72MHz,芯片內(nèi)置64KB flash,8KB SRAM,兩路I2C外設(shè)。
本次試用目的是利用GD32F310的I2C0實(shí)現(xiàn)對HDC1080的初始化及讀取環(huán)境溫濕度,并利用UART口在電腦上顯示出來。
1、新建工程
①首先建立一個(gè)新的項(xiàng)目文件夾,并在此文件夾下建立對應(yīng)子文件夾,我建立的文件如下圖所示,這個(gè)依個(gè)人習(xí)慣會有不同:
② Document文件夾中存放對項(xiàng)目的說明文件readme.txt;將系統(tǒng)支持包中的GD32F3x0_Firmware_Library_V2.2.0/Firmware文件夾中的內(nèi)容復(fù)制到Libraries文件夾中;Listing/Output文件夾用于存放項(xiàng)目編譯時(shí)生成的目標(biāo)文件及l(fā)ist文件,在MDK的魔術(shù)棒中進(jìn)行設(shè)置路徑;users文件夾中存放main文件及我們自已寫的代碼;Project文件夾中存放MDK項(xiàng)目文件;
③打開MDK keil5,首先要先導(dǎo)入GD32F310G文件支持包。
④建立新的項(xiàng)目,選擇所使用的MCU,我們選擇GD32F330G8,如下圖所示
⑤新項(xiàng)目中建立如下文件組,并導(dǎo)入啟動文件和外設(shè)支持包。
⑥點(diǎn)擊魔術(shù)棒工具進(jìn)行項(xiàng)目設(shè)置。在C/C++選項(xiàng)中添加include文件路徑;
⑦點(diǎn)擊Debug選項(xiàng)進(jìn)行GDLink的設(shè)置,要選擇CMSIS_DAP Debugger,并將Reset and Run打勾。
⑧這樣整個(gè)項(xiàng)目的配置基本就結(jié)束了,可以在main.c文件中建立一個(gè)空循環(huán),編譯測試項(xiàng)目建立是否正確無誤。
2、硬件映射
硬件映射的目的是按目前的硬件連接建立.h文件,如下圖所示:
因此基于開發(fā)板I2C0采用的是PB6/PB7引腳,因?yàn)樾枰蛴∽x出的值,UART0使用的是PA9/PA10引腳。
3、編寫代碼
①UART0初始化和printf函數(shù)重定向:
void UART_TypeInit(void) { gpio_deinit(UART0_GPIO_PORT); usart_deinit(USART0); rcu_periph_clock_enable(UART0_GPIO_PORT_CLK); gpio_mode_set(UART0_GPIO_PORT,GPIO_MODE_AF,GPIO_PUPD_NONE,UART0_TX_PIN | UART0_RX_PIN); gpio_output_options_set(UART0_GPIO_PORT,GPIO_OTYPE_OD,GPIO_OSPEED_MAX,UART0_TX_PIN | UART0_RX_PIN); gpio_af_set(UART0_GPIO_PORT,GPIO_AF_1,UART0_TX_PIN | UART0_RX_PIN); rcu_periph_clock_enable(UART0_CLK); usart_baudrate_set(USART0,UART0_Baudrate); usart_parity_config(USART0,USART_PM_NONE); usart_word_length_set(USART0,USART_WL_8BIT); usart_stop_bit_set(USART0,USART_STB_1BIT); usart_enable(USART0); usart_transmit_config(USART0,USART_TRANSMIT_ENABLE); usart_receive_config(USART0,USART_RECEIVE_ENABLE); } /* retarget the C library printf function to the USART */ int fputc(int ch, FILE *f) { usart_data_transmit(USART0, (uint8_t)ch); while(RESET == usart_flag_get(USART0,USART_FLAG_TBE)); return ch; }
②I2C0外設(shè)初始化:
void I2C0_TypeInit(void) { gpio_deinit(I2C0_GPIO_PORT); i2c_deinit(I2C0); rcu_periph_clock_enable(I2C0_GPIO_PORT_CLK); gpio_mode_set(I2C0_GPIO_PORT,GPIO_MODE_AF,GPIO_PUPD_NONE,I2C0_SCL_PIN | I2C0_SDA_PIN); gpio_output_options_set(I2C0_GPIO_PORT,GPIO_OTYPE_OD,GPIO_OSPEED_MAX,I2C0_SCL_PIN | I2C0_SDA_PIN); gpio_af_set(I2C0_GPIO_PORT,GPIO_AF_1,I2C0_SCL_PIN | I2C0_SDA_PIN); rcu_periph_clock_enable(I2C0_CLK); i2c_clock_config(I2C0,I2C0_Frequence,I2C_DTCY_2); i2c_mode_addr_config(I2C0,I2C_I2CMODE_ENABLE,I2C_ADDFORMAT_7BITS,I2C0_OWN_Address); i2c_enable(I2C0); i2c_ack_config(I2C0,I2C_ACK_ENABLE); }
③讀寄存器操作:
void I2C0_Register_Read(uint8_t* B_buffer, uint8_t read_address,uint16_t number_of_byte) { /* wait until I2C bus is idle */ while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)); if(2 == number_of_byte){ i2c_ackpos_config(I2C0,I2C_ACKPOS_NEXT); } /* send a start condition to I2C bus */ i2c_start_on_bus(I2C0); /* wait until SBSEND bit is set */ while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)); /* send slave address to I2C bus */ i2c_master_addressing(I2C0, HDC1080_Addr, I2C_TRANSMITTER); /* wait until ADDSEND bit is set */ while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)); /* clear the ADDSEND bit */ i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND); /* wait until the transmit data buffer is empty */ while(SET != i2c_flag_get( I2C0 , I2C_FLAG_TBE)); /* enable I2C0*/ i2c_enable(I2C0); /* send the EEPROM's internal address to write to */ i2c_data_transmit(I2C0, read_address); /* wait until BTC bit is set */ while(!i2c_flag_get(I2C0, I2C_FLAG_BTC)); delay_1ms(20); /* send a start condition to I2C bus */ i2c_start_on_bus(I2C0); /* wait until SBSEND bit is set */ while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)); /* send slave address to I2C bus */ i2c_master_addressing(I2C0, HDC1080_Addr, I2C_RECEIVER); if(number_of_byte < 3){ /* disable acknowledge */ i2c_ack_config(I2C0,I2C_ACK_DISABLE); } /* wait until ADDSEND bit is set */ while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)); /* clear the ADDSEND bit */ i2c_flag_clear(I2C0,I2C_FLAG_ADDSEND); if(1 == number_of_byte){ /* send a stop condition to I2C bus */ i2c_stop_on_bus(I2C0); } /* while there is data to be read */ while(number_of_byte){ if(3 == number_of_byte){ /* wait until BTC bit is set */ while(!i2c_flag_get(I2C0, I2C_FLAG_BTC)); /* disable acknowledge */ i2c_ack_config(I2C0,I2C_ACK_DISABLE); } if(2 == number_of_byte){ /* wait until BTC bit is set */ while(!i2c_flag_get(I2C0, I2C_FLAG_BTC)); /* send a stop condition to I2C bus */ i2c_stop_on_bus(I2C0); } delay_1ms(1); /* wait until the RBNE bit is set and clear it */ if(i2c_flag_get(I2C0, I2C_FLAG_RBNE)){ /* read a byte from the EEPROM */ *B_buffer = i2c_data_receive(I2C0); /* point to the next location where the byte read will be saved */ B_buffer++; /* decrement the read bytes counter */ number_of_byte--; } } /* wait until the stop condition is finished */ while(I2C_CTL0(I2C0)&0x0200); /* enable acknowledge */ i2c_ack_config(I2C0, I2C_ACK_ENABLE); i2c_ackpos_config(I2C0, I2C_ACKPOS_CURRENT); }
④寫寄存器操作:
void I2C0_Byte_Write(uint8_t* P_buffer, uint8_t write_address) { uint8_t i; /* wait until I2C bus is idle */ while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)); /* send a start condition to I2C bus */ i2c_start_on_bus(I2C0); /* wait until SBSEND bit is set */ while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)); /* send slave address to I2C bus */ i2c_master_addressing(I2C0, HDC1080_Addr, I2C_TRANSMITTER); /* wait until ADDSEND bit is set */ while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)); /* clear the ADDSEND bit */ i2c_flag_clear(I2C0,I2C_FLAG_ADDSEND); /* wait until the transmit data buffer is empty */ while(SET != i2c_flag_get(I2C0, I2C_FLAG_TBE)); /* send the EEPROM's internal address to write to : only one byte address */ i2c_data_transmit(I2C0, write_address); /* wait until BTC bit is set */ while(!i2c_flag_get(I2C0, I2C_FLAG_BTC)); for(i=0;i<2;i++) { /* send the byte to be written */ i2c_data_transmit(I2C0, *(P_buffer+i)); /* wait until BTC bit is set */ while(!i2c_flag_get(I2C0, I2C_FLAG_TBE)); } /* send a stop condition to I2C bus */ i2c_stop_on_bus(I2C0); /* wait until the stop condition is finished */ while(I2C_CTL0(I2C0)&0x0200); }
⑤對HDC1080進(jìn)行初始化并讀取其ID:
void HDC1080_Init(void) { uint8_t IDBuffer[2]={0}; uint8_t InitSetup[2]={0x90,0x00}; uint32_t SID[3]={0},MID=0,DID=0; I2C0_Byte_Write(InitSetup,CONFIGURATION); delay_1ms(20); I2C0_Register_Read(IDBuffer,DEVICE_ID,2); DID = (((uint32_t)IDBuffer[0])<<8 | IDBuffer[1]); printf("The DeviceID is 0x%x\n\r",DID); I2C0_Register_Read(IDBuffer,MANUFACTURE_ID,2); MID = ((uint16_t) IDBuffer[0]<<8 | IDBuffer[1]); printf("The ManufactureID is 0x%x\n\r",MID); I2C0_Register_Read(IDBuffer,FIRST_SID,2); SID[0] = ((uint16_t) IDBuffer[0]<<8 | IDBuffer[1]); I2C0_Register_Read(IDBuffer,MID_SID,2); SID[1] = ((uint16_t) IDBuffer[0]<<8 | IDBuffer[1]); I2C0_Register_Read(IDBuffer,LAST_SID,2); SID[2] = ((uint16_t) IDBuffer[0]<<8 | IDBuffer[1]); printf("The First bytes of the serial ID of the part is 0x%x\n\r",SID[0]); printf("The MID bytes of the serial ID of the part is 0x%x\n\r",SID[1]); printf("The Last bytes of the serial ID of the part is 0x%x\n\r",SID[2]); printf("\n\r"); }
⑥讀取溫濕度值并轉(zhuǎn)換成十進(jìn)制顯示:
void readSensor(void) { //holds 2 bytes of data from I2C Line uint8_t Buffer_Byte[2]; //holds the total contents of the temp register uint16_t temp,hum; //holds the total contents of the humidity register double temperature=0,humidity=0 ; I2C0_Register_Read(Buffer_Byte,T_MEASUREMENT,2); temp = (((uint32_t)Buffer_Byte[0])<<8 | Buffer_Byte[1]); temperature = (double)(temp)/(65536)*165-40; printf("The temperature is %.2f\n\r",temperature); I2C0_Register_Read(Buffer_Byte,RH_MEASUREMENT,2); hum = (((uint32_t)Buffer_Byte[0])<<8 | Buffer_Byte[1]); humidity = (double)(hum)/(65536)*100; printf("The humidity is %.2f%%\n\r",humidity); }
⑦main函數(shù):
/*! \brief main function \param[in] none \param[out] none \retval none */ int main(void) { /* configure periphreal */ systick_Init(); LED_TypeInit(); // NVIC_config(); // KEY_EXTI_TypeInit(); UART_TypeInit(); I2C0_TypeInit(); printf("**********DEMO START**********\n\r"); printf("******************************\n\r"); HDC1080_Init(); while(1) { readSensor(); delay_1ms(1000); } }
4、編譯下載
①Build項(xiàng)目文件:
②沒有錯誤,直接下載到開發(fā)板中,可以打開串口看到讀出溫濕度每隔1S讀一次并打印出來,與環(huán)境溫度計(jì)比較取值還是比較準(zhǔn)確的。
5、試用總結(jié)
GD32F310G8芯片采用4x4 QFN28封裝,結(jié)構(gòu)可以設(shè)計(jì)相當(dāng)緊湊,軟件開發(fā)資源也是很豐富,雖然功能不算特別強(qiáng)大,但主流的外設(shè)基本都有囊括,在目前國產(chǎn)替代的大環(huán)境之下,應(yīng)用前景還是相當(dāng)廣泛的。
-
I2C
+關(guān)注
關(guān)注
28文章
1487瀏覽量
123740 -
uart
+關(guān)注
關(guān)注
22文章
1235瀏覽量
101387
發(fā)布評論請先 登錄
相關(guān)推薦
評論