xld0932

个性签名:We are a team and we work as a team !

  • 2021-03-03
  • 加入了学习《DIY作品演示》,观看 基于MQTT消息通讯的IoT入门实例

  • 2021-02-26
  • 回复了主题帖: 【GD32E503评测】——07.LCD第二篇:绘制自定义图案

    freebsder 发表于 2021-2-25 22:29 绘图纯粹是算法了,考校的是算法功力,其实没啥特别考验mcu的
    有的哈,一个是算法的实现,还有就是MCU执行的效率和速度哈……

  • 2021-02-22
  • 回复了主题帖: 开工大吉,抢楼有礼!预测:2021年电子热门关键词

    国产MCU经过1年的铺垫,会逐渐迎来调整的发展

  • 2021-02-21
  • 发表了主题帖: 【GD32E503评测】——07.LCD第二篇:绘制自定义图案

    一、概述 在第一篇中我们测试了LCD的刷新速度,使用了官方提供的gd32e50x_lcd_eval.c文件已经实现的lcd_clear函数实现整屏数据填充;另外官方还提供了画水平线、画垂直线、画空心矩形和实心矩形的函数实现;本篇我们主要在调用官方提供的函数绘制图片查看显示效果之前,我们还添加了画线函数,可以实现任意起点和终点之间的连接,不局限于水平线和垂直线;还添加了画圆形图案的函数,使用中点画圆算法,实现了实心圆和空心圆的绘制;   二、任意起点、终点线的绘制 /******************************************************************************* * @brief * @param * @retval * @attention *******************************************************************************/ void LCD_DrawLine(uint16_t StartX, uint16_t StartY, uint16_t EndX, uint16_t EndY, uint16_t Color) { uint16_t CurrentX = StartX; uint16_t CurrentY = StartY; int16_t DeltaX = EndX - StartX; int16_t DeltaY = EndY - StartY; int16_t IncreaseX = 0, OffsetX = 0; int16_t IncreaseY = 0, OffsetY = 0; uint16_t Distance = 0; if(DeltaX > 0) { IncreaseX = 1; } else if(DeltaX == 0) { IncreaseX = 0; } else { IncreaseX = -1; DeltaX = -DeltaX; } if(DeltaY > 0) { IncreaseY = 1; } else if(DeltaY == 0) { IncreaseY = 0; } else { IncreaseY = -1; DeltaY = -DeltaY; } if(DeltaX > DeltaY) Distance = DeltaX; else Distance = DeltaY; for(uint16_t i = 0; i <= Distance + 1; i++) { lcd_point_set(CurrentX, CurrentY, Color); OffsetX += DeltaX; OffsetY += DeltaY; if(OffsetX > Distance) { OffsetX -= Distance; CurrentX += IncreaseX; } if(OffsetY > Distance) { OffsetY -= Distance; CurrentY += IncreaseY; } } }   三、空心圆、实心圆的绘制 /******************************************************************************* * @brief * @param * @retval * @attention *******************************************************************************/ void LCD_DrawCircle(uint16_t CenterX, uint16_t CenterY, uint16_t Radius, uint16_t Color, uint8_t Filled) { int16_t CurrentX = 0, CurrentY = Radius; int16_t Distance = 3 - (Radius << 0x01); while(CurrentX <= CurrentY) { if(Filled) { for(int16_t i = CurrentX; i <= CurrentY; i++) { lcd_point_set(CenterX + CurrentX, CenterY + i, Color); lcd_point_set(CenterX - CurrentX, CenterY + i, Color); lcd_point_set(CenterX - i, CenterY + CurrentX, Color); lcd_point_set(CenterX - i, CenterY - CurrentX, Color); lcd_point_set(CenterX - CurrentX, CenterY - i, Color); lcd_point_set(CenterX + CurrentX, CenterY - i, Color); lcd_point_set(CenterX + i, CenterY - CurrentX, Color); lcd_point_set(CenterX + i, CenterY + CurrentX, Color); } } else { lcd_point_set(CenterX + CurrentX, CenterY + CurrentY, Color); lcd_point_set(CenterX - CurrentX, CenterY + CurrentY, Color); lcd_point_set(CenterX - CurrentY, CenterY + CurrentX, Color); lcd_point_set(CenterX - CurrentY, CenterY - CurrentX, Color); lcd_point_set(CenterX - CurrentX, CenterY - CurrentY, Color); lcd_point_set(CenterX + CurrentX, CenterY - CurrentY, Color); lcd_point_set(CenterX + CurrentY, CenterY - CurrentX, Color); lcd_point_set(CenterX + CurrentY, CenterY + CurrentX, Color); } CurrentX++; if(Distance < 0) { Distance += (4 * CurrentX + 6); } else { Distance += (10 + 4 * (CurrentX - CurrentY)); CurrentY--; } } }   四、结合官方提供的水平线、垂直线、空心矩形、实心矩形绘制DEMO图案 /******************************************************************************* * @brief * @param * @retval * @attention *******************************************************************************/ void LCD_Demo(void) { LCD_DrawLine(50, 50, 50, 100, LCD_COLOR_RED); LCD_DrawLine(50, 50, 100, 50, LCD_COLOR_RED); LCD_DrawLine(50, 50, 100, 100, LCD_COLOR_RED); lcd_rectangle_draw(120, 120, 170, 170, LCD_COLOR_YELLOW); LCD_DrawCircle(50, 200, 40, LCD_COLOR_BLACK, 0); LCD_DrawCircle(50, 200, 20, LCD_COLOR_BLACK, 1); lcd_rectangle_fill(140, 240, 160, 260, LCD_COLOR_YELLOW); LCD_DrawCircle(150, 250, 40, LCD_COLOR_WHITE, 0); }   五、运行效果图 六、调试问题 在下载的官方GD32E50x_Firmware_Library_V1.1.2和GD32E50x_Demo_Suites_V1.1.1这两个文件夹中都有关于LCD有底层驱动代码,我开始使用的是GD32E50x_Firmware_Library_V1.1.2中的官方代码,在显示的时候总是读取不到LCD的Device_Code,更别说显示正常了,但使用GD32E50x_Demo_Suites_V1.1.1中的官方驱动代码,显示就是正常的,然后就对照官方例程一点点的定位,最后发现官方提供的驱动是支持不同型号TFT驱动芯片的,而我开发板上的TFT驱动芯片的操作时序配置不匹配导致了操作不成功的问题,具体修改如下所示: /*! \brief lcd peripheral initialize \param[in] none \param[out] none \retval none */ void exmc_lcd_init(void) { exmc_norsram_parameter_struct lcd_init_struct; exmc_norsram_timing_parameter_struct lcd_timing_init_struct; /* EXMC clock enable */ rcu_periph_clock_enable(RCU_EXMC); /* GPIO clock enable */ rcu_periph_clock_enable(RCU_GPIOD); rcu_periph_clock_enable(RCU_GPIOE); rcu_periph_clock_enable(RCU_GPIOG); /* configure EXMC_D[0~15]*/ /* PD14(EXMC_D0), PD15(EXMC_D1),PD0(EXMC_D2), PD1(EXMC_D3), PD8(EXMC_D13), PD9(EXMC_D14), PD10(EXMC_D15) */ gpio_init(GPIOD, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_1| GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15); /* PE7(EXMC_D4), PE8(EXMC_D5), PE9(EXMC_D6), PE10(EXMC_D7), PE11(EXMC_D8), PE12(EXMC_D9), PE13(EXMC_D10), PE14(EXMC_D11), PE15(EXMC_D12) */ gpio_init(GPIOE, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15); /* configure PE2(EXMC_A23) */ gpio_init(GPIOE, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2); /* configure PD4(NOE) and PD5(NWE) */ gpio_init(GPIOD, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4 | GPIO_PIN_5); /* configure PG9(EXMC NE1) */ gpio_init(GPIOG, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9); lcd_timing_init_struct.asyn_access_mode = EXMC_ACCESS_MODE_A; lcd_timing_init_struct.syn_data_latency = EXMC_DATALAT_2_CLK; lcd_timing_init_struct.syn_clk_division = EXMC_SYN_CLOCK_RATIO_DISABLE; lcd_timing_init_struct.bus_latency = 2; #if 0 lcd_timing_init_struct.asyn_data_setuptime = 10; lcd_timing_init_struct.asyn_address_holdtime = 2; lcd_timing_init_struct.asyn_address_setuptime = 5; #else lcd_timing_init_struct.asyn_data_setuptime = 18; lcd_timing_init_struct.asyn_address_holdtime = 3; lcd_timing_init_struct.asyn_address_setuptime = 8; #endif lcd_init_struct.norsram_region = EXMC_BANK0_NORSRAM_REGION0; lcd_init_struct.write_mode = EXMC_ASYN_WRITE; lcd_init_struct.extended_mode = DISABLE; lcd_init_struct.asyn_wait = DISABLE; lcd_init_struct.nwait_signal = DISABLE; lcd_init_struct.memory_write = ENABLE; lcd_init_struct.nwait_config = EXMC_NWAIT_CONFIG_BEFORE; lcd_init_struct.wrap_burst_mode = DISABLE; lcd_init_struct.nwait_polarity = EXMC_NWAIT_POLARITY_LOW; lcd_init_struct.burst_mode = DISABLE; lcd_init_struct.databus_width = EXMC_NOR_DATABUS_WIDTH_16B; lcd_init_struct.memory_type = EXMC_MEMORY_TYPE_SRAM; lcd_init_struct.address_data_mux = DISABLE; lcd_init_struct.read_write_timing = &lcd_timing_init_struct; lcd_init_struct.write_timing = &lcd_timing_init_struct; exmc_norsram_init(&lcd_init_struct); exmc_norsram_enable(EXMC_BANK0_NORSRAM_REGION1); }   七、工程源码

  • 回复了主题帖: 【GD32E503评测】——06.通过差分ADC检测PT100传感器温度值

    ljjsw 发表于 2021-2-21 10:42 多谢大佬的分享啊,大佬的资料很详细很全面的哦

  • 2021-02-20
  • 发表了主题帖: 【GD32E503评测】——06.通过差分ADC检测PT100传感器温度值

    本帖最后由 xld0932 于 2021-2-20 23:35 编辑 一、PT100温度传感器 PT100温度传感器是一种将温度变量转换为可传送的标准化输出信号的仪表。主要用于工业过程温度参数的测量和控制。温度的采集范围可以在-200℃~+850℃。根据PT100引出线数可以分为2线制、3线制和4线制三种。   二、MAX31865至数字输出转换器 MAX31865是简单易用的热敏电阻至数字输出转换器,优化用于铂电阻温度检测器(RTD),适配100R至1000R铂电阻RTD(PT100至PT1000)。外部电阻设置RTD灵敏度,高精度Δ- Σ ADC将RTD电阻与基准电阻之比转换为数字输出。MAX31865输入具有高达±45V的过压保护,提供可配置的RTD及电缆开路、短路条件检测。 MAX31865接口为SPI接口,兼容于2线、3线和4线的传感器连接,采样达到了15位ADC分辨率,标称温度分辨率精确到了0.03125℃,最大转换时间不超过21ms。典型的应用电路如下所示: 三、硬件连接 我们使用LCD触摸屏的接口部分,正好有一个SPI接口,我们将MAX31865模块的接口与MCU的SPI相连接,并给MAX31865模块提供3.3V的工作电压,硬件连接图如下所示:   四、程序设计 配置与MAX31865通讯的SPI端口引脚、配置MAX31865寄存器;通过SHELL命令来调用温度读取函数: /******************************************************************************* * @file MAX31865.h * @author King * @version V1.00 * @date 08-Jan-2021 * @brief ...... ******************************************************************************* * @attention * *******************************************************************************/ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __MAX31865_H__ #define __MAX31865_H__ #ifdef __cplusplus extern "C" { #endif #undef EXTERN #ifdef __MAX31865_C__ #define EXTERN #else #define EXTERN extern #endif /* Includes ------------------------------------------------------------------*/ #include "config.h" /* Exported constants --------------------------------------------------------*/ #define SPI_SCLK_PORT GPIOA #define SPI_SCLK_PIN GPIO_PIN_5 #define SPI_MISO_PORT GPIOA #define SPI_MISO_PIN GPIO_PIN_6 #define SPI_MOSI_PORT GPIOA #define SPI_MOSI_PIN GPIO_PIN_7 #define SPI_CS_PORT GPIOE #define SPI_CS_PIN GPIO_PIN_4 /* Exported types ------------------------------------------------------------*/ /* Exported macro ------------------------------------------------------------*/ #define SPI_SCLK_L() gpio_bit_write(SPI_SCLK_PORT, SPI_SCLK_PIN, RESET) #define SPI_SCLK_H() gpio_bit_write(SPI_SCLK_PORT, SPI_SCLK_PIN, SET) #define SPI_MISO_READ() gpio_input_bit_get(SPI_MISO_PORT, SPI_MISO_PIN) #define SPI_MOSI_L() gpio_bit_write(SPI_MOSI_PORT, SPI_MOSI_PIN, RESET) #define SPI_MOSI_H() gpio_bit_write(SPI_MOSI_PORT, SPI_MOSI_PIN, SET) #define SPI_CS_L() gpio_bit_write(SPI_CS_PORT, SPI_CS_PIN, RESET) #define SPI_CS_H() gpio_bit_write(SPI_CS_PORT, SPI_CS_PIN, SET) /* Exported functions --------------------------------------------------------*/ EXTERN void MAX31865_Init(void); EXTERN void MAX31865_GetConversionValue(void); #ifdef __cplusplus } #endif #endif /******************* (C) COPYRIGHT 2021 *************************END OF FILE***/ /******************************************************************************* * @file MAX31865.c * @author King * @version V1.00 * @date 08-Jan-2021 * @brief ...... ******************************************************************************* * @attention * *******************************************************************************/ /* Define to prevent recursive inclusion -------------------------------------*/ #define __MAX31865_C__ /* Includes ------------------------------------------------------------------*/ #include "MAX31865.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ float Temperature = 0.0; /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ /* Exported variables --------------------------------------------------------*/ /* Exported function prototypes ----------------------------------------------*/ /******************************************************************************* * @brief * @param * @retval * @attention *******************************************************************************/ void MAX31865_Delay(void) { uint32_t i; i = 0x1000; while(i--); } /******************************************************************************* * @brief * @param * @retval * @attention *******************************************************************************/ void MAX31865_SCLK(uint8_t Level) { if(Level) SPI_SCLK_H(); else SPI_SCLK_L(); MAX31865_Delay(); } /******************************************************************************* * @brief * @param * @retval * @attention *******************************************************************************/ uint8_t MAX31865_MISO(void) { return SPI_MISO_READ(); } /******************************************************************************* * @brief * @param * @retval * @attention *******************************************************************************/ void MAX31865_MOSI(uint8_t Level) { if(Level) SPI_MOSI_H(); else SPI_MOSI_L(); MAX31865_Delay(); } /******************************************************************************* * @brief * @param * @retval * @attention *******************************************************************************/ void MAX31865_CS(uint8_t Enable) { if(Enable) SPI_CS_H(); else SPI_CS_L(); MAX31865_Delay(); } /******************************************************************************* * @brief * @param * @retval * @attention *******************************************************************************/ uint8_t MAX31865_ReadByte(void) { uint8_t i = 0, Data = 0; for(i = 0; i < 8; i++) { MAX31865_SCLK(0); Data <<= 1; if(MAX31865_MISO() == 1) { Data |= 0x01; } MAX31865_SCLK(1); } return Data; } /******************************************************************************* * @brief * @param * @retval * @attention *******************************************************************************/ void MAX31865_WriteByte(uint8_t Data) { uint8_t i = 0; MAX31865_SCLK(1); for(i = 0; i < 8; i++) { MAX31865_SCLK(0); if(Data & 0x80) { MAX31865_MOSI(1); } else { MAX31865_MOSI(0); } MAX31865_SCLK(1); Data <<= 1; } } /******************************************************************************* * @brief * @param * @retval * @attention *******************************************************************************/ uint8_t MAX31865_ReadREG(uint8_t Address) { uint8_t Value = 0; MAX31865_CS(0); MAX31865_WriteByte(Address); Value = MAX31865_ReadByte(); MAX31865_CS(1); return Value; } /******************************************************************************* * @brief * @param * @retval * @attention *******************************************************************************/ void MAX31865_WriteREG(uint8_t Address, uint8_t Value) { MAX31865_CS(0); MAX31865_WriteByte(Address); MAX31865_WriteByte(Value); MAX31865_CS(1); } /******************************************************************************* * @brief * @param * @retval * @attention *******************************************************************************/ void MAX31865_GetConversionValue(void) { unsigned int data; float Rt; float Rt0 = 100; //---PT100 float Z1,Z2,Z3,Z4,temp; float a = 3.9083e-3; float b = -5.7750e-7; float rpoly; data = MAX31865_ReadREG(0x01) << 8; data |= MAX31865_ReadREG(0x02); data>>=1; //---去掉Fault位 Rt=(float)data/32768.0*430; //---RREF=430 Z1 = -a; Z2 = a*a-4*b; Z3 = 4*b/Rt0; Z4 = 2*b; temp = Z2+Z3*Rt; temp = (sqrt(temp)+Z1)/Z4; if(temp >= 0) { printf("\r\nTemp : %0.1f\r\n", temp); } else { rpoly = Rt; temp = -242.02; temp += 2.2228 * rpoly; rpoly *= Rt; // square temp += 2.5859e-3 * rpoly; rpoly *= Rt; // ^3 temp -= 4.8260e-6 * rpoly; rpoly *= Rt; // ^4 temp -= 2.8183e-8 * rpoly; rpoly *= Rt; // ^5 temp += 1.5243e-10 * rpoly; printf("\r\nTemp : %0.3f\r\n", temp); } Temperature = temp; } SHELL_EXPORT_CMD(temp, MAX31865_GetConversionValue, read PT100 temperature); /******************************************************************************* * @brief * @param * @retval * @attention *******************************************************************************/ void MAX31865_InitGPIO(void) { rcu_periph_clock_enable(RCU_GPIOA); rcu_periph_clock_enable(RCU_GPIOE); gpio_init(SPI_SCLK_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SPI_SCLK_PIN); gpio_init(SPI_MOSI_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SPI_MOSI_PIN); gpio_init(SPI_MISO_PORT, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, SPI_MISO_PIN); gpio_init(SPI_CS_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SPI_CS_PIN); SPI_CS_H(); SPI_SCLK_H(); } /******************************************************************************* * @brief * @param * @retval * @attention *******************************************************************************/ void MAX31865_Init(void) { MAX31865_InitGPIO(); MAX31865_WriteREG(0x80, 0xC3); printf("\r\nMAX31865 Configuration : 0x%02x\r\n", MAX31865_ReadREG(0x00)); } /******************* (C) COPYRIGHT 2021 *************************END OF FILE***/   五、运行结果 程序编译无误后,下载到开发板运行;上电后我们看到MAX31865寄存器配置读取成功,输入SHELL命令temp来调用温度读取函数,将读到的温度值打印输出出来,如下图所示: 六、工程代码

  • 2021-02-18
  • 发表了主题帖: 【GD32E503评测】——05.LCD第一篇:测试刷屏速度

    本帖最后由 xld0932 于 2021-2-18 00:17 编辑 一、LCD部分原理图 LCD部分使用了GD32E503的EXMC(外部存储器控制器)这个外设,它是用来访问各种片外存储器,通过配置寄存器,EXMC可以把AMBA协议转换为专用的片外存储器通信协议, 包括SRAM,ROM,NOR Flash,NAND Flash,PC卡等等。它支持 8 位, 或 16 位总线带宽,所以比一般的SPI通讯来控制LCD显示的速度要快得多。 因为这个TFT是带有触摸接口的,所以在实现LCD触摸功能的时候,我们就不能实现DAC1的功能了,所以程序是基于之前SHELL的基础功能来实现的。   二、代码实现 我们基于官方提供的LCD底层驱动程序,将gd32e50x_lcd_eval.c、gd32e50x_lcd_eval.h、lcd_font.h文件添加到工程中,然后在项目BSP目录下再新建一个LCD.c和LCD.h文件,来实现我们自己需要完成的功能。 我们首先需要实现对LCD的初始化,初始化部分包含3个部分,分别是exmc外设配置、LCD的初始化、以及将LCD清屏成默认的颜色 /******************************************************************************* * @brief * @param * @retval * @attention *******************************************************************************/ void LCD_Init(void) { exmc_lcd_init(); lcd_init(); lcd_clear(LCD_COLOR_GREEN); TASK_Append(TASK_ID_LCD, LCD_Handler, 100); } 其次我们来通讯调用SHELL命令,结合TASK任务,来测试LCD在连续整屏填充数据的情况下所消耗的时间,从而来测算LCD的整屏刷新速度,具体代码实现如下: /******************************************************************************* * @brief * @param * @retval * @attention *******************************************************************************/ void LCD_TestClearSpeed(void) { uint16_t ColorTable[] = { LCD_COLOR_WHITE , LCD_COLOR_BLACK , LCD_COLOR_GREY , LCD_COLOR_BLUE , LCD_COLOR_BLUE2 , LCD_COLOR_RED , LCD_COLOR_MAGENTA, LCD_COLOR_GREEN , LCD_COLOR_CYAN , LCD_COLOR_YELLOW , }; BSP_SetRunTime(0); for(uint8_t i = 0; i < sizeof(ColorTable); i++) { lcd_clear(ColorTable); } printf("\r\n"); printf("\r\nLCD Clear Speed : %0.3fms", (float)BSP_GetRunTime() / 1000.0); printf("\r\n"); } uint8_t LCD_TestFlag = 0; /******************************************************************************* * @brief * @param * @retval * @attention *******************************************************************************/ void LCD_Handler(void) { if(LCD_TestFlag == 1) { LCD_TestFlag = 0; LCD_TestClearSpeed(); } } /******************************************************************************* * @brief * @param * @retval * @attention *******************************************************************************/ void LCD_TestHandler(void) { LCD_TestFlag = 1; } SHELL_EXPORT_CMD(lcd, LCD_TestHandler, test lcd clear speed);   三、运行结果 我们输入lcd这个SHELL命令,开始测试,待测试结束后会在屏幕上输出运行时间,如下图所示,连续刷新了10个整屏数据所占用的时间大概为308ms,分摊到一个整屏数据的填充时间大概需要30ms,这样的速度在更新显示时,LCD的显示频率计算得出大概在30帧左右的速度。   四、工程源码

  • 2021-02-17
  • 回复了主题帖: 【GD32E503评测】——04.MCU CoreMark性能测试

    w494143467 发表于 2021-2-17 14:51 测评写的不错,就喜欢你这样的测评帖子,感谢老铁的分享!期待后续
    谢谢

  • 2021-02-15
  • 加入了学习《DIY作品演示》,观看 GD32E503-EVAL实现按键控制DAC输出波形切换

  • 2021-02-14
  • 发表了主题帖: 【GD32E503评测】——04.MCU CoreMark性能测试

    本帖最后由 xld0932 于 2021-2-14 21:46 编辑     CoreMark是用来衡量嵌入式系统中中心处理单元(CPU,或叫做微控制器MCU)性能的标准。该标准于2009年由EEMBC组织的Shay Gla-On提出,并且试图将其发展成为工业标准,从而代替陈旧的Dhrystone标准。代码使用C语言写成,包含如下的运算法则:列举(寻找并排序),数学矩阵操作(普通矩阵运算)和状态机(用来确定输入流中是否包含有效数字),最后还包括CRC(循环冗余校验)。     为什么不用Dhrystone,而用CoreMark呢?Dhrystone是测量处理器运算能力的最常见基准程序之一,常用于处理器的整型运算性能的测量。程序是用C语言编写的,因此C编译器的编译效率对测试结果也有很大影响,所以Dhrystone还有许多漏洞,比如易被非法利用、人为痕迹明显、代码长度太短、缺乏验证及标准的运行规则等。       一、准备工作     1.1.到CoreMark官网上去下载开源的源代码:https://www.eembc.org/coremark/index.php(点击网页上的Download,然后跳转到GitHub上下载源代码)     1.2.在下载的CoreMark源码中,我们只使用到了simple中的port接口适配文件和根目录下的源文件     1.3.基础工程是基于上篇文章的代码上进行添加的;   二、移植CoreMark     2.1.将CoreMark源代码添加到项目工程,如下图所示     2.2.将工程的Optimization配置到O3级别,添加CoreMark的头文件路径,如下图所示:     2.3.修改原先的main函数,因为CoreMark代码自带一个main入口函数,所以需要屏蔽之前我们自己写的main函数,如所示: /******************************************************************************* * @brief * @param * @retval * @attention *******************************************************************************/ int user_main(void) { InitSystem(); while(1) { TASK_Scheduling(); MCU_DAC_OutputHandler(); } }     2.4.修改SysTick_Handler函数,用于CoreMark运算过程中的计时处理,如所示: /*! \brief this function handles SysTick exception \param[in] none \param[out] none \retval none */ void SysTick_Handler(void) { #if 0 SysTick_Tick++; TASK_TimeSlice(SysTick_Tick); #else CoreMark_IncTick(); #endif }     2.5.在core_portme.c文件中添加移植的代码,如下所示: /** * Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Original Author: Shay Gal-on */ /* Includes ------------------------------------------------------------------*/ #include "config.h" #include "coremark.h" /* Private defines ----------------------------------------------------------*/ #define ITERATIONS 6000 /* Private variables --------------------------------------------------------*/ volatile uint8_t stop_time_flg = 1; /* Exported function prototypes ---------------------------------------------*/ extern void InitSystem(void); #if VALIDATION_RUN volatile ee_s32 seed1_volatile = 0x3415; volatile ee_s32 seed2_volatile = 0x3415; volatile ee_s32 seed3_volatile = 0x66; #endif #if PERFORMANCE_RUN volatile ee_s32 seed1_volatile = 0x0; volatile ee_s32 seed2_volatile = 0x0; volatile ee_s32 seed3_volatile = 0x66; #endif #if PROFILE_RUN volatile ee_s32 seed1_volatile = 0x8; volatile ee_s32 seed2_volatile = 0x8; volatile ee_s32 seed3_volatile = 0x8; #endif volatile ee_s32 seed4_volatile = ITERATIONS; volatile ee_s32 seed5_volatile = 0x0; /** * Porting : Timing functions * How to capture time and convert to seconds must be ported to whatever is supported by the platform. * e.g. Read value from on board RTC, read value from cpu clock cycles performance counter etc. * Sample implementation for standard time.h and windows.h definitions included. */ /** * Define : TIMER_RES_DIVIDER * Divider to trade off timer resolution and total time that can be measured. * * Use lower values to increase resolution, but make sure that overflow does not occur. * If there are issues with the return value overflowing, increase this value. */ #define NSECS_PER_SEC 1000 #define CORETIMETYPE clock_t #define MYTIMEDIFF(fin,ini) ((fin)-(ini)) #define TIMER_RES_DIVIDER 1 #define EE_TICKS_PER_SEC (NSECS_PER_SEC / TIMER_RES_DIVIDER) /** * Define Host specific (POSIX), or target specific global time variables. */ static CORETIMETYPE start_time_val = 0, stop_time_val = 0; /** * Function : start_time * This function will be called right before starting the timed portion of the benchmark. * * Implementation may be capturing a system timer (as implemented in the example code) * or zeroing some system parameters - e.g. setting the cpu clocks cycles to 0. */ void start_time(void) { stop_time_flg = 0; stop_time_val = 0; } /** * Function : stop_time * This function will be called right after ending the timed portion of the benchmark. * * Implementation may be capturing a system timer (as implemented in the example code) * or other system parameters - e.g. reading the current value of cpu cycles counter. */ void stop_time(void) { stop_time_flg = 1; } /** * Function : get_time * Return an abstract "ticks" number that signifies time on the system. * * Actual value returned may be cpu cycles, milliseconds or any other value, * as long as it can be converted to seconds by <time_in_secs>. * This methodology is taken to accomodate any hardware or simulated platform. * The sample implementation returns millisecs by default, * and the resolution is controlled by <TIMER_RES_DIVIDER> */ CORE_TICKS get_time(void) { CORE_TICKS elapsed=(CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val)); return elapsed; } /** * Function : time_in_secs * Convert the value returned by get_time to seconds. * * The <secs_ret> type is used to accomodate systems with no support for floating point. * Default implementation implemented by the EE_TICKS_PER_SEC macro above. */ secs_ret time_in_secs(CORE_TICKS ticks) { secs_ret retval=((secs_ret)ticks) / (secs_ret)EE_TICKS_PER_SEC; return retval; } ee_u32 default_num_contexts = 1; /** * Function : portable_init * Target specific initialization code * Test for some common mistakes. */ void portable_init(core_portable *p, int *argc, char *argv[]) { InitSystem(); if (sizeof(ee_ptr_int) != sizeof(ee_u8 *)) { ee_printf("ERROR! Please define ee_ptr_int to a type that holds a pointer!\n"); } if (sizeof(ee_u32) != 4) { ee_printf("ERROR! Please define ee_u32 to a 32b unsigned type!\n"); } p->portable_id=1; } /** * Function : portable_fini * Target specific final code */ void portable_fini(core_portable *p) { p->portable_id=0; } /** * @brief : time.h * @param : * @returns: * @details: */ void CoreMark_IncTick(void) { if(stop_time_flg == 0) stop_time_val++; } /************************ (C) COPYRIGHT ************************END OF FILE****/   三、运行调试     将程序都移植完成后,对项目工程进行编译,编译无误后下载到开发板进行运行测试;     在第一次下载运行后,串口就输出“ERROR! Must execute for at least 10 secs for a valid result!”的错误提示,如下图所示:     执行的时间小于了10秒钟,我们修改了core_portme.c中的ITERATIONS这个宏定义值,将原先的2500修改到6000,再次尝试运行时,程序运行正常,测试结果如下所示:     从上图我们可以看到CoreMark的测试结果值为576.6,当然这是基于上一个工程的基础上做的一个移植,程序运行还有可优化的空间,后面再继续研究!   四、源代码

  • 2021-01-26
  • 发表了主题帖: 【GD32E503评测】——03.按键控制DAC切换输出波形

    本帖最后由 xld0932 于 2021-1-26 11:11 编辑     本篇主要实现功能为通过检测按键值,来控制DAC切换输出的波形;DAC输出波形有空电平、满电平、正弦波、三角波、矩形波;主要由2个部分组成,一个是按键检测及处理、另一个就是DAC的波形输出部分。     一、按键部分     1.1、按键原理图:     1.2、按键端口宏定义及结构体定义     1.3、按键数组     1.4、按键初始化     1.5、按键扫描     1.6、按键运行结果     二、DAC部分     2.1、DAC原理图:在DAC输出时,需要设置一下JP12这个跳线设置     2.2、DAC初始化     2.3、DAC输出电平     2.4、DAC输出正弦波、三角波、矩形波     三、运行结果     四、工程代码

  • 2021-01-25
  • 加入了学习《DIY作品演示》,观看 GD32E503-EVAL实现LED闪烁

  • 2021-01-11
  • 发表了主题帖: 【GD32E503评测】——02.从零开始(新建工程、LED闪烁、SHELL移植)

    本帖最后由 xld0932 于 2021-1-11 21:46 编辑 一、新建工程 1、我们使用的是KEIL集成开发环境,上个帖子我们已经安装过了芯片的PACK包,下载了芯片的驱动库程序,这两个是我们需要提前准备的; 2、打开KEIL软件,点击菜单栏Project->New uVision Project... 3、在弹出的Create New Project窗口中选择好项目工程存放的路径,输入工程名称,点击保存; 4、在弹出的Select Device for Target窗口中,选择芯片的型号:GD32E503VE,然后点击OK; 5、在弹出的Manage Run-Time Environment窗口中,选择CMSIS下面的CORE选项,然后点击OK;至此一个基于GD32E503的KEIL空工程就创建完成了,接下来我们需要在工程中添加代码和对工程进行配置; 6、点击工具栏上的Manage Project Items图标,在弹出的窗口中修改和添加源代码,如下图所示;最后点击OK; 7、点击工具样上的Options for Target...图标,在弹出的窗口中对项目工程进行参数设置; 8、在Target选项卡中,Code Generation中的ARM Compiler选择Use default compiler version 6,勾选Use MicroLIB; 9、在Output选项卡中,勾选Create HEX File; 10、在C/C++(AC86)选项卡中,Preprocessor Symbols中的Define添加宏定义,在Include Paths中添加需要包含的文件路径; 11、在Debug选项卡中,选择Use CMSIS-DAP ARMv8-M Debugger; 12、在Utilities选项卡中,勾选Use Debug Driver,点击Setting按键,在弹出的窗口中勾选Reset and Run选项,其后点击OK,再次点击Options for Target窗口中的OK;至此工程就配置完成了;   二、LED灯闪烁 1、硬件原理图:LED灯是通过GPIO口直接驱动的,所以当GPIO端口引脚为高电平时LED点亮,当GPIO端口引脚为低电平时LED灯熄灭; 2、LED头文件:定义了每个LED控制引脚的时钟、端口和引脚 3、LED源文件:实现了对LED灯的初始化,并创建了一个LED的TASK任务,这个任务是每间隔250毫秒调用一次LED_Handler函数;LED_Handler函数实现了对4个LED灯的闪烁控制;   三、移植Letter-shell 1、Letter-shell是一个C语言编写的,可以嵌入在程序中的嵌入式shell,主要面向嵌入式设备,以C语言函数为运行单位,可以通过命令行调用,运行程序中的函数;它是程序在运行时的一个极其方便一个调试助手,本文移植的是Letter-shell 2.x的版本;开源代码链接:https://gitee.com/smallqing/letter-shell; 2、Letter-shell是基于串口的,正好开发板上将USART0通过MiniUSB接口引出来了,方便我们调试监控和打印信息,所以我们需要对USART0进行初始化配置; 3、配置USART0,移植Letter-shell;   四、编译下载运行程序 1、将程序完善后,对整个工程进行编译,编译无误后将程序下载到开发板运行; 2、打开串口调试助手,在程序复位后运行,打印如下消息,当输入help并回车后,显示当前SHELL支持的命令,说明串口配置是SHELL移植是正确的; 3、观察开发板的运行情况,看到4个LED灯每间隔250毫秒的时间进行一次翻转操作; 五、工程源程序  

  • 2021-01-04
  • 回复了主题帖: 【GD32E503评测】——step01.开启体验国产M33之旅

    楼主好文采

  • 回复了主题帖: 【GD32E503评测】——01.准备工作

    yang377156216 发表于 2021-1-4 13:33 开篇精彩!
    后面更精彩

  • 发表了主题帖: 【GD32E503评测】——01.准备工作

    本帖最后由 xld0932 于 2021-1-4 13:04 编辑 一、元旦收到了开发,开心 二、上电测试     开发板上有3个USB接口,分为板载的GD-LINK、USART调试口、USBD接口;通过Mini-USB线给开发板供电,需要注意的是只有GD-LINK和USBD这两个USB接口可以给开发板供电、USART调试接口没有供电功能;开发板上电后,运行是例程16_EXMC_TouchScreen,在显示屏上显示4个LED灯的控制按钮,通过触控相应的图标来实现对LED灯的控制。   三、开发环境及其它准备工作 3.1、开发IDE环境使用Keil的MDK-ARM 3.2、到GD32的官网下载GD32E503V芯片的PACK支持包进行安装(我使用的是KEIL,所以安装的是Keil目录下的可执行程序),下载链接:http://www.gd32mcu.com/data/documents/yingyongruanjian/GD32E50x_AddOn_V1.1.0.rar 3.3、GD32E503xx芯片数据手册(英文版):http://www.gd32mcu.com/data/documents/shujushouce/GD32E503xx_Datasheet_Rev1.1.pdf 3.4、GD32E50x_用户手册(中文版):http://www.gd32mcu.com/data/documents/yingyongbiji/GD32E50x_yonghushouce_Rev1.1.pdf 3.5、GD32E50x系列MCU标准固件库:http://www.gd32mcu.com/data/documents/yingyongruanjian/GD32E50x_Firmware_Library_V1.1.0.rar 3.6、GD32E50x系列开发板例程及评估板用户指南:http://www.gd32mcu.com/data/documents/kaifaban/GD32E50x_Demo_Suites_V1.1.0.rar   四、下载例程     我们收到的开发型号为GD32E503V_EVAL,所以我在下载的GD32E50x系列开发板例程及评估板用户指南中找到GD32E503V_EVAL_Demo_Suites文件夹,其中Docs文件夹中存放是原理图和一些入门手册,Projects中存放的就是对应和例程,Utilities文件夹则是存放的一些公用文件和配置程序;     我们使用KEIL软件打开Projects\01_GPIO_Running_LED\MDK-ARM\中的工程,我们需要修改一下调试工具的配置:点击KEIL工具栏上的魔法棒,在弹出的窗口中选择Debug选项卡,如下图所示,选择CMSIS-DAP ARMv8-M Debugger(因为我们使用的是开发板板载的GD-LINK调试工具),当我们点击后面Settings的时候,我们可以在弹出的窗口中检测到芯片的序号:     当下载调试工具配置OK后,我们就可以对进行进行编译和下载了。将编译无误的程序下载到开发板后,我们发现LCD液晶显示屏熄灭了,LED灯在间隔顺序闪烁。

  • 2020-12-30
  • 回复了主题帖: 测评入围名单:免费评测GD32E503V-EVAL(M33、带屏)

    个人信息确认无误,可以参加测评!

  • 回复了主题帖: 测评入围名单:免费评测GD32E503V-EVAL(M33、带屏)

    本帖最后由 xld0932 于 2020-12-30 15:29 编辑 个人信息无误,确认可以完成评测计划。

  • 回复了主题帖: 测评入围名单:免费评测GD32E503V-EVAL(M33、带屏)

    本帖最后由 xld0932 于 2020-12-30 15:27 编辑 个人信息无误,确认可以完成评测计划   1、熟悉开发板、搭建开发环境、创建基础工程(GPIO控制LED闪烁); 2、基于基础工程,实现UART的收发验证,移植letter-shell作为调试端口,为后面的功能验证准备; 3、DAC的输出精度、幅值测试、输出三角波、矩形波、正弦波、其它等波形; 4、MCU CoreMark性能测试; 5、基于开发板移植GUI:LittlevGL,测试显示性能和刷新频率速度; 6、差分ADC应用测试,检测PT100传感器温度值;

  • 2020-11-05
  • 回复了主题帖: 【MM32 eMiniBoard测评】2a. 发现虚拟串口可能有问题,串口例程也不能接收

    我也遇到了楼主的问题,刚开始以为是硬件连接的问题,在看了数据手册后发现PA9\PA10这两个引脚既可以做为TX也可以作为RX,所以硬件上没有问题;后面我尝试跟原厂的工程师沟通了一下,他们回复不建议使用板载的USB CDC的虚拟串口功能;板载上有用端子将UART2直接引出来了,可以外接一个USB转串口调试工具,也可以通过排针将UART1的引脚接到USB转串口工具去调试

最近访客

< 1/4 >

统计信息

已有118人来访过

  • 芯币:253
  • 好友:--
  • 主题:18
  • 回复:39
  • 课时:3
  • 资源:--

留言

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


现在还没有留言