任务:编写一个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