changweilin

  • 2024-03-31
  • 发表了主题帖: HC32F4A0开发板环境适应性试验

    HC32F4A0开发板环境适应性试验 1概述 1.1开发板简述         HC32F4A0系列支持宽电压范围(1.8~3.6V),宽温度范围(-40~+105℃)和各种低功耗模式。支持低功耗模式的快速唤醒,STOP模式唤醒最快至2μs,Power Down 模式唤醒最快至25μs。该芯片的温度范围满足(-40℃~+85℃)的工业级温度范围。 1.2试验流程         将开发板至于环境试验箱内部,设定温度为-40℃,此时开发板处于未通电状态,到温后保温两小时,进行冷启动,验证开发板是否工作正常;然后将试验箱温度设置为+70℃开始升温,开发板全程处于工作状态,到温后保温一小时,观察整个过程中开发板工作过程有无异常;设备连接方式如图1所示。 图1 设备连接示意图 1.3测试设备         本次测试所用设备如表1所示,设备实物图连接图如图3所示: 测试设备 单位 数量 EV_F4A0_LQ176_REV1.0开发板 块 壹 ARM仿真器 个 壹 5V电源适配器 个 壹 ZLG USBCANFD-200U 个 壹 爱斯佩克ESPEC EG-02KA环境试验箱 台 壹 表1 测试设备 2试验方法         将开发板连接信号线放入纸盒中防止开发板和环境试验箱中的金属铁架接触造成短路,将带屏蔽层的双绞线连接到开发板的插座上,通过试验箱侧面的孔洞引出,连接电源线打开开发板上的船型开关,通过外部控制开发板的通断如图2所示,电缆连接示意图如图3所示,试验所用试验箱为爱斯佩克ESPEC EG-02KA环境试验箱如图4所示。 图2 开发板连接示意图 图3 电缆连接示意图 图5 环境试验箱 3试验过程 3.1负温         设定温度为-40℃如图5所示;保温两小时。 图5  -40℃ 3.2正温         负温到温后两小时完成测试后设定为+70℃如图6所示。 图6  +70℃ 4试验结果         开发板处于负温下两小时后,冷启动正常,CAN回传数据正常,但通过视窗观察屏幕不亮,查阅屏幕资料发现屏幕工作温度为-20~70℃,因此初步判断为屏幕在-40℃环境下无法工作;转正温过程中CAN回传数据正常,屏幕在-13.7℃时恢复正常显示,+70℃到温后两小时内CAN数据回传正常,屏幕正常点亮。 5试验结论         该芯片在-40~70℃的温度范围内CAN通讯工作正常,符合手册所描述的宽温度范围,因测试设备限制无法对芯片进行全面的环境适应性测试,测试结果仅供参考,因个人试验无法保证试验过程的科学性、完善性和严谨性、因此该试验结果无法作为环境适应性的佐证,测试结果仅适用于该文章,对于测试结果的使用、使用所产生的直接或间接损失及一切法律后果,本人不承担任何经济和法律责任;若要进行芯片选型及成品设备环境适应性测试时应参考相关国标及企标,制订完整的环境适应性试验大纲,交予有相关资质的专业测试机构进行试验,并出具相关报告后方可进行。

  • 2024-03-30
  • 发表了主题帖: HC32F4A0开发板DAC信号发生测试

    HC32F4A0开发板DAC信号发生测试 1概述 1.1开发板接口         HC32F4A0搭载了两个12位的数字-模拟电压转换器单元DAC1和DAC2。每个DAC单元包含两个D/A转换通道,可以独立转换也可以通过转换数据的同步更新实现同步转换。每个转换通道配有一个输出放大器,可以在没有外部运放时直接驱动外部负载。独立管脚输入参考电压VREFH和VREFL可用来提高转换精度。 参考官方提供的例程,计划产生正弦波、方波、锯齿波、三角波四种波形,使用按键K1 ~ K5来控制波形的产生和关闭。 1.2开发板原理图         DAC外围电路和引脚分配如图1、2所示。 图1 DAC外围电路示意图 图2 引脚分配图 1.3测试设备         本次测试所用设备如表1所示,设备实物图连接图如图3所示: 测试设备 单位 数量 EV_F4A0_LQ176_REV1.0开发板 块 壹 ARM仿真器 个 壹 5V电源适配器 个 壹 RIGOL DHO804示波器 台 壹 表1 测试设备 图3 开发板实物连接图 2代码编写 方波产生函数 static void Pulse_Init(uint32_t pPulseTable[], uint32_t u32count) { uint32_t i; float32_t pulse; for (i = 0U; i < u32count; i++) { if(i<=u32count/2-1) pulse=u32count; else pulse=0; #if (DAC_DATA_ALIGN == DAC_DATA_ALIGN_LEFT) { pPulseTable[i] = (uint32_t)pulse << 9; } #else { pSinTable[i] = (uint32_t)fSin; } #endif } }   锯齿波产生函数 static void Sawtooth_Init(uint32_t pSawTable[], uint32_t u32count) { uint32_t i; float32_t sawtooth; for (i = 0U; i < u32count; i++) { sawtooth=i; #if (DAC_DATA_ALIGN == DAC_DATA_ALIGN_LEFT) { pSawTable[i] = (uint32_t)sawtooth << 9; } #else { pSinTable[i] = (uint32_t)fSin; } #endif } }   三角波产生函数 static void Triangle_Init(uint32_t pTriangleTable[], uint32_t u32count) { uint32_t i; uint32_t j=0; float32_t triangle; for (i = 0U; i < u32count; i++) { if(i<=u32count/2-1) j=j+1; else j=j-1; triangle=j; #if (DAC_DATA_ALIGN == DAC_DATA_ALIGN_LEFT) { pTriangleTable[i] = (uint32_t)triangle*2 << 9; } #else { pSinTable[i] = (uint32_t)fSin; } #endif } } 主函数 int32_t main(void) { uint16_t u16OutputCnt = 0U; en_key_event_t enEvent; uint8_t u8IsConversionStart = 0U; uint32_t flag=0U; LL_PERIPH_WE(LL_PERIPH_GPIO | LL_PERIPH_FCG | LL_PERIPH_PWC_CLK_RMU | \ LL_PERIPH_EFM | LL_PERIPH_SRAM); BSP_CLK_Init(); BSP_IO_Init(); BSP_LED_Init(); BSP_KEY_Init(); /* Init MAU for generating sine data*/ MAU_Init(); /* Init sine data table */ static uint32_t gu32SinTable[SINE_DOT_NUMBER]; SinTable_Init(gu32SinTable, SINE_DOT_NUMBER); static uint32_t gu32SawTable[SINE_DOT_NUMBER]; Sawtooth_Init(gu32SawTable, SINE_DOT_NUMBER); static uint32_t gu32PulseTable[SINE_DOT_NUMBER]; Pulse_Init(gu32PulseTable, SINE_DOT_NUMBER); static uint32_t gu32TriangleTable[SINE_DOT_NUMBER]; Triangle_Init(gu32TriangleTable, SINE_DOT_NUMBER); DAC_ConversionInit(); LL_PERIPH_WP(LL_PERIPH_GPIO | LL_PERIPH_FCG | LL_PERIPH_PWC_CLK_RMU | \ LL_PERIPH_EFM | LL_PERIPH_SRAM); for (;;) { enEvent = Key_Event(); switch (enEvent) { case E_KEY1_PRESSED: if (u8IsConversionStart == 1U) { break; } flag=1; u16OutputCnt = 0U; u8IsConversionStart = 1U; BSP_LED_On(LED_BLUE); DAC_StartConversion(); break; case E_KEY2_PRESSED: if (u8IsConversionStart == 1U) { break; } flag=2; u16OutputCnt = 0U; u8IsConversionStart = 1U; BSP_LED_On(LED_BLUE); DAC_StartConversion(); break; case E_KEY3_PRESSED: if (u8IsConversionStart == 1U) { break; } flag=3; u16OutputCnt = 0U; u8IsConversionStart = 1U; BSP_LED_On(LED_BLUE); DAC_StartConversion(); break; case E_KEY4_PRESSED: if (u8IsConversionStart == 1U) { break; } flag=4; u16OutputCnt = 0U; u8IsConversionStart = 1U; BSP_LED_On(LED_BLUE); DAC_StartConversion(); break; case E_KEY5_PRESSED: if (u8IsConversionStart == 0U) { break; } u8IsConversionStart = 0U; DAC_StopConversion(); BSP_LED_Off(LED_BLUE); break; default: break; } if (u8IsConversionStart == 0U) { continue; } if (flag==1){ DAC_SetConversionData(gu32SinTable[u16OutputCnt]); } else if(flag==2){ DAC_SetConversionData(gu32SawTable[u16OutputCnt]); } else if(flag==3){ DAC_SetConversionData(gu32PulseTable[u16OutputCnt]); } else if(flag==4){ DAC_SetConversionData(gu32TriangleTable[u16OutputCnt]); } else{ } /* Loop output */ if (++u16OutputCnt >= SINE_DOT_NUMBER) { u16OutputCnt = 0U; } } }   3实验现象 3.1实验现象分析         按下开发板上的K1、K2、K3、K4,示波器分别显示正弦波、锯齿波、方波、三角波,按下K5会关闭DAC输出。 3.2实验现象         如图4、5、6、7所示 图4 正弦波 图5 锯齿波 图6 方波 图7 三角波

  • 2024-03-27
  • 发表了主题帖: HC32F4A0开发板SRAM读写测试

    HC32F4A0开发板SRAM读写测试 1概述 1.1开发板接口         开发板搭载了一片512k*16bit的一块片外SRAM,型号为:IS62WV51216BLL-55TLI,同时官方例程提供了读写SRAM的例程,通过阅读官方例程和前期的代码相结合即可完成SRAM的读写测试。         MCU定义了总大小为1GB的外部存储器访问区间,用于不同类型的外部存储器和内部数据交换,包括EXMC和QSPI等,,SRAM/PSRAM/NOR Flash(SMC)的数据访问映射512MB的地址空间、SDRAM(DMC)的数据访问映射128MB的地址空间、NAND Flash(NFC)的控制和数据访问映射1MB的地址空间、QSPI的控制和数据访问映射128MB的地址空间,1GB的空间分配如图1所示。 图1 片外地址分配示意图 1.2开发板原理图         SRAM芯片外围电路如图2所示。 图1 SRAM外围电路示意图 1.3测试设备         本次测试所用设备如表1所示,设备实物图连接图如图2所示: 测试设备 单位 数量 EV_F4A0_LQ176_REV1.0开发板 块 壹 ARM仿真器 个 壹 5V电源适配器 个 壹 表1 测试设备 图2 开发板实物连接图 2代码编写 读写测试函数 static uint32_t MEMORY_Access8(uint32_t u3AccessAddr, uint32_t NumBytes,uint16_t u16Width,uint16_t u16Height) { uint32_t i; uint32_t j; uint32_t u32TestErrCnt = 0UL; uint32_t u32MemoryAddr = u3AccessAddr; for (i = 0UL; i < NumBytes; i += DATA_BUF_LEN) { (void)MEMORY_Write8(u32MemoryAddr, m_au8WriteData, DATA_BUF_LEN); lcd_show_xnum(150,50,m_au8WriteData[i],3,24,0,LCD_COLOR_BLACK,u16Width,u16Height); (void)MEMORY_Read8(u32MemoryAddr, m_au8ReadData, DATA_BUF_LEN); lcd_show_xnum(150,80,m_au8ReadData[i],3,24,0,LCD_COLOR_BLACK,u16Width,u16Height); /* Verify data. */ for (j = 0UL; j < DATA_BUF_LEN; j++) { if (m_au8WriteData[j] != m_au8ReadData[j]) { u32TestErrCnt++; } } u32MemoryAddr += (DATA_BUF_LEN * sizeof(m_au8ReadData[0])); (void)memset(m_au8ReadData, 0, (DATA_BUF_LEN * sizeof(m_au8ReadData[0]))); BSP_LED_Toggle(LED_BLUE); } return u32TestErrCnt; }   数据产生函数 static void InitTestData(void) { uint32_t i; /* Clear count value */ m_u32ByteTestErrorCnt = 0UL; /* Initialize test data. */ for (i = 0UL; i < DATA_BUF_LEN; i++) { m_au8ReadData[i] = 0U; m_au8WriteData[i] = (uint8_t)rand(); } } 主函数 int32_t main(void) { uint16_t u16Width; uint16_t u16Height; uint16_t count; /* MCU Peripheral registers write unprotected */ LL_PERIPH_WE(LL_PERIPH_ALL); /* Initialize system clock: */ BSP_CLK_Init(); BSP_IO_Init(); BSP_LED_Init(); /* EXCLK 30MHz */ CLK_SetClockDiv(CLK_BUS_EXCLK, CLK_EXCLK_DIV8); BSP_LCD_IO_Init(); /* Initialize NT35510 LCD */ BSP_NT35510_Init(); /* Clear LCD screen */ BSP_NT35510_Clear(LCD_COLOR_WHITE); /* Turn on LCD backlight */ BSP_LCD_BKLCmd(EIO_PIN_SET); (void)BSP_IS62WV51216_Init(); BSP_IS62WV51216_GetMemInfo(&m_u32StartAddr, &m_u32ByteSize); /* MCU Peripheral registers write protected */ LL_PERIPH_WP(LL_PERIPH_ALL); u16Width = BSP_NT35510_GetPixelWidth(); u16Height = BSP_NT35510_GetPixelHeight(); lcd_show_string(20,20,u16Width,24,24,"test_count:",LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_string(20,50,u16Width,24,24,"write_data:",LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_string(20,80,u16Width,24,24,"read_data:",LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_string(20,110,u16Width,24,24,"error_count:",LCD_COLOR_BLACK,u16Width,u16Height); for (count=0;count<100;count++) { m_u32TestCnt++; lcd_show_xnum(160,20,m_u32TestCnt,3,24,0,LCD_COLOR_BLACK,u16Width,u16Height); /* Initialize test data. */ InitTestData(); /****************** Access data width: Byte *****************/ m_u32ByteTestErrorCnt = MEMORY_Access8(m_u32StartAddr, m_u32ByteSize,u16Width,u16Height); /****************** Error check ******************/ if (m_u32ByteTestErrorCnt > 0UL) { BSP_LED_On(LED_RED); lcd_show_xnum(160,110,m_u32ByteTestErrorCnt,3,24,0,LCD_COLOR_BLACK,u16Width,u16Height); } } while(1){} } 3实验现象 3.1实验现象分析         开发板会实时显示当前测试的次数,共计测试一百次,每读写一次开发板蓝色LED灯会闪烁一次,每次读写的数据会在屏幕上实时刷新,如果写入和读取的数据校验失败,开发板红色LED灯会保持常亮,错误计数会增加一。 3.2实验现象 如视频所示 [localvideo]2cc223e97a18bdcb0bffbfc741ce13bf[/localvideo]   4总结         开发板SRAM读写的相关例程十分详细,有板级的库函数,开发调试都非常方便,进行一定修改后配合前期的LCD相关函数即可进行使用。

  • 2024-03-25
  • 发表了主题帖: HC32F4A0开发板ADC采样测试

    HC32F4A0开发板ADC采样测试 1概述 1.1开发板接口         本MCU搭载3个ADC单元,单元1和2支持16个通道,单元3支持20个通道,可以转换来自外部引脚、以及芯片内部的模拟信号。模拟输入通道可以任意组合成一个序列,一个序列可以进行单次扫描转换,或连续扫描转换。支持对任意指定通道进行连续多次转换并对转换结果进行平均。ADC模块还搭载模拟看门狗功能,对任意指定通道的转换结果进行监视,检测其是否超出用户设定的范围;开发板的三路ADC通过连接器J10引出,其中ADC123_IN3连接可调电位器R105 10K,因此可以通过旋转电位器调节采样电压的值。 1.2开发板原理图         ADC采样外围电路如图1所示。 图1 ADC采样外围电路示意图 1.3测试设备         本次测试所用设备如表1所示,设备实物图连接图如图2所示: 测试设备 单位 数量 EV_F4A0_LQ176_REV1.0开发板 块 壹 ARM仿真器 个 壹 5V电源适配器 个 壹 RIGOL DHO804示波器 台 壹 表1 测试设备 图2 开发板实物连接图 2代码编写 时钟配置 static void AdcClockConfig(void) { CLK_SetClockDiv((CLK_BUS_PCLK2 | CLK_BUS_PCLK4), (CLK_PCLK2_DIV1 | CLK_PCLK4_DIV8)); CLK_SetPeriClockSrc(ADC_CLK); } 采样函数 static void AdcPolling(uint16_t u16Width,uint16_t u16Height) { uint16_t u16AdcValue; int32_t iRet = LL_ERR; __IO uint32_t u32TimeCount = 0UL; /* Can ONLY start sequence A conversion. Sequence B needs hardware trigger to start conversion. */ ADC_Start(ADC_UNIT); do { if (ADC_GetStatus(ADC_UNIT, ADC_EOC_FLAG) == SET) { ADC_ClearStatus(ADC_UNIT, ADC_EOC_FLAG); iRet = LL_OK; break; } } while (u32TimeCount++ < ADC_TIMEOUT_VAL); if (iRet == LL_OK) { /* Get any ADC value of sequence A channel that needed. */ u16AdcValue = ADC_GetValue(ADC_UNIT, ADC_CH); lcd_show_xnum(20,60,(ADC_CAL_VOL(u16AdcValue))/1000,1,32,0,LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_xnum(52,60,(ADC_CAL_VOL(u16AdcValue))%1000,3,32,0,LCD_COLOR_BLACK,u16Width,u16Height); } else { ADC_Stop(ADC_UNIT); lcd_show_string(20,100,u16Width,32,32,"error:",LCD_COLOR_BLACK,u16Width,u16Height); } } 主函数 int32_t main(void) { uint16_t u16Width; uint16_t u16Height; /* MCU Peripheral registers write unprotected */ LL_PERIPH_WE(LL_PERIPH_ALL); /* Initialize system clock: */ BSP_CLK_Init(); BSP_IO_Init(); BSP_LED_Init(); /* EXCLK 30MHz */ //CLK_SetClockDiv(CLK_BUS_EXCLK, CLK_EXCLK_DIV8); AdcConfig(); BSP_LCD_IO_Init(); /* Initialize NT35510 LCD */ BSP_NT35510_Init(); /* Clear LCD screen */ BSP_NT35510_Clear(LCD_COLOR_WHITE); /* Turn on LCD backlight */ BSP_LCD_BKLCmd(EIO_PIN_SET); /* MCU Peripheral registers write protected */ LL_PERIPH_WP(LL_PERIPH_ALL); u16Width = BSP_NT35510_GetPixelWidth(); u16Height = BSP_NT35510_GetPixelHeight(); lcd_show_string(20,20,u16Width,32,32,"The sampling voltage is:",LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_string(40,60,u16Width,32,32,".",LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_string(100,60,u16Width,32,32,"V",LCD_COLOR_BLACK,u16Width,u16Height); while(1){ AdcPolling(u16Width,u16Height); }; } 3实验现象 3.1实验现象分析         调节开发板上的可调电位器,得到的电压值应符合变化趋势,通过示波器测量电位器的中间引脚,可和采样得到的电压值进行对比分析。 3.2实验现象 如视频所示 [localvideo]9deacae656d8b6aa70a2120ecac880a4[/localvideo] [localvideo]a4e26f8e85507d01b4d60debbb3a4c1c[/localvideo]  

  • 2024-03-24
  • 发表了主题帖: HC32F4A0开发板CAN通讯测试

    本帖最后由 changweilin 于 2024-3-24 23:39 编辑 HC32F4A0开发板CAN通讯测试 1概述 1.1开发板接口         该开发板有2个CAN接口,支持CAN2.0B,最高支持CAN FD,使用的接口芯片型号为:MCP2542,CAN2.0B控制器中应用程序可通过1个PTB和3 STB将发送数据送至总线,由发送调度器决定邮箱发送顺序。通过8个接收缓冲器获取总线数据。3个STB以及8个RB可以理解为一个3级FIFO和一个8级FIFO,FIFO完全由硬件控制;本次测试主要测试经典CAN的收发并将收发数据显示在屏幕上。 1.2开发板原理图         CAN芯片的接口及外围电路如图1所示。 图1 CAN接口外围电路示意图 1.3测试设备         本次测试所用设备如表1所示,开发板和CAN盒之间使用屏蔽双绞线连接,在CAN盒连接端跨接120Ω的匹配电阻防止信号反射,设备实物图连接图如图2所示: 测试设备 单位 数量 EV_F4A0_LQ176_REV1.0开发板 块 壹 ARM仿真器 个 壹 5V电源适配器 个 壹 ZLG USBCANFD-200U 个 壹 ALIENTEK 4.3’TFTLCD 块 壹 RIGOL DHO804示波器 台 壹 表1 测试设备 图2 开发板实物连接图 2代码编写 产生发送数据 static void LoadData() { uint8_t i; for (i = 0U; i < CAN_TX_DATA_SIZE; i++) { stcTx1.au8Data[i] = i + 0x0AU; stcTx2.au8Data[i] = i + 0x3aU; } stcTx1.u32Ctrl = 0x0UL; stcTx1.u32ID = CAN_TX_ID1; stcTx1.IDE = CAN_TX_ID1_IDE; stcTx1.DLC = CAN_TX_DLC; stcTx2.u32Ctrl = 0x0UL; stcTx2.u32ID = CAN_TX_ID2; stcTx2.IDE = CAN_TX_ID2_IDE; stcTx2.DLC = CAN_TX_DLC; } 发送数据并显示 static void CanTx(uint16_t u16Width,uint16_t u16Height) { uint8_t i; if (BSP_KEY_GetStatus(BSP_KEY_1) == SET) { if (m_u8TxStart == 0U) { m_u8TxProcess++; if (m_u8TxProcess > CAN_TX_PROCESS_STB) { m_u8TxProcess = CAN_TX_PROCESS_PTB; } switch (m_u8TxProcess) { case CAN_TX_PROCESS_PTB: /* Transmit one frame via PTB */ (void)CAN_FillTxFrame(CAN_UNIT, CAN_TX_BUF_PTB, &stcTx1); CAN_StartTx(CAN_UNIT, CAN_TX_REQ_PTB); //lcd_show_xnum(140,20,m_astRxFrame[0].u32ID,4,24,0,LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_xnum(120,100,stcTx1.au8Data[0],2,24,0,LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_xnum(150,100,stcTx1.au8Data[1],2,24,0,LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_xnum(180,100,stcTx1.au8Data[2],2,24,0,LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_xnum(210,100,stcTx1.au8Data[3],2,24,0,LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_xnum(240,100,stcTx1.au8Data[4],2,24,0,LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_xnum(270,100,stcTx1.au8Data[5],2,24,0,LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_xnum(300,100,stcTx1.au8Data[6],2,24,0,LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_xnum(330,100,stcTx1.au8Data[7],2,24,0,LCD_COLOR_BLACK,u16Width,u16Height); break; case CAN_TX_PROCESS_STB: /* Transmit one frame via STB */ (void)CAN_FillTxFrame(CAN_UNIT, CAN_TX_BUF_STB, &stcTx2); CAN_StartTx(CAN_UNIT, CAN_TX_REQ_STB_ONE); lcd_show_xnum(120,100,stcTx2.au8Data[0],2,24,0,LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_xnum(150,100,stcTx2.au8Data[1],2,24,0,LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_xnum(180,100,stcTx2.au8Data[2],2,24,0,LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_xnum(210,100,stcTx2.au8Data[3],2,24,0,LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_xnum(240,100,stcTx2.au8Data[4],2,24,0,LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_xnum(270,100,stcTx2.au8Data[5],2,24,0,LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_xnum(300,100,stcTx2.au8Data[6],2,24,0,LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_xnum(330,100,stcTx2.au8Data[7],2,24,0,LCD_COLOR_BLACK,u16Width,u16Height); break; } m_u32TxTick = CAN_TX_TIMEOUT_MS; m_u8TxStart = 1U; } else { } } } 接收数据并显示 static void CanRx(uint16_t u16Width,uint16_t u16Height) { uint8_t i; uint8_t j; uint8_t u8RxFrameNum = 0U; int32_t i32Ret; /* Get all received frames. */ do { i32Ret = CAN_GetRxFrame(CAN_UNIT, &m_astRxFrame[u8RxFrameNum]); if (i32Ret == LL_OK) { u8RxFrameNum++; } } while (i32Ret == LL_OK); lcd_show_xnum(140,20,m_astRxFrame[0].u32ID,4,24,0,LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_xnum(120,60,m_astRxFrame[0].au8Data[0],2,24,0,LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_xnum(150,60,m_astRxFrame[0].au8Data[1],2,24,0,LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_xnum(180,60,m_astRxFrame[0].au8Data[2],2,24,0,LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_xnum(210,60,m_astRxFrame[0].au8Data[3],2,24,0,LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_xnum(240,60,m_astRxFrame[0].au8Data[4],2,24,0,LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_xnum(270,60,m_astRxFrame[0].au8Data[5],2,24,0,LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_xnum(300,60,m_astRxFrame[0].au8Data[6],2,24,0,LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_xnum(330,60,m_astRxFrame[0].au8Data[7],2,24,0,LCD_COLOR_BLACK,u16Width,u16Height); /* Handle received frames. */ for (i = 0U; i < u8RxFrameNum; i++) { for (j = 0; j < (uint8_t)m_astRxFrame[i].DLC; j++) { m_astRxFrame[i].au8Data[j] = 2U; } } } 过滤器设置 #define CAN_FILTER1_ID (0x101UL) #define CAN_FILTER1_ID_MASK (0x0UL) #define CAN_FILTER1_ID_TYPE (CAN_ID_STD) 主函数 int32_t main(void) { uint16_t u16Width; uint16_t u16Height; /* MCU Peripheral registers write unprotected */ LL_PERIPH_WE(LL_PERIPH_ALL); /* Initialize system clock: */ BSP_CLK_Init(); CLK_SetClockDiv(CLK_BUS_EXCLK, CLK_EXCLK_DIV8); BSP_IO_Init(); //BSP_LED_Init(); BSP_LCD_IO_Init(); BSP_KEY_Init(); BSP_LCD_RSTCmd(EIO_PIN_RESET); /* RST# to low */ DDL_DelayMS(50UL); BSP_LCD_RSTCmd(EIO_PIN_SET); /* RST# to high */ DDL_DelayMS(50UL); BSP_NT35510_Init(); BSP_NT35510_Clear(LCD_COLOR_WHITE); BSP_LCD_BKLCmd(EIO_PIN_SET); /* Set LCD cursor */ BSP_NT35510_SetCursor(0U, 0U); /* Turn on LCD backlight */ BSP_LCD_BKLCmd(EIO_PIN_SET); CanCommClockConfig(); CanPinConfig(); CanInitConfig(); CanIrqConfig(); CanPhyEnable(); (void)SysTick_Init(1000U); /* Clear LCD screen */ /* MCU Peripheral registers write protected */ LL_PERIPH_WP(LL_PERIPH_ALL); u16Width = BSP_NT35510_GetPixelWidth(); u16Height = BSP_NT35510_GetPixelHeight(); LoadData(); lcd_show_string(20,20,u16Width,u16Height,24,"CAN_RX_ID:",LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_string(20,60,u16Width,u16Height,24,"RX_DATA:",LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_string(20,100,u16Width,u16Height,24,"TX_DATA:",LCD_COLOR_BLACK,u16Width,u16Height); for (;;) { if (m_u8RxFlag != 0U) { /* Read frames here or in CAN_IrqCallback */ CanRx(u16Width,u16Height); m_u8RxFlag = 0U; } CanTx(u16Width,u16Height); } } 3实验现象 3.1实验现象分析         本实验通过按键来触发CAN数据的发送,每次按下按键会以不同的方式发送不同的数据,发送的数据会在LCD显示屏上实时更新,同时使用ZLG CANpro显示接收到的数据,并且给开发板发送数据,开发板会将收到的数据和CANID显示在显示屏上。 3.2CAN发送         首次按下按键K1发送的数据如图3所示,CAN盒接收到的数据如图4所示,再次按下按键K1,发送的数据如图5所示,CAN盒接收到的数据如图6所示。使用示波器抓取发送的数据如图7、8所示;实验现象和编写代码的预期一致。 图3 第一次按下按键数据显示 图4 第一次按下按键CAN盒接收数据显示 图5 第二次按下按键数据显示 图6 第二次按下按键CAN盒接收数据显示 图7 第一次发送波形 图8 第二次发送波形 3.3CAN接收         使用CANPRO软件发送数据,设置如图9所示,LCD显示屏会将接收到的CANID和CAN数据显示在屏幕上,如图10所示,程序中设置了过滤器仅能接接收ID为101的数据,因此当修改CANID为102时显示屏上的ID并不更新,证明过滤器正常工作。 图9 CAN发送设置 图10 开发板接收到的CAN数据 图11 修改ID和数据后设置 图12 数据发送成功         如图11、12所示修改CANID和数据后发送成功,但显示屏未更新数据和ID,证明过滤器正常工作。 4实验过程         can盒发送过程: [localvideo]a70085968c58011fa6b3f80d74dbc6e1[/localvideo]        can盒接收过程 [localvideo]c4f9a9e8dc4e56f5dad22cda077c72dd[/localvideo]   5总结         开发板CAN接口的相关例程十分详细,进行一定修改后配合前期的LCD相关函数即可进行使用,能够满足接口快速开发的需求。  

  • 2024-03-23
  • 发表了主题帖: HC32F4A0开发板W25Q64芯片读写及LCD显示

    本帖最后由 changweilin 于 2024-3-23 23:58 编辑 HC32F4A0开发板W25Q64芯片读写及LCD显示 1概述 1.1开发板接口         该开发板搭载了QSPI_FLASH型号为W25Q64JVSSIQ,本篇主要测评该芯片的读写功能,查看原理图后发现该开发板还有LCD接口,该接口可以兼容主控为NT35510的LCD屏实现FLASH读写时的显示功能。 1.2开发板原理图         W25Q64芯片的外围电路及接口如图1所示。 图1 W25Q64外围电路及接口示意图         LCD显示屏外围电路及接口如图2所示。 图2 LCD接口及外围电路示意图 1.3测试设备         本次测试所用设备如表1所示,设备实物图如图3所示: 测试设备 单位 数量 EV_F4A0_LQ176_REV1.0开发板 块 壹 ARM仿真器 个 壹 5V电源适配器 个 壹 ALIENTEK 4.3’TFTLCD 块 壹   表1 测试设备 图3 开发板实物连接图 2代码编写 2.1LCD驱动函数         编写LCD驱动函数,使其可以显示字符串和数字代码如下  BSP_NT35510.c #include "BSP_NT35510.h" #include "FONT.h" uint32_t g_back_color = 0XFFFF; static uint32_t lcd_pow(uint8_t m, uint8_t n) { uint32_t result = 1; while (n--) result *= m; return result; } void lcd_show_char(uint16_t x, uint16_t y, char chr, uint8_t size, uint8_t mode, uint16_t color,uint16_t u16Width,uint16_t u16Height) { uint8_t temp, t1, t; uint16_t y0 = y; uint8_t csize = 0; uint8_t *pfont = 0; csize = (size / 8 + ((size % 8) ? 1 : 0)) * (size / 2); chr = chr - ' '; switch (size) { case 12: pfont = (uint8_t *)asc2_1206[chr]; break; case 16: pfont = (uint8_t *)asc2_1608[chr]; break; case 24: pfont = (uint8_t *)asc2_2412[chr]; break; case 32: pfont = (uint8_t *)asc2_3216[chr]; break; default: return ; } for (t = 0; t < csize; t++) { temp = pfont[t]; for (t1 = 0; t1 < 8; t1++) { if (temp & 0x80) { BSP_NT35510_WritePixel(x, y, color); } else if (mode == 0) { BSP_NT35510_WritePixel(x, y, g_back_color); } temp <<= 1; y++; if (y >= u16Height) return; if ((y - y0) == size) { y = y0; x++; if (x >= u16Width) return; break; } } } } void lcd_show_string(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t size, char *p, uint16_t color,uint16_t u16Width,uint16_t u16Height) { uint8_t x0 = x; width += x; height += y; while ((*p <= '~') && (*p >= ' ')) { if (x >= width) { x = x0; y += size; } if (y >= height) break; lcd_show_char(x, y, *p, size, 0, color,u16Width,u16Height); x += size / 2; p++; } } void lcd_show_xnum(uint16_t x, uint16_t y, uint32_t num, uint8_t len, uint8_t size, uint8_t mode, uint16_t color,uint16_t u16Width,uint16_t u16Height) { uint8_t t, temp; uint8_t enshow = 0; for (t = 0; t < len; t++) { temp = (num / lcd_pow(10, len - t - 1)) % 10; if (enshow == 0 && t < (len - 1)) { if (temp == 0) { if (mode & 0X80) { lcd_show_char(x + (size / 2) * t, y, '0', size, mode & 0X01, color, u16Width, u16Height); } else { lcd_show_char(x + (size / 2) * t, y, ' ', size, mode & 0X01, color, u16Width, u16Height); } continue; } else { enshow = 1; } } lcd_show_char(x + (size / 2) * t, y, temp + '0', size, mode & 0X01, color, u16Width, u16Height); } }  BSP_NT35510.h #ifndef __BSP_NT35510_H__ #define __BSP_NT35510_H__ #include "main.h" void lcd_show_char(uint16_t x, uint16_t y, char chr, uint8_t size, uint8_t mode, uint16_t color,uint16_t u16Width,uint16_t u16Height); void lcd_show_string(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t size, char *p, uint16_t color,uint16_t u16Width,uint16_t u16Height); void lcd_show_xnum(uint16_t x, uint16_t y, uint32_t num, uint8_t len, uint8_t size, uint8_t mode, uint16_t color,uint16_t u16Width,uint16_t u16Height); #endif   2.2主函数 #include "main.h" #define SPI_FLASH_DATA_SIZE (256UL) #define SPI_FLASH_ADDR (0UL) static uint8_t m_au8WriteData[SPI_FLASH_DATA_SIZE]; static uint8_t m_au8ReadData[SPI_FLASH_DATA_SIZE]; static void LoadData(void); static void ClearData(void); static void VerifyData(void); int32_t main(void) { uint16_t u16Width; uint16_t u16Height; uint16_t count; /* MCU Peripheral registers write unprotected */ LL_PERIPH_WE(LL_PERIPH_ALL); /* Initialize system clock: */ BSP_CLK_Init(); BSP_IO_Init(); BSP_LED_Init(); BSP_LCD_IO_Init(); /* Initialize NT35510 LCD */ BSP_NT35510_Init(); /* Clear LCD screen */ BSP_NT35510_Clear(LCD_COLOR_WHITE); /* Turn on LCD backlight */ BSP_LCD_BKLCmd(EIO_PIN_SET); /* Set LCD cursor */ BSP_W25QXX_Init(); /* MCU Peripheral registers write protected */ LL_PERIPH_WP(LL_PERIPH_ALL); u16Width = BSP_NT35510_GetPixelWidth(); u16Height = BSP_NT35510_GetPixelHeight(); lcd_show_string(20,20,u16Width,32,32,"wirte:",LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_string(20,100,u16Width,32,32,"read:",LCD_COLOR_BLACK,u16Width,u16Height); LoadData(); for(count=0;count<SPI_FLASH_DATA_SIZE;count++){ (void)BSP_W25QXX_EraseSector(SPI_FLASH_ADDR); (void)BSP_W25QXX_Write(SPI_FLASH_ADDR,m_au8WriteData,SPI_FLASH_DATA_SIZE); (void)BSP_W25QXX_Read(SPI_FLASH_ADDR,m_au8ReadData,SPI_FLASH_DATA_SIZE); VerifyData(); lcd_show_xnum(20,60,m_au8WriteData[count],3,32,0,LCD_COLOR_BLACK,u16Width,u16Height); lcd_show_xnum(20,140,m_au8ReadData[count],3,32,0,LCD_COLOR_BLACK,u16Width,u16Height); BSP_LED_Toggle(LED_BLUE); ClearData(); } while(1){}; } static void LoadData(void) { uint32_t i; for (i = 0UL; i < SPI_FLASH_DATA_SIZE; i++) { m_au8WriteData[i] = (uint8_t)i; } } static void ClearData(void) { uint32_t i; for (i = 0UL; i < SPI_FLASH_DATA_SIZE; i++) { m_au8ReadData[i] = 0U; } } static void VerifyData(void) { uint32_t i; for (i = 0UL; i < SPI_FLASH_DATA_SIZE; i++) { if (m_au8ReadData[i] != m_au8WriteData[i]) { BSP_LED_Off(LED_BLUE); BSP_LED_On(LED_RED); for (;;) { ; } } } }   3实验现象 3.1实验现象分析         试验现象应为,每读写一次FLASH,LCD显示屏刷新一次,开发板上蓝色LED灯闪烁一次,读写256次后停止。 3.2实验现象         如视频所示: [localvideo]ecd398c8810ec62d71a6475e2ea8460e[/localvideo]  

  • 2024-02-18
  • 回复了主题帖: HC32F4A0开发板开箱、搭建开发环境及点亮LED灯

    LitchiCheng 发表于 2024-2-18 09:25 这个开发板好大,感觉把很多外设都扩展出来给用户了 这板子比想象中大很多,各种功能很齐全,拿来学习外设确实很好

  • 2024-02-17
  • 回复了主题帖: HC32F4A0开发板开箱、搭建开发环境及点亮LED灯

    Jacktang 发表于 2024-2-16 22:23 实验现象视频没上传成功吧 好像是的,等上班了我联系下管理看看啥情况

  • 2024-02-15
  • 发表了主题帖: HC32F4A0开发板开箱、搭建开发环境及点亮LED灯

    本帖最后由 changweilin 于 2024-2-18 20:56 编辑 HC32F4A0开发板开箱、搭建开发环境及点亮LED灯 1开发板简介 1.1主控芯片        XHSCEV_F4A0_LQ176_Rev1.0开发板搭载小华半导体公司的HC32F4A0SITB-LQFP176芯片,该芯片为Cortex-M4架构,集成FPU、MPU,支持SIMD指令的DSP ,最高工作主频 240MHz ,达到 300DMIPS或825Coremarks的运算性能,支持宽电压范围(1.8-3.6v),器件等级为工业级(工作温度-40℃~105℃),片内包含2MB的Flash和516KB的SRAM,6个独立时钟源,16个高性能模拟外设,多路定时器,142GPIO,最多32个通信接口,是HC32F4系列性能最高外设最丰富的芯片。 1.2开发板外设       该开发板外设资源及其丰富,其硬件系统如图1所示:  图1 开发板外设框图        开发板可以通过Micro-USB接口或者5v电源适配器接口供电,使用船型开关来控制电源适配器的通断,可以使用SWD、JTAG、TRACE以及板载DAP进行调试和下载程序;该开发板有20PIN的JTAG口,当使用JTAG口进行调试时,JTAG口的电源会给整个开发板进行供电,此时关闭船型开关整个开发板依然会处于工作状态,因此为方便调试要在KEIL5中勾选Reset AND Run如图2所示,烧录程序后会直接运行。 图2 Keil5调试设置 1.3实物开箱        开发板正反面实物如图3、图4所示,因搭载外设种类较多,整体尺寸较大为200mm×150mm,开发板采用白色丝印、蓝色阻焊剂,主要元器件都位于开发板正面,整体焊接平整,切口处无毛刺且丝印清晰。 图3 开发板正面 图4 开发板背面 2开发环境搭建 2.1开发环境选择       根据文档《UM_小华半导体MCU开发环境使用_Rev1.1.pdf》及小华半导体官网相关资料,小华MCU可选择IAR Workbench、Keil uVision5 MDK和XHCode进行开发,根据个人开发习惯选择开发环境,下面我会使用Keil5 MDK来搭建开发环境和工程模板;值得一提的是小华官方提供了图形化编程工具XHCode如图5所示,可以快速查看各种型号芯片的所有外设并进行快速配置。 图5 XHCode界面 2.2开发环境搭建 2.2.1相关资料下载       该开发板的相关资料可以通过eeworld测评网站:https://bbs.eeworld.com.cn/elecplay/content/5aa6118a和小华半导体官方网站:https://xhsc.com.cn/Productlist/info.aspx?itemid=1801进行下载。 2.2.2创建工程模板       下载并安装HC32F4AO系列的支持包,选择对应型号的芯片如图6所示,根据个人开发习惯搭建工程模板如图7所示。 图6 选择芯片型号 图7 个人工程模板结构 3点亮LED灯 3.1原理图分析       查阅开发板电路图可知该开发板没有独立控制LED灯的引脚,经过对原理图(图8)的分析发现TPS2051BD的EN脚可以控制OUT脚的高低电平进而控制MMBT5551三极管的通断,当三极管导通时LED灯点亮、断开时LED灯熄灭,LED10和LED11可以通过PB11和PC9的高低电平来控制亮灭。 图8 LED相关原理图 3.2点亮LED灯代码       LED灯控制函数: #include "main.h" #define LED11_PORT (GPIO_PORT_C) #define LED11_PIN (GPIO_PIN_09) #define LED10_PORT (GPIO_PORT_B) #define LED10_PIN (GPIO_PIN_11) void LED_Init(void) { stc_gpio_init_t stcGpioInit; stcGpioInit.u16PinState = PIN_STAT_RST;//初始化电平状态 stcGpioInit.u16PinDir = PIN_DIR_OUT; //配置输入or输出 stcGpioInit.u16PinOutputType = PIN_OUT_TYPE_CMOS; //推挽输出 stcGpioInit.u16PinDrv = PIN_HIGH_DRV; //驱动能力 stcGpioInit.u16Latch = PIN_LATCH_OFF; //输出锁存关闭 stcGpioInit.u16PullUp = PIN_PU_ON; //内部上拉 stcGpioInit.u16Invert = PIN_INVT_OFF; //关闭内部反向 stcGpioInit.u16ExtInt = PIN_EXTINT_OFF; //关闭中断 //stcGpioInit.u16PinInputType = PIN_IN_TYPE_SMT; //开启输入施密特触发器 stcGpioInit.u16PinAttr = PIN_ATTR_DIGITAL; //引脚为模拟状态 LL_PERIPH_WE( LL_PERIPH_GPIO ); //gpio寄存器解保护 GPIO_Init( LED11_PORT, LED11_PIN, &stcGpioInit ); GPIO_Init( LED10_PORT, LED10_PIN, &stcGpioInit ); LL_PERIPH_WP( LL_PERIPH_GPIO ); //gpio寄存器保护 } void LED10_ON(void)//LED10点亮 { GPIO_SetPins(LED10_PORT,LED10_PIN); } void LED10_OFF(void)//LED10熄灭 { GPIO_ResetPins(LED10_PORT,LED10_PIN); } void LED11_ON(void)//LED11点亮 { GPIO_SetPins(LED11_PORT,LED11_PIN); } void LED11_OFF(void)//LED11熄灭 { GPIO_ResetPins(LED11_PORT,LED11_PIN); }         主函数: #include "main.h" int32_t main( void ) { LL_PERIPH_WE( LL_PERIPH_ALL );//寄存器解保护 BSP_CLK_Init();//配置系统时钟 LL_PERIPH_WP( LL_PERIPH_ALL );//寄存器保护 LED_Init();//初始化GPIO和LED灯 delay_init( 240 );//根据系统时钟频率配置延时基准 while( 1 ) { LED10_ON();//点亮LED10 LED11_OFF();//关闭LED11 delay_ms(500);//延时500MS LED10_OFF();//关闭LED10 LED11_ON();//点亮LED11 delay_ms(500);//延时500MS } }   3.3实验现象      如视频所示 [localvideo]fea39ae81ff9f7d2f900faa0f2ba4b80[/localvideo] 4点亮三色LED灯 4.1三色LED灯原理图分析      开发板上有红、黄、蓝三色LED灯各一个(图9),通过TCA9539的P15、P16和P17进行控制,因此可通过I2C接口控制TCA9539进而控制开发板上的三色LED灯的亮灭(图10)。 图9 三色LED灯原理图 图10  TCA9539控制芯片 4.2点亮三色LED灯代码 #include "main.h" int32_t main( void ) { LL_PERIPH_WE( LL_PERIPH_ALL );//寄存器解保护 BSP_CLK_Init();//配置系统时钟 BSP_IO_Init();//初始化TCA9539 BSP_LED_Init();//初始化LED灯 LL_PERIPH_WP( LL_PERIPH_ALL );//寄存器保护 delay_init( 240 );//根据系统时钟频率配置延时基准 while( 1 ) { BSP_LED_On(LED_RED); BSP_LED_Off(LED_YELLOW); BSP_LED_Off(LED_BLUE); delay_ms(500);//延时500MS BSP_LED_Off(LED_RED); BSP_LED_On(LED_YELLOW); BSP_LED_Off(LED_BLUE); delay_ms(500);//延时500MS BSP_LED_Off(LED_RED); BSP_LED_Off(LED_YELLOW); BSP_LED_On(LED_BLUE); delay_ms(500);//延时500MS } } 4.3实验现象       如视频所示 [localvideo]eb6cfe19ae068d29aaf2dfae21c8ea99[/localvideo]

  • 2024-02-04
  • 回复了主题帖: 测评入围名单(最后一批):年终回炉,FPGA、AI、高性能MCU、书籍等42个测品

    个人信息无误,确认可以完成评测计划

  • 2024-01-19
  • 回复了主题帖: 辞旧:年底清仓,100+板卡来袭,有缘来领

    申请板卡:NuTiny-SDK-NUC472 项目概述 项目旨在实现一个测距数据处理系统;使用激光体制完成测距,并且需要接收CAN总线上其他设备采集来的数据,在MCU中进行数据对比后,在显示屏上显示距离数据,并将处理结果以485总线的形式传输给后级设备。通过该项目学习多总线多设备协同工作。 申请理由 第一次申请的NXP开发板没有库存了,经过查阅开发板相关资料发现该款开发板也拥有CAN接口、串口和I2c接口,因此我计划采用MAX485自己设计制作一个串口转RS485模块,然后通过I2C接口连接OLED屏显示数据;该MCU使用ARM Cortex-M4F内核,带有数字信号处理单元和 与 FPU 浮点运算单元可以完成测距算法,并且可以产生PWM波,通过控制PWM波的占空比来控制激光接收模块的增益强度以实现AGC算法。 后续会将接口模块的实现过程、项目经验和代码分享在论坛上,和其他设计师共同交流。

  • 2024-01-15
  • 回复了主题帖: 辞旧:年底清仓,100+板卡来袭,有缘来领

    申请板卡:37 四色板组合式开发平台 Kinetis MCU 套件 申请理由:本人因项目需求,要开发一款产品,需要能接收上级设备CAN总线数据,对数据进行处理后,调用FLASH内的参数进行校验,校验正确后显示在屏幕上,然后将结果通过RS485总线传输给下级设备,使用过程中要首先通过SIM卡验证,并保留串口调试方便后期软件升级;该开发板采用模块化设计,扩展性强,调试方便,其搭载的Kinetis系列车规级处理器具有低功耗尺寸小的特点,并且该开发板搭载的多种外设能完美满足我的使用需求,使用该开发板能大幅降低我的开发周期,因此衷心希望能申请该板卡进行原理验证。

最近访客

< 1/2 >

统计信息

已有17人来访过

  • 芯积分:109
  • 好友:--
  • 主题:8
  • 回复:5

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言