[活动专区] 【N32G401征文】空调控制面板以及常见外设驱动配置

[复制链接]
 楼主| Wayneso 发表于 2024-1-11 14:48 | 显示全部楼层 |阅读模式
#技术资源# #申请开发板# #申请原创#        手上目前有一块N32G401F8S7-1,一共20个引脚。用这个芯片简单制作了一个空调控制面板,用到了一些常用的外设驱动。N32G401这块芯片性价比是可以的,不过由于是新出的芯片,目前很多网络上对这块芯片的资料并不多,更多的是借鉴官方的操作手册以及例程,所以,本人将自己在制作空调控制面板过程中的一些经验以及驱动代码(自己造的轮子)分享出来,希望各位大佬能够多多指导。(N32G401F8S7-1只有20个引脚有点不够用,所以参加活动也是希望能获得一块板子,这样可以对N32G401有更多的深入应用)
  首先简单概括一下配置的驱动:定时器,串口,看门狗,中断,GPIO。
  配置 LCD 屏幕驱动(HT1621驱动)
  配置DS18B20温度传感器(one_wire 协议,需外接上拉电阻)
  配置 USART,用串口传输数据
  配置按键 KEY,五个按键使用中断的方式分别控制不同功能
  配置 Delay,Iwdg



  芯片使用的是内置的HSI高速时钟,(没有外接晶振)
  内置HSI时钟是8MHZ,有±1%的误差,可以使用PLL进行倍频,如果引脚够用建议使用外接晶振
DS18B20对时序要求比较高,需要1us分辨率的延迟,(国民技术官方的例程里有好几种延迟)
对时序要求高的外设,建议使用系统时钟进行延迟

1.配置LCD屏幕驱动(HT1621)
先看数据手册,确保地址无误,如果不确定的话可以用for循环遍历所有地址,再根据实际配置地址
数码管显示数字由于是两位地址确定一个数码管,所以写了两个数组,一个对应高位,一个对应低位
每个HT1621的对应的地址都不一样,务必根据自己实际地址配置,不然显示肯定出错
以下是代码,ht1621和背光引脚的引脚初始化,需要注意的是:我用N32G401的内部8MHZ晶振HSI,然后通过PLL倍频将芯片时钟设定为64MHZ
所以定时器的预分频值为640-1。
我给背光引脚配置了一个高级定时器,配置PWM模式来控制亮度
  1. /**
  2. * [url=home.php?mod=space&uid=139335]@name[/url]     LCD_BLK_Value
  3. * [url=home.php?mod=space&uid=42490]@function[/url] LCD背光值(0~100)
  4. * @param    u8 set
  5. * [url=home.php?mod=space&uid=266161]@return[/url]   none
  6. */
  7. void LCD_BLK_Value(u8 set)
  8. {
  9.     TIM_Compare2_Set(TIM1, set);
  10. }
以下是HT1621以及背光的GPIO配置。

  1. /**
  2. * @description: 屏幕初始化
  3. * @param none
  4. * [url=home.php?mod=space&uid=266161]@return[/url] none
  5. */
  6. void LCD_Init(void)
  7. {
  8.     RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOA);
  9.     RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOB);

  10.     GPIO_InitType GPIO_InitStructure;
  11.     GPIO_Structure_Initialize(&GPIO_InitStructure);
  12.     GPIO_InitStructure.Pin = GPIO_PIN_5 | GPIO_PIN_7;
  13.     GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUT_PP;
  14.     GPIO_InitStructure.GPIO_Slew_Rate = GPIO_SLEW_RATE_FAST;
  15.     GPIO_Peripheral_Initialize(GPIOA, &GPIO_InitStructure);

  16.     GPIO_Structure_Initialize(&GPIO_InitStructure);
  17.     GPIO_InitStructure.Pin = GPIO_PIN_1;
  18.     GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUT_PP;
  19.     GPIO_InitStructure.GPIO_Slew_Rate = GPIO_SLEW_RATE_FAST;
  20.     GPIO_Peripheral_Initialize(GPIOB, &GPIO_InitStructure);

  21.     LCD_CS_1();
  22.     LCD_DATA_1();
  23.     LCD_WR_1();

  24.     HT1621_WriteCommand(HT1621_SYS_EN); // 打开系统振荡器
  25.     HT1621_WriteCommand(HT1621_BIAS);   // BIAS 1/3 4个公共口
  26.     HT1621_WriteCommand(HT1621_RC256);  // 使用RC_256K系统时钟源,片内RC振荡器
  27.     HT1621_WriteCommand(HT1621_WDT_DIS);
  28.     HT1621_WriteCommand(HT1621_LCD_ON);

  29.     LCD_BLK_Init();
  30.     LCD_BLK_Value(LCD_BLK_VALUE); // 开启背光
  31.     HT1621_Set_LCD(1);            // 屏幕显示
  32. }

  33. /**
  34. * [url=home.php?mod=space&uid=139335]@name[/url]     LCD_BLK_Init
  35. * [url=home.php?mod=space&uid=42490]@function[/url] LCD背光初始化
  36. * @param    none
  37. * [url=home.php?mod=space&uid=266161]@return[/url]   none
  38. */
  39. void LCD_BLK_Init(void)
  40. {
  41.     RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOA);
  42.     RCC_APB2_Peripheral_Clock_Enable(RCC_APB2_PERIPH_TIM1);
  43.     RCC_APB2_Peripheral_Clock_Enable(RCC_APB2_PERIPH_AFIO);

  44.     GPIO_InitType GPIO_InitStructure;
  45.     GPIO_Structure_Initialize(&GPIO_InitStructure);
  46.     GPIO_InitStructure.Pin = GPIO_PIN_9;
  47.     GPIO_InitStructure.GPIO_Mode = GPIO_MODE_AF_PP;
  48.     GPIO_InitStructure.GPIO_Current = GPIO_DS_2MA;
  49.     GPIO_InitStructure.GPIO_Alternate = GPIO_AF3_TIM1;
  50.     GPIO_Peripheral_Initialize(GPIOA, &GPIO_InitStructure);

  51.     TIM_TimeBaseInitType TIM_TimeBaseInitStructure;
  52.     TIM_Base_Struct_Initialize(&TIM_TimeBaseInitStructure);
  53.     TIM_TimeBaseInitStructure.Period = 100 - 1;
  54.     TIM_TimeBaseInitStructure.Prescaler = 640 - 1;
  55.     TIM_TimeBaseInitStructure.RepetCnt = 0;
  56.     TIM_TimeBaseInitStructure.CntMode = TIM_CNT_MODE_UP;
  57.     TIM_TimeBaseInitStructure.ClkDiv = TIM_CLK_DIV1;
  58.     TIM_Base_Initialize(TIM1, &TIM_TimeBaseInitStructure);
  59.     TIM_On(TIM1);

  60.     OCInitType TIM_OCInitStructure;
  61.     TIM_Output_Channel_Struct_Initialize(&TIM_OCInitStructure);
  62.     TIM_OCInitStructure.OcMode = TIM_OCMODE_PWM1;
  63.     TIM_OCInitStructure.OcNPolarity = TIM_OCN_POLARITY_LOW;
  64.     TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
  65.     TIM_OCInitStructure.Pulse = 0;
  66.     TIM_OCInitStructure.OcNIdleState = TIM_OCN_IDLE_STATE_SET;
  67.     TIM_Output_Channel2_Initialize(TIM1, &TIM_OCInitStructure);

  68.     TIM_PWM_Output_Enable(TIM1);
  69. }

2.配置DS18B20温度传感器(one_wire 协议,需外接上拉电阻)
需要了解并掌握DS18B20传输时序,由于对时序要求比较高,务必确保延迟函数的准确度
以下是配置代码:
  1. /**
  2. * @description: 初始化DS18B20的IO口 DQ 同时检测DS的存在
  3. * @param none
  4. * @return 返回1:不存在
  5. * @return 返回0:存在
  6. */
  7. u8 DS18B20_Init(void)
  8. {
  9.     RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOA);
  10.     GPIO_InitType GPIO_InitStructure;
  11.     GPIO_InitStructure.Pin = DS18B20_PIN; // 推挽输出
  12.     GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUT_PP;
  13.     GPIO_InitStructure.GPIO_Slew_Rate = GPIO_SLEW_RATE_FAST;
  14.     GPIO_Peripheral_Initialize(DS18B20_PORT, &GPIO_InitStructure);

  15.     GPIO_Pins_Set(DS18B20_PORT, DS18B20_PIN); // 拉高

  16.     DS18B20_Rst();

  17.     return DS18B20_Check();
  18. }

  1. /**
  2. * @description: IO口输出初始化
  3. * @param none
  4. * @return none
  5. */
  6. void DS18B20_IO_OUT(void)
  7. {
  8.     GPIO_InitType GPIO_InitStructure;
  9.     GPIO_InitStructure.Pin = DS18B20_PIN;
  10.     GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUT_PP;
  11.     GPIO_InitStructure.GPIO_Slew_Rate = GPIO_SLEW_RATE_FAST;
  12.     GPIO_Peripheral_Initialize(DS18B20_PORT, &GPIO_InitStructure);
  13. }

  14. /**
  15. * @description: IO口输入初始化
  16. * @param none
  17. * @return none
  18. */
  19. void DS18B20_IO_IN(void)
  20. {
  21.     GPIO_InitType GPIO_InitStructure;
  22.     GPIO_InitStructure.Pin = DS18B20_PIN;
  23.     GPIO_InitStructure.GPIO_Mode = GPIO_MODE_INPUT;
  24.     GPIO_InitStructure.GPIO_Slew_Rate = GPIO_SLEW_RATE_FAST;
  25.     GPIO_Peripheral_Initialize(DS18B20_PORT, &GPIO_InitStructure);
  26. }
在配置的过程中,我发现使用STM32大多都是通过bit-band操作寄存器,我查了官方的例程,也有相关例程,由于篇幅有限,就不再这里拓展,以后有机会单开一篇来讲讲
DS18B20用的是one-wire通讯协议,所以可以像这样配置操作总线传输数据:
  1. #define DS18B20_DQ_IN GPIO_Input_Pin_Data_Get(DS18B20_PORT, DS18B20_PIN)

  2. #define DS18B20_DQ_OUT_1 GPIO_Pins_Set(DS18B20_PORT, DS18B20_PIN)
  3. #define DS18B20_DQ_OUT_0 GPIO_Pins_Reset(DS18B20_PORT, DS18B20_PIN)
3.配置按键 KEY,五个按键使用中断的方式分别控制不同功能

  1. /**
  2. * [url=home.php?mod=space&uid=139335]@name[/url]     KEY_init
  3. * [url=home.php?mod=space&uid=42490]@function[/url] 初始化按键,启用中断
  4. * @param    none
  5. * @return   none
  6. */
  7. void KEY_init(void)
  8. {
  9.         RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOA); // 按键全部使用GPIOA
  10.         RCC_APB2_Peripheral_Clock_Enable(RCC_APB2_PERIPH_AFIO);
  11.         RCC_APB1_Peripheral_Clock_Enable(RCC_APB1_PERIPH_TIM6);

  12.         GPIO_InitType GPIO_InitStructure;
  13.         GPIO_Structure_Initialize(&GPIO_InitStructure);
  14.         GPIO_InitStructure.Pin = KEY6_GPIO_PIN | KEY7_GPIO_PIN | KEY8_GPIO_PIN | KEY9_GPIO_PIN | KEY10_GPIO_PIN;
  15.         GPIO_InitStructure.GPIO_Mode = GPIO_MODE_INPUT; // 输入
  16.         GPIO_InitStructure.GPIO_Pull = GPIO_PULL_UP;
  17.         GPIO_Peripheral_Initialize(GPIOA, &GPIO_InitStructure);

  18.         GPIO_EXTI_Line_Set(EXTI_LINE_SOURCE5, AFIO_EXTI_PA0);
  19.         GPIO_EXTI_Line_Set(EXTI_LINE_SOURCE6, AFIO_EXTI_PA1);
  20.         GPIO_EXTI_Line_Set(EXTI_LINE_SOURCE7, AFIO_EXTI_PA2);
  21.         GPIO_EXTI_Line_Set(EXTI_LINE_SOURCE8, AFIO_EXTI_PA3);
  22.         GPIO_EXTI_Line_Set(EXTI_LINE_SOURCE9, AFIO_EXTI_PA4);

  23.         /* Configure key EXTI line */
  24.         EXTI_InitType EXTI_InitStructure;
  25.         EXTI_InitStructure.EXTI_Line = EXTI_LINE5;
  26.         EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  27.         EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  28.         EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  29.         EXTI_Peripheral_Initializes(&EXTI_InitStructure);

  30.         EXTI_InitStructure.EXTI_Line = EXTI_LINE6;
  31.         EXTI_Peripheral_Initializes(&EXTI_InitStructure);

  32.         EXTI_InitStructure.EXTI_Line = EXTI_LINE7;
  33.         EXTI_Peripheral_Initializes(&EXTI_InitStructure);

  34.         EXTI_InitStructure.EXTI_Line = EXTI_LINE8;
  35.         EXTI_Peripheral_Initializes(&EXTI_InitStructure);

  36.         EXTI_InitStructure.EXTI_Line = EXTI_LINE9;
  37.         EXTI_Peripheral_Initializes(&EXTI_InitStructure);

  38.         /* Set key input interrupt priority */
  39.         NVIC_InitType NVIC_InitStructure;
  40.         NVIC_Priority_Group_Set(NVIC_PER3_SUB1_PRIORITYGROUP);
  41.         NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
  42.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_SUB_PRIORITY_3;
  43.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PER_PRIORITY_3;
  44.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  45.         NVIC_Initializes(&NVIC_InitStructure);
  46. }
4.配置USART,IWDG,DELAY
以下是官方例程中给的两种中断方式,根据实际需求选择使用

  1. #include "DELAY.h"

  2. /**
  3. * @brief SysTick_Config 函数用于配置 SysTick 定时器
  4. * @param ticks: SysTick 定时器的计数值
  5. * @return 0 表示配置成功,1 表示配置失败(计数值过大)
  6. */
  7. static uint32_t DBG_SysTick_Config(uint32_t ticks)
  8. {
  9.     if (ticks > SysTick_LOAD_RELOAD_Msk)
  10.         return (1); /* 重新加载值不合理 */

  11.     SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* 设置重新加载寄存器 */
  12.     NVIC_SetPriority(SysTick_IRQn, (1 << __NVIC_PRIO_BITS) - 1); /* 设置 Cortex-M0 系统中断的优先级 */
  13.     SysTick->VAL = 0;                                            /* 加载 SysTick 计数器的初始值 */
  14.     SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
  15.                     SysTick_CTRL_ENABLE_Msk; /* 启用 SysTick IRQ 和 SysTick 定时器 */

  16.     SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk; /* 禁用 SysTick 中断 */
  17.     SysTick->VAL = 0;
  18.     return (0); /* 配置成功 */
  19. }

  20. /**
  21. * @brief SysTick_Delay_Us 函数用于提供微秒级延时
  22. * @param us: 延时的微秒数
  23. * @return 无
  24. */
  25. void SysTick_Delay_Us(__IO uint32_t us)
  26. {
  27.     volatile uint32_t i;
  28.     RCC_ClocksType RCC_Clocks;

  29.     RCC_Clocks_Frequencies_Value_Get(&RCC_Clocks);       /* 获取系统时钟频率 */
  30.     DBG_SysTick_Config(RCC_Clocks.SysclkFreq / 1000000); /* 配置 SysTick 定时器为微秒分辨率 */

  31.     for (i = 0; i < us; i++)
  32.     {
  33.         /* 当计数器值减至0时,CRTL 寄存器的第16位将被设置为1 */
  34.         /* 当设置为1时,读取此位将其清零 */
  35.         while (!(SysTick->CTRL & (1 << 16)))
  36.             ;
  37.     }
  38.     /* 关闭 SysTick 定时器 */
  39.     SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
  40. }

  41. /**
  42. * @brief SysTick_Delay_Ms 函数用于提供毫秒级延时
  43. * @param ms: 延时的毫秒数
  44. * @return 无
  45. */
  46. void SysTick_Delay_Ms(__IO uint32_t ms)
  47. {
  48.     volatile uint32_t i;
  49.     RCC_ClocksType RCC_Clocks;

  50.     RCC_Clocks_Frequencies_Value_Get(&RCC_Clocks);    /* 获取系统时钟频率 */
  51.     DBG_SysTick_Config(RCC_Clocks.SysclkFreq / 1000); /* 配置 SysTick 定时器为毫秒分辨率 */

  52.     for (i = 0; i < ms; i++)
  53.     {
  54.         /* 当计数器值减至0时,CRTL 寄存器的第16位将被设置为1 */
  55.         /* 当设置为1时,读取此位将其清零 */
  56.         while (!(SysTick->CTRL & (1 << 16)))
  57.             ;
  58.     }
  59.     /* 关闭 SysTick 定时器 */
  60.     SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
  61. }


  62. void systick_delay_us(u32 nus)
  63. {
  64.     u32 temp;
  65.     SysTick_Clock_Source_Set(SYSTICK_CLKSOURCE_HCLK);       // select system clock
  66.     SysTick->LOAD = nus * (SystemClockFrequency / 1000000); // time relode
  67.     SysTick->VAL = 0x00;                                    // clear timer value
  68.     SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;               // Start countdown
  69.     do
  70.     {
  71.         temp = SysTick->CTRL;
  72.     } while (temp & 0x01 && !(temp & (1 << 16))); // wait for the time reach
  73.     SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;    // close the count
  74.     SysTick->VAL = 0X00;                          // clear timer value
  75. }

  76. /**
  77. *\*\name    systick_delay_ms.
  78. *\*\fun     ms delay  program function.
  79. *\*\param   nms
  80. *\*\return  none
  81. **/
  82. void systick_delay_ms(u16 nms)
  83. {
  84.     u32 temp;
  85.     SysTick_Clock_Source_Set(SYSTICK_CLKSOURCE_HCLK);                     // select system clock
  86.     SysTick->LOAD = (u32)nms * ((SystemClockFrequency / 1000000) * 1000); // time relode(SysTick->LOAD is 24bit)
  87.     SysTick->VAL = 0x00;                                                  // clear timer value
  88.     SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;                             // Start countdown
  89.     do
  90.     {
  91.         temp = SysTick->CTRL;
  92.     } while (temp & 0x01 && !(temp & (1 << 16))); // wait for the time reach
  93.     SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;    // close the count
  94.     SysTick->VAL = 0X00;                          // clear timer value
  95. }
配置USART:

  1. /**
  2. * @name     USART2_Init
  3. * @function USART2初始化  逻辑"0"发送 逻辑"1"接收
  4. * @param    none
  5. * @return   none
  6. */
  7. void USART2_Init(void)
  8. {
  9.     RCC_APB1_Peripheral_Clock_Enable(RCC_APB1_PERIPH_USART2);
  10.     RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOD);
  11.     RCC_APB2_Peripheral_Clock_Enable(RCC_APB2_PERIPH_AFIO);

  12.     GPIO_InitType GPIO_InitStructure;
  13.     /* 配置USARTy Tx为复用推挽输出 */
  14.     GPIO_InitStructure.Pin = GPIO_PIN_15;
  15.     GPIO_InitStructure.GPIO_Mode = GPIO_MODE_AF_PP;
  16.     GPIO_InitStructure.GPIO_Alternate = GPIO_AF4_USART2;
  17.     GPIO_Peripheral_Initialize(GPIOD, &GPIO_InitStructure);

  18.     /* 配置USARTy Rx为复用推挽输入和上拉输入 */
  19.     GPIO_InitStructure.Pin = GPIO_PIN_14;
  20.     GPIO_InitStructure.GPIO_Alternate = GPIO_AF4_USART2;
  21.     GPIO_Peripheral_Initialize(GPIOD, &GPIO_InitStructure);

  22.     USART_InitType USART2_InitStructure;
  23.     USART2_InitStructure.BaudRate = 9600;
  24.     USART2_InitStructure.Mode = USART_MODE_RX | USART_MODE_TX;
  25.     USART2_InitStructure.WordLength = USART_WL_8B;
  26.     USART2_InitStructure.Parity = USART_PE_NO;
  27.     USART2_InitStructure.StopBits = USART_STPB_1;
  28.     USART2_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
  29.     USART_Initializes(USART2, &USART2_InitStructure);

  30.     NVIC_InitType NVIC_InitStructure;
  31.     NVIC_Priority_Group_Set(NVIC_PER2_SUB2_PRIORITYGROUP);
  32.     NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
  33.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
  34.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  35.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  36.     NVIC_Initializes(&NVIC_InitStructure);

  37.     USART_Interrput_Enable(USART2, USART_INT_RXDNE);
  38.     USART_Interrput_Enable(USART2, USART_INT_TXDE);

  39.     USART_Enable(USART2);
  40. }
配置IWDG:

  1. __IO uint32_t LsiFreq = 40000; // 内部低速时钟频率,初始值设定为 40000

  2. void IWDG_Config(IWDG_CONFIG_PRESCALER IWDG_prescaler, uint16_t reload_value)
  3. {
  4.     /* 由于 LSI 频率变化,超时时间可能有所不同 */
  5.     /* 关闭 IWDG_PREDIV 和 IWDG_RELV 寄存器的写保护 */
  6.     IWDG_Write_Protection_Disable();

  7.     /* IWDG 计数器时钟预分频设置 */
  8.     IWDG_Prescaler_Division_Set(IWDG_prescaler);

  9.     /* 设置 IWDG 重装载值 */
  10.     /* 设置计数器重装载值以获取 x 秒的 IWDG 超时。
  11.        计数器重装载值时间 = x(秒) / IWDG 计数器时钟周期
  12.                          = x(秒) / (LSI/IWDG_prescaler)
  13.     */
  14.     IWDG_Counter_Reload(reload_value);

  15.     /* 使用 IWDG_PREDIV 的值重新加载计数器到 IWDG_RELV 寄存器,以防止复位 */
  16.     IWDG_Key_Reload();

  17.     /* 启用 IWDG(LSI 振荡器将由硬件启用) */
  18.     IWDG_Enable();
  19. }

  20. void IWDG_Feed(void)
  21. {
  22.     /* 将重装载寄存器的值写入计数器 */
  23.     IWDG_Key_Reload();
  24. }

本文由于篇幅原因仅分享所有的驱动配置,各个硬件外设通讯协议以及时序都能在网上找到资源,只需要将驱动配置完成即可使用。
欢迎官方以及各位工程师帮忙指出不足之处~




 楼主| Wayneso 发表于 2024-1-11 15:22 | 显示全部楼层
本来是打算使用SPI驱动的液晶屏幕,驱动都差不多写好了,后来发现HT1621更简易和便宜,所以换成了断码屏。
有机会再写一篇SPI+DMA驱动LCD屏幕
jobszheng 发表于 2024-1-11 15:44 | 显示全部楼层
我们当年低成本方案也是使用的HT1621与断码屏组合的方式。超级好用,代码也简洁
 楼主| Wayneso 发表于 2024-1-11 16:17 | 显示全部楼层
jobszheng 发表于 2024-1-11 15:44
我们当年低成本方案也是使用的HT1621与断码屏组合的方式。超级好用,代码也简洁 ...

确实好用hhh,对一些显示固定面板首选HT1621+断码屏
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

9

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部

3

主题

9

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部