发作品签到
专业版

天空星GD32高频信号发生器

工程标签

989
0
0
2

简介

天空星GD32开发板高频信号发生器扩展版

简介:天空星GD32开发板高频信号发生器扩展版
立创·天空星扩展板征集令

开源协议

GPL 3.0

创建时间:2024-09-09 10:42:17更新时间:2024-10-28 01:20:34

描述

开源协议

GPL V3.0

  • GPL的条款和条件必须提供给任何接受GPL应用的作品的副本(“被许可人”)的人员。
  • 任何遵守条款和条件的被授证人员都有权修改作品,以及复制和重新分发作品或任何派生版本。
  • GPL下的软件可以用于所有目的,包括商业目的,甚至作为创建专有软件的工具,例如使用GPL许可的编译器时,分发 GPL许可作品(如软件)的用户或公司可能会收取副本费用或无偿提供费用。

项目参数

  • 使用GD32F407天空星开发板作为系统主控,进行官方标准库软件适配
  • 使用AD9910 DDS作为信号发生器源,工作频率1GHz,可产生480MHz正弦
  • 实现任意波形生成,数字斜坡扫频,可调频调幅调相
  • 采用2.4寸lcd屏与六个按键实现菜单操作
  • 使用lvgl库实现gui,使用SPI+DMA+双缓存,最大程度优化性能

实物展示

原理图设计

电源框架

AD9910电源树.png
AD9910需要的电源域比较复杂,整个系统主要分为6路电源
5V主电源:typec口或插座提供5V输入,经过双磁珠电容滤波后,用于给开发板供电以及后级的降压电路
QQ截图20241022193429.png
3.3V主电源:由5V经过SY8113BADC DCDC降压得到,用于屏幕等供电
QQ截图20241022193650.png
3.3V模拟电源与数字电源: 由3.3V主电源经过磁珠隔离得来,用于AD9910的AVDD3V3,DVDD3V3供电
QQ截图20241022195701.png
1.8V模拟电源与数字电源: 由3.3V主电源经过两路TP5108 LDO降压得到,用于AD9910的AVDD1V8,DVDD1V8供电
QQ截图20241022193942(2).png

时钟源

AD9910使用一个外部时钟源输入,这里使用40MHz有源晶振,3.3V经过磁珠后供电
QQ截图20241022201009(1).png

输出滤波电路

DDS输出需要经过LC低通滤波电路,DDS系统中的基本输出频率高阶谐波会因混叠而折回至基带,使用低通滤波过滤高频谐波分量,会产生一定相移,导致两端输出并不是完全的180度差分
QQ截图20241022201305.png

其他

剩下的一些设计是2.4寸屏幕,六个按键,引出的排针等等

PCB设计

本项目涉及的频率较高,PCB使用了四层板,中间一层铺模拟地,其余全铺GND,本人经验不足,如有错误欢迎指出
QQ20241026-003827.png
有一些值得注意的点:
晶振部分做了包地打过孔,以及裸露禁止铺铜的处理
QQ截图20241022202014.png
DCDC的布局走线参考与数据手册,主要使用填充区域走线
QQ截图20241022202551.png
AD9910支持并行输入,因开发板限制,本项目使用的是串行输入,但是这里把并口也引出排针,并做了等长组处理
QQ截图20241022202821.png

软件设计

软件层面主要包括四个部分:GD32F407驱动,AD9910驱动,LVGL驱动,GUI菜单
这里只是介绍框架,详细内容请看附件中的工程代码

GD32F407驱动

本项目使用官方下载的标准库,涉及的外设为GPIO,SPI,DMA,TIMER等等,更详细的GD32资料可以去开发板文档查阅学习:https://wiki.lckfb.com/zh-hans/
引脚以及外设配置可以查看官方数据手册与标准库中的example
为了达到最大性能的屏幕显示,重点在于spi与dma的使用

void LCD_SPI_Init(void)
{
          /* 开启各引脚时钟 */
        rcu_periph_clock_enable(RCU_LCD_SCL);
        rcu_periph_clock_enable(RCU_LCD_SDA);
        rcu_periph_clock_enable(RCU_LCD_CS);
        rcu_periph_clock_enable(RCU_LCD_DC);
        rcu_periph_clock_enable(RCU_LCD_RES);
          /* 使能SPI */
        rcu_periph_clock_enable(RCU_SPI_HARDWARE);

          /* 配置 SPI的SCK GPIO */
        gpio_af_set(PORT_LCD_SCL, LINE_AF_SPI, GPIO_LCD_SCL);
        gpio_mode_set(PORT_LCD_SCL, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_LCD_SCL);
        gpio_output_options_set(PORT_LCD_SCL, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_LCD_SCL);
        gpio_bit_set(PORT_LCD_SCL,GPIO_LCD_SCL);
          /* 配置 SPI的MOSI  GPIO */
        gpio_af_set(PORT_LCD_SDA, LINE_AF_SPI, GPIO_LCD_SDA);
        gpio_mode_set(PORT_LCD_SDA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_LCD_SDA);
        gpio_output_options_set(PORT_LCD_SDA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_LCD_SDA);
        gpio_bit_set(PORT_LCD_SDA, GPIO_LCD_SDA);
           /* 配置DC */
        gpio_mode_set(PORT_LCD_DC,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,GPIO_LCD_DC);
        gpio_output_options_set(PORT_LCD_DC,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_LCD_DC);
        gpio_bit_write(PORT_LCD_DC, GPIO_LCD_DC, SET);
           /* 配置RES */
        gpio_mode_set(PORT_LCD_RES,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,GPIO_LCD_RES);
        gpio_output_options_set(PORT_LCD_RES,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_LCD_RES);
        gpio_bit_write(PORT_LCD_RES, GPIO_LCD_RES, SET);
           /* 配置CS */
        gpio_mode_set(PORT_LCD_CS,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,GPIO_LCD_CS);
        gpio_output_options_set(PORT_LCD_CS,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_LCD_CS);
        gpio_bit_write(PORT_LCD_CS, GPIO_LCD_CS, SET);

        /* 配置 SPI 参数 */
		spi_parameter_struct spi_init_struct;
		spi_i2s_deinit(SPI0);
        spi_init_struct.trans_mode           = SPI_TRANSMODE_FULLDUPLEX;  // 传输模式全双工
        spi_init_struct.device_mode          = SPI_MASTER;   // 配置为主机
        spi_init_struct.frame_size           = SPI_FRAMESIZE_8BIT; // 8位数据
        spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;
        spi_init_struct.nss                  = SPI_NSS_SOFT;  // 软件cs
        spi_init_struct.prescale             = SPI_PSC_2;//2分频
        spi_init_struct.endian               = SPI_ENDIAN_MSB;
        spi_init(SPI0, &spi_init_struct);

        /* 使能 SPI */
        spi_enable(SPI0);
		spi_dma_enable(SPI0,SPI_DMA_TRANSMIT);
		
		rcu_periph_clock_enable(BSP_DMA_RCU); 
    
		/* SPI0 transmit dma config:DMA1-DMA_CH3  */
		dma_deinit(DMA1, DMA_CH5);
		dma_init_struct.periph_addr  		= (uint32_t)(&SPI_DATA(SPI0));
		dma_init_struct.memory0_addr  		= 0;
		dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT;
		dma_init_struct.priority     		= DMA_PRIORITY_ULTRA_HIGH;
		dma_init_struct.number       		= 0;
		dma_init_struct.periph_inc   		= DMA_PERIPH_INCREASE_DISABLE;
		dma_init_struct.memory_inc   		= DMA_MEMORY_INCREASE_ENABLE;
		dma_init_struct.direction	 		= DMA_MEMORY_TO_PERIPH; 
		dma_init_struct.circular_mode		= DMA_CIRCULAR_MODE_DISABLE;
		dma_single_data_mode_init(DMA1, DMA_CH5, &dma_init_struct);
		/* configure DMA mode */
		
		dma_channel_subperipheral_select(DMA1, DMA_CH5, DMA_SUBPERI3);
		dma_channel_disable(DMA1,DMA_CH5);	
}

GD32允许SPI配置了DMA后不使用DMA而直接SPI发送,故我们更改LCD的读写逻辑:对于少量数据如寄存器配置,发送指令等等,采用硬件spi直接发送;对于LVGL屏幕周期刷新任务,数据量较大,采用DMA一次性发送
两个发送函数:

void SPI_Transmit_DMA(uint8_t* data,uint32_t Size)
{
	swap_high_low_8bits(data, Size);//交换每一个16位颜色数据中的高八位与第八位,否则LVGL色彩会有bug,应当视实际情况调试
	dma_init_struct.memory0_addr  		= (uint32_t)data;
	dma_init_struct.number       		= Size;
	dma_single_data_mode_init(DMA1, DMA_CH5, &dma_init_struct);

	dma_channel_enable(DMA1,DMA_CH5);	
	while(dma_flag_get(DMA1,DMA_CH5,DMA_FLAG_FTF)!= SET){}
	dma_flag_clear(DMA1,DMA_CH5,DMA_FLAG_FTF);
	dma_channel_disable(DMA1,DMA_CH5);
}

void SPI_Transmit(uint8_t* data,uint32_t Size){
	for(int i=0;ix2 - area->x1 + 1) * (area->y2 - area->y1 + 1) * 2;
	LCD_Address_Set(area->x1, area->y1, area->x2, area->y2);
	LCD_CS_Clr();
	SPI_Transmit_DMA((uint8_t*)color_p,size);
	LCD_CS_Set();
    /*IMPORTANT!!!
     *Inform the graphics library that you are ready with the flushing*/
    lv_disp_flush_ready(disp_drv);
}

AD9910驱动

整体使用GPIO模拟硬件SPI时序的方式驱动AD9910,对于需要动态改变的工作参数来说,驱动程序还需要支持快速调整DDS工作参数的功能,这可以通过修改内部的频率控制字(FCW)来实现。
驱动AD9910的第一步是要对其进行初始化和配置。这包括但不限于设置工作模式、输出频率、相位偏移、输出幅度等。驱动程序首先包含初始化函数,确保AD9910在启动时能够正确配置。

void AD9910_IOInit(void)
{	
	rcu_periph_clock_enable(RCU_GPIOB);
	rcu_periph_clock_enable(RCU_GPIOC);
	rcu_periph_clock_enable(RCU_GPIOD);
	rcu_periph_clock_enable(RCU_GPIOE);
	
	gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, (GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9));
	gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, (GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9));

	gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO_PIN_0);
	gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0);
	
	gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, (GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_7));
	gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, (GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_7));
	
	gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_3));
	gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_3));
}

void Init_AD9910(void)
{
    uchar k, m;

    AD9910_IOInit();//IO初始化
    AD9910_PWR_0;//软件拉低

    PROFILE2_0;
	PROFILE1_0;
	PROFILE0_0;
    DRCTL_0;
    DRHOLD_0;
    MAS_REST_1;
    delay_ms(5);
    MAS_REST_0;

    CS_0;
    txd_8bit(0x00);    //发送CFR1控制字地址
    for (m = 0; m < 4; m++)
        txd_8bit(cfr1[m]);
    CS_1;
    for (k = 0; k < 10; k++);

    CS_0;
    txd_8bit(0x01);    //发送CFR2控制字地址
    for (m = 0; m < 4; m++)
        txd_8bit(cfr2[m]);
    CS_1;
    for (k = 0; k < 10; k++);

    CS_0;
    txd_8bit(0x02);    //发送CFR3控制字地址
    for (m = 0; m < 4; m++)
        txd_8bit(cfr3[m]);
    CS_1;
    for (k = 0; k < 10; k++);

    UP_DAT_1;
    for(k = 0; k < 10; k++);
    UP_DAT_0;
    delay_ms(1);

}

AD官方还发过AD9910的评估软件,可以用来菜单化操作,通过配置生成内部寄存器的值
QQ截图20241022203941.png
链接:https://www.analog.com/cn/resources/evaluation-hardware-and-software/evaluation-boards-kits/EVAL-AD9910.html

GUI菜单

GUI的设计使用NXP的GUIGUIDER软件,免费但是功能可能没有squareline studio多,菜单采用多级菜单的形式,例如主界面->波形生成->正弦波。
屏幕截图 2024-10-25 180232.png
GUI制作用到了开源的GUI图形库LVGL,主要使用了Label、Button、Spinbox等控件。关于人机交互,则是使用主板上的五个按键,可以实现界面跳转,功能选择以及波形参数的配置。

void setup_scr_MainScreen(lv_ui *ui)
{
	//Write codes MainScreen
	ui->MainScreen = lv_obj_create(NULL);
	lv_obj_set_size(ui->MainScreen, 320, 240);
	lv_obj_set_scrollbar_mode(ui->MainScreen, LV_SCROLLBAR_MODE_OFF);

	//Write style for MainScreen, Part: LV_PART_MAIN, State: LV_STATE_DEFAULT.
	lv_obj_set_style_bg_opa(ui->MainScreen, 255, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_color(ui->MainScreen, lv_color_hex(0xffcfb0), LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_grad_dir(ui->MainScreen, LV_GRAD_DIR_NONE, LV_PART_MAIN|LV_STATE_DEFAULT);

	//Write codes MainScreen_label_1
	ui->MainScreen_label_1 = lv_label_create(ui->MainScreen);
	lv_label_set_text(ui->MainScreen_label_1, "AD9910\nWaveGenerator");
	lv_label_set_long_mode(ui->MainScreen_label_1, LV_LABEL_LONG_WRAP);
	lv_obj_set_pos(ui->MainScreen_label_1, 73, 33);
	lv_obj_set_size(ui->MainScreen_label_1, 174, 41);

	//Write style for MainScreen_label_1, Part: LV_PART_MAIN, State: LV_STATE_DEFAULT.
	lv_obj_set_style_border_width(ui->MainScreen_label_1, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_radius(ui->MainScreen_label_1, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_color(ui->MainScreen_label_1, lv_color_hex(0x000000), LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_font(ui->MainScreen_label_1, &lv_font_SourceHanSerifSC_Regular_18, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_opa(ui->MainScreen_label_1, 255, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_letter_space(ui->MainScreen_label_1, 2, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_line_space(ui->MainScreen_label_1, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_align(ui->MainScreen_label_1, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_opa(ui->MainScreen_label_1, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_pad_top(ui->MainScreen_label_1, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_pad_right(ui->MainScreen_label_1, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_pad_bottom(ui->MainScreen_label_1, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_pad_left(ui->MainScreen_label_1, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_shadow_width(ui->MainScreen_label_1, 0, LV_PART_MAIN|LV_STATE_DEFAULT);

	//Write codes MainScreen_btn_1
	ui->MainScreen_btn_1 = lv_btn_create(ui->MainScreen);
	ui->MainScreen_btn_1_label = lv_label_create(ui->MainScreen_btn_1);
	lv_label_set_text(ui->MainScreen_btn_1_label, "WaveGenerate");
	lv_label_set_long_mode(ui->MainScreen_btn_1_label, LV_LABEL_LONG_WRAP);
	lv_obj_align(ui->MainScreen_btn_1_label, LV_ALIGN_CENTER, 0, 0);
	lv_obj_set_style_pad_all(ui->MainScreen_btn_1, 0, LV_STATE_DEFAULT);
	lv_obj_set_width(ui->MainScreen_btn_1_label, LV_PCT(100));
	lv_obj_set_pos(ui->MainScreen_btn_1, 83, 92);
	lv_obj_set_size(ui->MainScreen_btn_1, 159, 24);

	//Write style for MainScreen_btn_1, Part: LV_PART_MAIN, State: LV_STATE_DEFAULT.
	lv_obj_set_style_bg_opa(ui->MainScreen_btn_1, 255, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_color(ui->MainScreen_btn_1, lv_color_hex(0xff6500), LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_grad_dir(ui->MainScreen_btn_1, LV_GRAD_DIR_NONE, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_border_width(ui->MainScreen_btn_1, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_radius(ui->MainScreen_btn_1, 5, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_shadow_width(ui->MainScreen_btn_1, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_color(ui->MainScreen_btn_1, lv_color_hex(0x000000), LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_font(ui->MainScreen_btn_1, &lv_font_montserratMedium_16, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_opa(ui->MainScreen_btn_1, 255, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_align(ui->MainScreen_btn_1, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN|LV_STATE_DEFAULT);

	//Write codes MainScreen_btn_2
	ui->MainScreen_btn_2 = lv_btn_create(ui->MainScreen);
	ui->MainScreen_btn_2_label = lv_label_create(ui->MainScreen_btn_2);
	lv_label_set_text(ui->MainScreen_btn_2_label, "Modulate");
	lv_label_set_long_mode(ui->MainScreen_btn_2_label, LV_LABEL_LONG_WRAP);
	lv_obj_align(ui->MainScreen_btn_2_label, LV_ALIGN_CENTER, 0, 0);
	lv_obj_set_style_pad_all(ui->MainScreen_btn_2, 0, LV_STATE_DEFAULT);
	lv_obj_set_width(ui->MainScreen_btn_2_label, LV_PCT(100));
	lv_obj_set_pos(ui->MainScreen_btn_2, 83, 134);
	lv_obj_set_size(ui->MainScreen_btn_2, 159, 24);

	//Write style for MainScreen_btn_2, Part: LV_PART_MAIN, State: LV_STATE_DEFAULT.
	lv_obj_set_style_bg_opa(ui->MainScreen_btn_2, 255, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_color(ui->MainScreen_btn_2, lv_color_hex(0xff6500), LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_grad_dir(ui->MainScreen_btn_2, LV_GRAD_DIR_NONE, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_border_width(ui->MainScreen_btn_2, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_radius(ui->MainScreen_btn_2, 5, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_shadow_width(ui->MainScreen_btn_2, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_color(ui->MainScreen_btn_2, lv_color_hex(0x000000), LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_font(ui->MainScreen_btn_2, &lv_font_montserratMedium_16, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_opa(ui->MainScreen_btn_2, 255, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_align(ui->MainScreen_btn_2, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN|LV_STATE_DEFAULT);

	//Write codes MainScreen_btn_3
	ui->MainScreen_btn_3 = lv_btn_create(ui->MainScreen);
	ui->MainScreen_btn_3_label = lv_label_create(ui->MainScreen_btn_3);
	lv_label_set_text(ui->MainScreen_btn_3_label, "FreqSweep");
	lv_label_set_long_mode(ui->MainScreen_btn_3_label, LV_LABEL_LONG_WRAP);
	lv_obj_align(ui->MainScreen_btn_3_label, LV_ALIGN_CENTER, 0, 0);
	lv_obj_set_style_pad_all(ui->MainScreen_btn_3, 0, LV_STATE_DEFAULT);
	lv_obj_set_width(ui->MainScreen_btn_3_label, LV_PCT(100));
	lv_obj_set_pos(ui->MainScreen_btn_3, 83, 176);
	lv_obj_set_size(ui->MainScreen_btn_3, 159, 24);

	//Write style for MainScreen_btn_3, Part: LV_PART_MAIN, State: LV_STATE_DEFAULT.
	lv_obj_set_style_bg_opa(ui->MainScreen_btn_3, 255, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_color(ui->MainScreen_btn_3, lv_color_hex(0xff6500), LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_grad_dir(ui->MainScreen_btn_3, LV_GRAD_DIR_NONE, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_border_width(ui->MainScreen_btn_3, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_radius(ui->MainScreen_btn_3, 5, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_shadow_width(ui->MainScreen_btn_3, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_color(ui->MainScreen_btn_3, lv_color_hex(0x000000), LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_font(ui->MainScreen_btn_3, &lv_font_montserratMedium_16, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_opa(ui->MainScreen_btn_3, 255, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_align(ui->MainScreen_btn_3, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN|LV_STATE_DEFAULT);

	//The custom code of MainScreen.
	
	lv_group_focus_obj(ui->MainScreen_btn_1);
	//Update current screen layout.
	lv_obj_update_layout(ui->MainScreen);

	//绑定组1和设备
    groupRect_MainScreen = lv_group_create();  //创建组1
    //挂载组1的控件,包括加减按钮以及指向下一个界面的按钮
    lv_group_add_obj(groupRect_MainScreen,ui->MainScreen_btn_1);
    lv_group_add_obj(groupRect_MainScreen,ui->MainScreen_btn_2);
	lv_group_add_obj(groupRect_MainScreen,ui->MainScreen_btn_3);
    //绑定外部设备
    lv_indev_set_group(indev_keypad,groupRect_MainScreen);

	//Init events for screen.
	events_init_MainScreen(ui);
}

注意事项

AD9910芯片价格比较高,本项目的芯片来源于某宝购买,测试使用无问题,一般价格不会低于100
开发板与扩展版安装方式:
IMG_20241024_191511.jpg

参考项目

感谢大佬的开源贡献:https://oshwhub.com/cheerfulness/Oscilloscope-and-High-Frequency-Signal-Generator-Based-on-STM32

设计图

未生成预览图,请在编辑器重新保存一次

BOM

暂无BOM

附件

序号文件名称下载次数
1
AD9910_final.7z
97
克隆工程
添加到专辑
0
0
分享
侵权投诉

工程成员

评论

全部评论(1)
按时间排序|按热度排序
粉丝0|获赞0
相关工程
暂无相关工程

底部导航