任务:编写一个MOS测试脉冲发生器,通过按键输入控制输出脉冲数量(1-10个)脉冲宽度和脉冲频率可设。
main.c/key.c/lcd.c/pwm.c
main.c
/****************************************************************************************************** @file main.c* @author wl* @version V1.1* @date 2024-09-27* @brief 主函数* @license *****************************************************************************************************/
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/delay/delay.h"
#include "./SYSTEM/lcd/lcd.h"
#include "./SYSTEM/key/key.h"
#include "./SYSTEM/pwm/pwm.h"
#include "./SYSTEM/timer/atim.h"extern TIM_HandleTypeDef g_timx_npwm_chy_handle; /* 定时器x句柄 */
int main(void)
{HAL_Init(); /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */lcd_init();HT1621_Init();DelayMs(50);HT1621_WriteAllData();//清屏key_init();en_init();PWM_EN_L();gtim_timx_pwm_chy_init(10000 - 1, 7200 - 1);while(1){ key_task();delay_ms(10);}
}
key.c
/****************************************************************************************************** @file key.c* @author wl* @version V1.1* @date 2024-09-23* @brief 按键* @license *****************************************************************************************************/#include "./SYSTEM/key/key.h"
#include "./SYSTEM/delay/delay.h"
#include "./SYSTEM/lcd/lcd.h"
#include "./SYSTEM/pwm/pwm.h"unsigned char SEG_addr[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F};
unsigned char Data_highSEG[]={0x0e,0x06,0x0c,0x0e,0x06,0x0a,0x0a,0x0e,0x0e,0x0e};
unsigned char Data_lowSEG[]={0x0b,0x00,0x07,0x05,0x0c,0x0d,0x0f,0x00,0x0f,0x0d};uint8_t key;
uint16_t Num,Wid,Fre;
uint16_t Digital_tube[8]={0};
uint8_t Esc_key=0;/*******************************************************************************
* 函 数 名: key_init
* 函数功能: 按键初始化
* 输 入:
* 输 出: 无
*******************************************************************************/void key_init(void)
{Num = 15,Wid = 12,Fre = 100;GPIO_InitTypeDef gpio_init_struct;SW_ESC_GPIO_CLK_ENABLE(); /* ESC时钟使能 */SW_UP_GPIO_CLK_ENABLE(); /* UP时钟使能 */SW_DOWN_GPIO_CLK_ENABLE(); /* DOWN时钟使能 */SW_ENTER_GPIO_CLK_ENABLE(); /* ENTER时钟使能 */gpio_init_struct.Pin = SW_ESC_GPIO_PIN; /* ESC引脚 */gpio_init_struct.Mode = GPIO_MODE_INPUT; /* 输入 */gpio_init_struct.Pull = GPIO_PULLDOWN; /* 下拉 */gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */HAL_GPIO_Init(SW_ESC_GPIO_PORT, &gpio_init_struct); /* ESC引脚模式设置,上拉输入 */gpio_init_struct.Pin = SW_UP_GPIO_PIN; /* UP引脚 */gpio_init_struct.Mode = GPIO_MODE_INPUT; /* 输入 */gpio_init_struct.Pull = GPIO_PULLDOWN; /* 下拉 */gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */HAL_GPIO_Init(SW_UP_GPIO_PORT, &gpio_init_struct); /* UP引脚模式设置,上拉输入 */gpio_init_struct.Pin = SW_DOWN_GPIO_PIN; /* DOWN引脚 */gpio_init_struct.Mode = GPIO_MODE_INPUT; /* 输入 */gpio_init_struct.Pull = GPIO_PULLDOWN; /* 下拉 */gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */HAL_GPIO_Init(SW_DOWN_GPIO_PORT, &gpio_init_struct); /* DOWN引脚模式设置,下拉输入 */gpio_init_struct.Pin = SW_ENTER_GPIO_PIN; /* ENTER引脚 */gpio_init_struct.Mode = GPIO_MODE_INPUT; /* 输入 */gpio_init_struct.Pull = GPIO_PULLDOWN; /* 下拉 */gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */HAL_GPIO_Init(SW_ENTER_GPIO_PORT, &gpio_init_struct); /* ENTER引脚模式设置,下拉输入 */
}/*******************************************************************************
* 函 数 名: key_scan
* 函数功能: 按键扫描
* 输 入:
* 输 出: 无
*******************************************************************************/
uint8_t key_scan(uint8_t mode)
{static uint8_t key_up = 1; /* 按键按松开标志 */uint8_t keyval = 0;if (mode) key_up = 1; /* 支持连按 */if (key_up && (SW_ESC == 1 || SW_UP == 1 || SW_DOWN == 1 || SW_ENTER == 1)) /* 按键松开标志为1, 且有任意一个按键按下了 */{delay_ms(10); /* 去抖动 */key_up = 0;if (SW_ESC == 1) keyval = SW_ESC_PRES;if (SW_UP == 1) keyval = SW_UP_PRES;if (SW_DOWN == 1) keyval = SW_DOWN_PRES;if (SW_ENTER == 1) keyval = SW_ENTER_PRES;}else if (SW_ESC == 0 && SW_UP == 0 && SW_DOWN == 0 && SW_ENTER == 0) /* 没有任何按键按下, 标记按键松开 */{key_up = 1;}return keyval; /* 返回键值 */
}/*******************************************************************************
* 函 数 名: key_task
* 函数功能: 按键任务
* 输 入:
* 输 出: 无
*******************************************************************************/
void key_task(void)
{key = key_scan(0);if (key){switch (key){case SW_ESC_PRES: /* ESC */if(Esc_key == 0){HT1621_WirteData(SEG_addr[2],Data_lowSEG[Digital_tube[0]]); HT1621_WirteData(SEG_addr[3],Data_highSEG[Digital_tube[0]]);HT1621_WirteData(SEG_addr[4],Data_lowSEG[Digital_tube[1]]); HT1621_WirteData(SEG_addr[5],Data_highSEG[Digital_tube[1]]);HT1621_WirteData(SEG_addr[6],Data_lowSEG[Digital_tube[2]]);HT1621_WirteData(SEG_addr[7],Data_highSEG[Digital_tube[2]]);Esc_key = 1;}else if(Esc_key == 1){HT1621_WirteData(SEG_addr[10],Data_lowSEG[Digital_tube[3]]);HT1621_WirteData(SEG_addr[11],Data_highSEG[Digital_tube[3]]);HT1621_WirteData(SEG_addr[12],Data_lowSEG[Digital_tube[4]]);HT1621_WirteData(SEG_addr[13],Data_highSEG[Digital_tube[4]]);Esc_key = 2;}else if(Esc_key == 2){HT1621_WirteData(SEG_addr[16],Data_lowSEG[Digital_tube[5]]);HT1621_WirteData(SEG_addr[17],Data_highSEG[Digital_tube[5]]);HT1621_WirteData(SEG_addr[18],Data_lowSEG[Digital_tube[6]]);HT1621_WirteData(SEG_addr[19],Data_highSEG[Digital_tube[6]]);HT1621_WirteData(SEG_addr[20],Data_lowSEG[Digital_tube[7]]);HT1621_WirteData(SEG_addr[21],Data_highSEG[Digital_tube[7]]);Esc_key=0;}break;case SW_UP_PRES: /* UP */if(Esc_key == 0){Wid++;Digital_tube[0] =(Wid /100);Digital_tube[1] =(Wid /10)%10;Digital_tube[2] =(Wid % 10); HT1621_WirteData(SEG_addr[2],Data_lowSEG[Digital_tube[0]]);HT1621_WirteData(SEG_addr[3],Data_highSEG[Digital_tube[0]]);HT1621_WirteData(SEG_addr[4],Data_lowSEG[Digital_tube[1]]);HT1621_WirteData(SEG_addr[5],Data_highSEG[Digital_tube[1]]);HT1621_WirteData(SEG_addr[6],Data_lowSEG[Digital_tube[2]]);HT1621_WirteData(SEG_addr[7],Data_highSEG[Digital_tube[2]]);gtim_timx_pwm_chy_init((1000000/Fre) - 1, 72 - 1);/* 1Mhz的计数频率,2Khz的PWM. *///__HAL_TIM_SET_COMPARE(&g_timx_pwm_chy_handle, GTIM_TIMX_PWM_CHY, (1000000/Fre-(10000/Fre*Wid)));}if(Esc_key == 1){Num++;Digital_tube[3] =(Num /10)%10;Digital_tube[4] =(Num % 10); HT1621_WirteData(SEG_addr[10],Data_lowSEG[Digital_tube[3]]);HT1621_WirteData(SEG_addr[11],Data_highSEG[Digital_tube[3]]);HT1621_WirteData(SEG_addr[12],Data_lowSEG[Digital_tube[4]]);HT1621_WirteData(SEG_addr[13],Data_highSEG[Digital_tube[4]]);g_timxchy_cnt_ofcnt = 0;delay_ms(10);gtim_timx_pwm_chy_init((1000000/Fre) - 1, 72 - 1);/* 1Mhz的计数频率,2Khz的PWM. */delay_ms(10);}if(Esc_key == 2){Fre++;Digital_tube[5] =(Fre /100);Digital_tube[6] =(Fre /10)%10;Digital_tube[7] =(Fre % 10); HT1621_WirteData(SEG_addr[16],Data_lowSEG[Digital_tube[5]]);HT1621_WirteData(SEG_addr[17],Data_highSEG[Digital_tube[5]]);HT1621_WirteData(SEG_addr[18],Data_lowSEG[Digital_tube[6]]);HT1621_WirteData(SEG_addr[19],Data_highSEG[Digital_tube[6]]);HT1621_WirteData(SEG_addr[20],Data_lowSEG[Digital_tube[7]]);HT1621_WirteData(SEG_addr[21],Data_highSEG[Digital_tube[7]]);gtim_timx_pwm_chy_init((1000000/Fre) - 1, 72 - 1);/* 1Mhz的计数频率,2Khz的PWM. */} break;case SW_DOWN_PRES: /* DOWN */if(Esc_key == 0){Wid--;Digital_tube[0] =(Wid /100);Digital_tube[1] =(Wid /10)%10;Digital_tube[2] =(Wid % 10); HT1621_WirteData(SEG_addr[2],Data_lowSEG[Digital_tube[0]]);HT1621_WirteData(SEG_addr[3],Data_highSEG[Digital_tube[0]]);HT1621_WirteData(SEG_addr[4],Data_lowSEG[Digital_tube[1]]);HT1621_WirteData(SEG_addr[5],Data_highSEG[Digital_tube[1]]);HT1621_WirteData(SEG_addr[6],Data_lowSEG[Digital_tube[2]]);HT1621_WirteData(SEG_addr[7],Data_highSEG[Digital_tube[2]]);gtim_timx_pwm_chy_init((1000000/Fre) - 1, 72 - 1);/* 1Mhz的计数频率,2Khz的PWM. *///__HAL_TIM_SET_COMPARE(&g_timx_pwm_chy_handle, GTIM_TIMX_PWM_CHY, (1000000/Fre-(10000/Fre*Wid)));}if(Esc_key == 1){Num--;//Digital_tube[0] =(Num /100);Digital_tube[3] =(Num /10)%10;Digital_tube[4] =(Num % 10); HT1621_WirteData(SEG_addr[10],Data_lowSEG[Digital_tube[3]]);HT1621_WirteData(SEG_addr[11],Data_highSEG[Digital_tube[3]]);HT1621_WirteData(SEG_addr[12],Data_lowSEG[Digital_tube[4]]);HT1621_WirteData(SEG_addr[13],Data_highSEG[Digital_tube[4]]);g_timxchy_cnt_ofcnt = 0;delay_ms(10);gtim_timx_pwm_chy_init((1000000/Fre) - 1, 72 - 1);/* 1Mhz的计数频率,2Khz的PWM. */delay_ms(10);}if(Esc_key == 2){Fre--;Digital_tube[5] =(Fre /100);Digital_tube[6] =(Fre /10)%10;Digital_tube[7] =(Fre % 10); HT1621_WirteData(SEG_addr[16],Data_lowSEG[Digital_tube[5]]);HT1621_WirteData(SEG_addr[17],Data_highSEG[Digital_tube[5]]);HT1621_WirteData(SEG_addr[18],Data_lowSEG[Digital_tube[6]]);HT1621_WirteData(SEG_addr[19],Data_highSEG[Digital_tube[6]]);HT1621_WirteData(SEG_addr[20],Data_lowSEG[Digital_tube[7]]);HT1621_WirteData(SEG_addr[21],Data_highSEG[Digital_tube[7]]);gtim_timx_pwm_chy_init((1000000/Fre) - 1, 72 - 1);/* 1Mhz的计数频率,2Khz的PWM. */} break;case SW_ENTER_PRES: /* ENTER */break;} }else{delay_ms(10);}
}
key.h
/****************************************************************************************************** @file key.h* @author wl* @version V1.1* @date 2024-09-23* @brief * @license *****************************************************************************************************/#ifndef __KEY_H
#define __KEY_H#include "./SYSTEM/sys/sys.h"extern uint16_t Num,Wid,Fre;
extern uint8_t key;/******************************************************************************************/
/* 引脚 定义 */#define SW_ESC_GPIO_PORT GPIOB
#define SW_ESC_GPIO_PIN GPIO_PIN_2
#define SW_ESC_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0) /* PB口时钟使能 */#define SW_UP_GPIO_PORT GPIOA
#define SW_UP_GPIO_PIN GPIO_PIN_15
#define SW_UP_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0) /* PA口时钟使能 */#define SW_DOWN_GPIO_PORT GPIOB
#define SW_DOWN_GPIO_PIN GPIO_PIN_4
#define SW_DOWN_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0) /* PB口时钟使能 */#define SW_ENTER_GPIO_PORT GPIOB
#define SW_ENTER_GPIO_PIN GPIO_PIN_3
#define SW_ENTER_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0) /* PB口时钟使能 *//******************************************************************************************/#define SW_ESC HAL_GPIO_ReadPin(SW_ESC_GPIO_PORT, SW_ESC_GPIO_PIN) /* 读取SW_ESC引脚 */
#define SW_UP HAL_GPIO_ReadPin(SW_UP_GPIO_PORT, SW_UP_GPIO_PIN) /* 读取SW_UP引脚 */
#define SW_DOWN HAL_GPIO_ReadPin(SW_DOWN_GPIO_PORT, SW_DOWN_GPIO_PIN) /* 读取SW_DOWN引脚 */
#define SW_ENTER HAL_GPIO_ReadPin(SW_ENTER_GPIO_PORT, SW_ENTER_GPIO_PIN) /* 读取SW_ENTER引脚 */#define SW_ESC_PRES 1 /* ESC按下 */
#define SW_UP_PRES 2 /* UP按下 */
#define SW_DOWN_PRES 3 /* DOWN按下 */
#define SW_ENTER_PRES 4 /* ENTER按下*/void key_init(void); /* 按键初始化函数 */
uint8_t key_scan(uint8_t mode); /* 按键扫描函数 */
void key_task(void);
#endif
lcd.c
/****************************************************************************************************** @file lcd.c* @author wl* @version V1.1* @date 2024-09-23* @brief 液晶屏显示函数* @license *****************************************************************************************************/#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/lcd/lcd.h"
#include "./SYSTEM/delay/delay.h"/*******************************************************************************
* 函 数 名: lcd_init
* 函数功能: lcd初始化
* 输 入:
* 输 出: 无
*******************************************************************************/
void lcd_init(void)
{GPIO_InitTypeDef gpio_init_struct;LCD_CS_GPIO_CLK_ENABLE();LCD_LB_GPIO_CLK_ENABLE();LCD_DATA_GPIO_CLK_ENABLE();LCD_WR_GPIO_CLK_ENABLE();gpio_init_struct.Pin = LCD_CS_GPIO_PIN; /* LCD_CS引脚 */gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */HAL_GPIO_Init(LCD_CS_GPIO_PORT, &gpio_init_struct); /* 初始化LED0引脚 */gpio_init_struct.Pin = LCD_LB_GPIO_PIN; /* LCD_LB引脚 */gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */HAL_GPIO_Init(LCD_LB_GPIO_PORT, &gpio_init_struct); /* 初始化LED0引脚 */gpio_init_struct.Pin = LCD_DATA_GPIO_PIN; /* LCD_DATA引脚 */gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */HAL_GPIO_Init(LCD_DATA_GPIO_PORT, &gpio_init_struct); /* 初始化LED0引脚 */gpio_init_struct.Pin = LCD_WR_GPIO_PIN; /* LCD_WR引脚 */gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */HAL_GPIO_Init(LCD_WR_GPIO_PORT, &gpio_init_struct); /* 初始化LED0引脚 */
}/*******************************************************************************
* 函 数 名: Delay_us/DelayMs/HT1621_Delay
* 函数功能: 延迟函数
* 输 入:
* 输 出: 无
*******************************************************************************/
void Delay_us(unsigned char us)
{while(--us);
}void DelayMs(uint16_t iMs)
{uint16_t i,j;for(i=0;i<iMs;i++)for(j=0;j<65;j++){Delay_us(1);}
}void HT1621_Delay(uint32_t n)
{while(n--);
}/*******************************************************************************
* 函 数 名: HT1621_SendBit
* 函数功能: 按位发送数据
* 输 入:
* 输 出: 无
*******************************************************************************/
void HT1621_SendBit(unsigned char sdat,unsigned char cnt)
{unsigned char i;for(i=0;i<cnt;i++){HT1621_WR_L();HT1621_Delay(DELAY_TEST);if(sdat&0x80){HT1621_DAT_H();}else{HT1621_DAT_L();}HT1621_Delay(DELAY_TEST);HT1621_WR_H();HT1621_Delay(DELAY_TEST);sdat<<=1;}
}/*******************************************************************************
* 函 数 名: HT1621_WriteCMD
* 函数功能: 写入命令
* 输 入:
* 输 出: 无
*******************************************************************************/
void HT1621_WriteCMD(unsigned char command)
{HT1621_CS_L();HT1621_Delay(DELAY_TEST);HT1621_SendBit(0x80,4); HT1621_SendBit(command,8);HT1621_CS_H();
}/*******************************************************************************
* 函 数 名: HT1621_WirteData
* 函数功能: 写入数据
* 输 入:
* 输 出: 无
*******************************************************************************/
void HT1621_WirteData(unsigned char addr,unsigned char sdat)
{HT1621_CS_L();HT1621_SendBit(0xA0,3);//101 写命令HT1621_SendBit(addr<<=2,6);HT1621_SendBit(sdat<<=4,4); //一次只发送四位数据,一个地址发送一次,低四位HT1621_CS_H();
}/*******************************************************************************
* 函 数 名: HT1621_WriteCMD
* 函数功能: 写入命令
* 输 入:
* 输 出: 无
*******************************************************************************/
void HT1621_WriteAllData(void)
{unsigned char i;HT1621_CS_L();HT1621_SendBit(0xA0,3);HT1621_SendBit(0x00<<2,6);for(i=0;i<32;i++){HT1621_SendBit(0x00,8);}HT1621_CS_H();}/*******************************************************************************
* 函 数 名: HT1621_Init
* 函数功能: HT1621的初始化
* 输 入:
* 输 出: 无
*******************************************************************************/
void HT1621_Init(void)
{HT1621_CS_H();LCD_LB_H();DelayMs(20);HT1621_WriteCMD(0x02); //开启系统振荡器 // Lcd_seg_cmd(0x0028); //系统时钟为晶体振荡器HT1621_WriteCMD(0x06); //开启 LCD 偏置发生器HT1621_WriteCMD(0x52); //LCD 1/3 4duty 偏置状态 HT1621_WriteCMD(0x0E); //开启 LCD 偏置发生器HT1621_WriteCMD(0xC0); //蜂鸣频率:2KHz // Lcd_seg_cmd(0x000C); //允许时间基准输出HT1621_WriteCMD(0x12); //开启蜂鸣输出DelayMs(20);
// HT1621_CS_H();
// DelayMs(20);
}
lcd.h
/*
***************************************************************************************************** @file lcd.h* @author wl* @version V1.1* @date 2024-09-23* @brief * @license *****************************************************************************************************/#ifndef __LCD_H
#define __LCD_H
#include "./SYSTEM/sys/sys.h"#define DELAY_TEST 10/******************************************************************************************/
/* 引脚 定义 */#define LCD_CS_GPIO_PORT GPIOB
#define LCD_CS_GPIO_PIN GPIO_PIN_15
#define LCD_CS_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0) /* PB口时钟使能 */#define LCD_LB_GPIO_PORT GPIOA
#define LCD_LB_GPIO_PIN GPIO_PIN_12
#define LCD_LB_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0) /* PA口时钟使能 */#define LCD_DATA_GPIO_PORT GPIOA
#define LCD_DATA_GPIO_PIN GPIO_PIN_10
#define LCD_DATA_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0) /* PA口时钟使能 */#define LCD_WR_GPIO_PORT GPIOA
#define LCD_WR_GPIO_PIN GPIO_PIN_11
#define LCD_WR_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0) /* PA口时钟使能 *///#define LED0_GPIO_PORT GPIOB
//#define LED0_GPIO_PIN GPIO_PIN_5
//#define LED0_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0) /* PB口时钟使能 *///#define LED1_GPIO_PORT GPIOE
//#define LED1_GPIO_PIN GPIO_PIN_5
//#define LED1_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0) /* PE口时钟使能 *///#define LED0_GPIO_PORT GPIOB
//#define LED0_GPIO_PIN GPIO_PIN_5
//#define LED0_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0) /* PB口时钟使能 *///#define LED1_GPIO_PORT GPIOE
//#define LED1_GPIO_PIN GPIO_PIN_5
//#define LED1_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0) /* PE口时钟使能 *//******************************************************************************************/
/* LED端口定义 */
#define HT1621_CS_H() HAL_GPIO_WritePin(LCD_CS_GPIO_PORT, LCD_CS_GPIO_PIN, GPIO_PIN_SET)
#define HT1621_CS_L() HAL_GPIO_WritePin(LCD_CS_GPIO_PORT, LCD_CS_GPIO_PIN, GPIO_PIN_RESET) #define LCD_LB_H() HAL_GPIO_WritePin(LCD_LB_GPIO_PORT, LCD_LB_GPIO_PIN, GPIO_PIN_SET)
#define LCD_LB_L() HAL_GPIO_WritePin(LCD_LB_GPIO_PORT, LCD_LB_GPIO_PIN, GPIO_PIN_RESET) #define HT1621_DAT_H() HAL_GPIO_WritePin(LCD_DATA_GPIO_PORT, LCD_DATA_GPIO_PIN, GPIO_PIN_SET)
#define HT1621_DAT_L() HAL_GPIO_WritePin(LCD_DATA_GPIO_PORT, LCD_DATA_GPIO_PIN, GPIO_PIN_RESET) #define HT1621_WR_H() HAL_GPIO_WritePin(LCD_WR_GPIO_PORT, LCD_WR_GPIO_PIN, GPIO_PIN_SET)
#define HT1621_WR_L() HAL_GPIO_WritePin(LCD_WR_GPIO_PORT, LCD_WR_GPIO_PIN, GPIO_PIN_RESET)/******************************************************************************************/
/* 外部接口函数*/
void lcd_init(void);
void Delay_us(unsigned char us);
void DelayMs(uint16_t iMs);
void HT1621_Delay(uint32_t n);
void HT1621_SendBit(unsigned char sdat,unsigned char cnt);
void HT1621_WriteCMD(unsigned char command);
void HT1621_WirteData(unsigned char addr,unsigned char sdat);
void HT1621_WriteAllData(void);
void HT1621_Init(void);#endif
pwm.c
/****************************************************************************************************** @file pwm.c* @author wl* @version V1.1* @date 2024-09-24* @brief PWM脉冲* @license *****************************************************************************************************/#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/pwm/pwm.h"
#include "./SYSTEM/delay/delay.h"
#include "./SYSTEM/key/key.h"uint32_t g_timxchy_cnt_ofcnt = 0 ; /* 计数溢出次数 */
TIM_HandleTypeDef g_timx_pwm_chy_handle; /* 定时器x句柄 *//*******************************************************************************
* 函 数 名: en_init
* 函数功能: PWM_EN引脚初始化
* 输 入:
* 输 出: 无
*******************************************************************************/
void en_init(void)
{GPIO_InitTypeDef gpio_init_struct;PWM_EN_GPIO_CLK_ENABLE();gpio_init_struct.Pin = PWM_EN_GPIO_PIN; /* PWM_EN引脚 */gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */HAL_GPIO_Init(PWM_EN_GPIO_PORT, &gpio_init_struct); /* 初始化PWM_EN引脚 */
}
/*******************************************************************************
* 函 数 名: gtim_timx_pwm_chy_init
* 函数功能: 配置定时器,使用PWM模式1
* 输 入: arr: 自动重装值,psc: 时钟预分频数
* 输 出: 无
*******************************************************************************/
void gtim_timx_pwm_chy_init(uint16_t arr, uint16_t psc)
{GTIM_TIMX_PWM_CHY_CLK_ENABLE();TIM_OC_InitTypeDef timx_oc_pwm_chy = {0}; /* 定时器PWM输出配置 */g_timx_pwm_chy_handle.Instance = GTIM_TIMX_PWM; /* 定时器x */g_timx_pwm_chy_handle.Init.Prescaler = psc; /* 定时器分频 */g_timx_pwm_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP; /* 递增计数模式 */g_timx_pwm_chy_handle.Init.Period = arr; /* 自动重装载值 */HAL_TIM_PWM_Init(&g_timx_pwm_chy_handle); /* 初始化PWM */timx_oc_pwm_chy.OCMode = TIM_OCMODE_PWM1; /* 模式选择PWM1 */timx_oc_pwm_chy.Pulse = (1000000/Fre-(10000/Fre*Wid)); /* 设置比较值,此值用来确定占空比 *//* 默认比较值为自动重装载值的一半,即占空比为50% */timx_oc_pwm_chy.OCPolarity = TIM_OCPOLARITY_LOW; /* 输出比较极性为低 */HAL_TIM_PWM_ConfigChannel(&g_timx_pwm_chy_handle, &timx_oc_pwm_chy, GTIM_TIMX_PWM_CHY); /* 配置TIMx通道y */HAL_TIM_PWM_Start(&g_timx_pwm_chy_handle, GTIM_TIMX_PWM_CHY); /* 开启对应PWM通道 */HAL_NVIC_SetPriority(GTIM_TIMX_PWM_IRQn, 1, 3); /* 设置中断优先级,抢占优先级1,子优先级3 */
// HAL_NVIC_DisableIRQ(GTIM_TIMX_PWM_IRQn); /* 关闭ITMx中断 */HAL_NVIC_EnableIRQ(GTIM_TIMX_PWM_IRQn); /* 开启ITMx中断 */HAL_TIM_Base_Start_IT(&g_timx_pwm_chy_handle); /* 使能定时器x和定时器x更新中断 */
}/*******************************************************************************
* 函 数 名: HAL_TIM_PWM_MspInit
* 函数功能: 定时器底层驱动,时钟使能,引脚配置,此函数会被HAL_TIM_PWM_Init()调用
* 输 入:
* 输 出: 无
*******************************************************************************/
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
{if (htim->Instance == GTIM_TIMX_PWM){GPIO_InitTypeDef gpio_init_struct;GTIM_TIMX_PWM_CHY_GPIO_CLK_ENABLE(); /* 开启通道y的CPIO时钟 */GTIM_TIMX_PWM_CHY_CLK_ENABLE();gpio_init_struct.Pin = GTIM_TIMX_PWM_CHY_GPIO_PIN; /* 通道y的CPIO口 */gpio_init_struct.Mode = GPIO_MODE_AF_PP; /* 复用推完输出 */gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */HAL_GPIO_Init(GTIM_TIMX_PWM_CHY_GPIO_PORT, &gpio_init_struct);GTIM_TIMX_PWM_CHY_GPIO_REMAP(); /* IO口REMAP设置, 是否必要查看头文件配置的说明 */}
}/*******************************************************************************
* 函 数 名: GTIM_TIMX_PWM_IRQHandler
* 函数功能: 定时器中断服务函数
* 输 入:
* 输 出: 无
*******************************************************************************/
void GTIM_TIMX_PWM_IRQHandler(void)
{/* 以下代码没有使用定时器HAL库共用处理函数来处理,而是直接通过判断中断标志位的方式 */if(__HAL_TIM_GET_FLAG(&g_timx_pwm_chy_handle, TIM_FLAG_UPDATE) != RESET){g_timxchy_cnt_ofcnt++; /* 累计溢出次数 */if(g_timxchy_cnt_ofcnt == Num + 1)){HAL_TIM_PWM_Stop(&g_timx_pwm_chy_handle, GTIM_TIMX_PWM_CHY); /* 关闭对应PWM通道 */}
// else
// {
// HAL_TIM_PWM_Start(&g_timx_pwm_chy_handle, GTIM_TIMX_PWM_CHY); /* 开启对应PWM通道 */
// }__HAL_TIM_CLEAR_IT(&g_timx_pwm_chy_handle, TIM_IT_UPDATE); /* 清除定时器溢出中断标志位 */}
}
pwm.h
/*
***************************************************************************************************** @file pwm.h* @author wl* @version V1.1* @date 2024-09-23* @brief * @license *****************************************************************************************************/#ifndef __PWM_H
#define __PWM_H
#include "./SYSTEM/sys/sys.h"extern TIM_HandleTypeDef g_timx_pwm_chy_handle; /* 定时器x句柄 */
extern uint32_t g_timxchy_cnt_ofcnt; /* 计数溢出次数 */
/* EN引脚 */
#define PWM_EN_GPIO_PORT GPIOB
#define PWM_EN_GPIO_PIN GPIO_PIN_9
#define PWM_EN_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0) /* PB口时钟使能 */
/* EN端口定义 */
#define PWM_EN_H() HAL_GPIO_WritePin(PWM_EN_GPIO_PORT, PWM_EN_GPIO_PIN, GPIO_PIN_SET)
#define PWM_EN_L() HAL_GPIO_WritePin(PWM_EN_GPIO_PORT, PWM_EN_GPIO_PIN, GPIO_PIN_RESET) /* TIMX PWM输出定义 * 这里输出的PWM控制LED0(RED)的亮度* 默认是针对TIM2~TIM5* 注意: 通过修改这几个宏定义,可以支持TIM1~TIM8任意一个定时器,任意一个IO口输出PWM*/
#define GTIM_TIMX_PWM_CHY_GPIO_PORT GPIOA
#define GTIM_TIMX_PWM_CHY_GPIO_PIN GPIO_PIN_8
#define GTIM_TIMX_PWM_CHY_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0) /* PA口时钟使能 *//* TIMX REMAP设置* 因为我们LED0接在PB5上, 必须通过开启TIM3的部分重映射功能, 才能将TIM3_CH2输出到PB5上* 因此, 必须实现GTIM_TIMX_PWM_CHY_GPIO_REMAP* 对那些使用默认设置的定时器PWM输出脚, 不用设置重映射, 是不需要该函数的!*/
#define GTIM_TIMX_PWM_CHY_GPIO_REMAP() do{__HAL_RCC_AFIO_CLK_ENABLE();\__HAL_AFIO_REMAP_TIM1_PARTIAL();\}while(0) /* 通道REMAP设置, 该函数不是必须的, 根据需要实现 */#define GTIM_TIMX_PWM TIM1
#define GTIM_TIMX_PWM_CHY TIM_CHANNEL_1 /* 通道Y, 1<= Y <=4 */
#define GTIM_TIMX_PWM_CHY_CCRX TIM1->CCR2 /* 通道Y的输出比较寄存器 */
#define GTIM_TIMX_PWM_IRQn TIM1_UP_IRQn
#define GTIM_TIMX_PWM_IRQHandler TIM1_UP_IRQHandler
#define GTIM_TIMX_PWM_CHY_CLK_ENABLE() do{ __HAL_RCC_TIM1_CLK_ENABLE(); }while(0) /* TIM3 时钟使能 *//******************************************************************************************/
void en_init(void);
void gtim_timx_pwm_chy_init(uint16_t arr, uint16_t psc); /* 通用定时器 PWM初始化函数 */
#endif