#include "at32f403a_407_conf.h"
uint32_t gSysTick = 0;
/**
* @brief 系统时钟配置:64MHz
* @param none
* @retval none
*/
void system_clock_config(void)
{
crm_reset();
crm_clock_source_enable(CRM_CLOCK_SOURCE_HICK, TRUE);
while(crm_flag_get(CRM_HICK_STABLE_FLAG) != SET);
crm_pll_config(CRM_PLL_SOURCE_HICK, CRM_PLL_MULT_16, CRM_PLL_OUTPUT_RANGE_LE72MHZ);
crm_clock_source_enable(CRM_CLOCK_SOURCE_PLL, TRUE);
while(crm_flag_get(CRM_PLL_STABLE_FLAG) != SET);
crm_sysclk_switch(CRM_SCLK_PLL);
while(crm_sysclk_switch_status_get() != CRM_SCLK_PLL);
crm_ahb_div_set(CRM_AHB_DIV_1);
crm_apb2_div_set(CRM_APB2_DIV_2);
crm_apb1_div_set(CRM_APB1_DIV_2);
system_core_clock_update();
}
/**
* @brief TMR6初始化:50μs中断周期,用于精准计时
* @param none
* @retval none
*/
void tmr6_init(void)
{
crm_periph_clock_enable(CRM_TMR6_PERIPH_CLOCK, TRUE);
tmr_base_init(TMR6, 50 - 1, 64 - 1); // 64MHz/64/50 = 20000Hz(50μs)
tmr_cnt_dir_set(TMR6, TMR_COUNT_UP);
tmr_interrupt_enable(TMR6, TMR_OVF_INT, TRUE);
nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
nvic_irq_enable(TMR6_GLOBAL_IRQn, 0, 0);
tmr_counter_enable(TMR6, TRUE);
}
/**
* @brief TMR6中断服务函数:更新系统计时
* @param none
* @retval none
*/
void TMR6_GLOBAL_IRQHandler(void)
{
if(tmr_flag_get(TMR6, TMR_OVF_FLAG) != RESET)
{
gSysTick++; // 每50μs加1
tmr_flag_clear(TMR6, TMR_OVF_FLAG);
}
}
/**
* @brief LED引脚初始化:仅GPIOB的6号引脚
* @param none
* @retval none
*/
void led_gpio_init(void)
{
crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
gpio_init_type gpio_init_struct;
gpio_init_struct.gpio_pins = GPIO_PINS_6;
gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init(GPIOB, &gpio_init_struct);
// 初始熄灭LED(置低)
gpio_bits_reset(GPIOB, GPIO_PINS_6);
}
/**
* @brief PB6控制:50μs亮、1ms灭
* @param none
* @retval none
*/
void pb6_ctrl(void)
{
static uint8_t state = 0; // 0:灭 1:亮
static uint32_t tick = 0;
if (state == 0) // 灭→亮,持续50μs
{
gpio_bits_set(GPIOB, GPIO_PINS_6); // 亮
tick = gSysTick;
state = 1;
}
else if (gSysTick - tick >= 1) // 50μs * 1 = 50μs
{
gpio_bits_reset(GPIOB, GPIO_PINS_6); // 灭
tick = gSysTick;
state = 0;
}
// 灭的持续时间:1ms = 50μs * 20 → 计数20次
if (state == 0 && gSysTick - tick >= 20)
{
tick = gSysTick;
}
}
int main(void)
{
system_clock_config(); // 初始化系统时钟
led_gpio_init(); // 初始化PB6引脚
tmr6_init(); // 初始化50μs定时器
while(1)
{
pb6_ctrl(); // 循环控制PB6亮灭
}
}
#include "at32f403a_407_conf.h"
// 声明外部函数
extern void display_dec_int(int num);
extern void display_scan(void);
extern void key_gpio_init(void);
extern uint8_t key_scan(void);
extern void delay_ms(int ms);
// 全局计数变量
int num = 0;
// 用于自动计数的定时器中断计数变量
static int auto_count_tick = 0;
// 自动计数间隔(单位:毫秒,这里设置为1000毫秒即1秒)
#define AUTO_COUNT_INTERVAL 1000
// 系统时钟配置
void system_clock_config(void)
{
crm_reset();
crm_clock_source_enable(CRM_CLOCK_SOURCE_HICK, TRUE);
while (crm_flag_get(CRM_HICK_STABLE_FLAG) != SET);
crm_pll_config(CRM_PLL_SOURCE_HICK, CRM_PLL_MULT_16, CRM_PLL_OUTPUT_RANGE_LE72MHZ);
crm_clock_source_enable(CRM_CLOCK_SOURCE_PLL, TRUE);
while (crm_flag_get(CRM_PLL_STABLE_FLAG) != SET);
crm_sysclk_switch(CRM_SCLK_PLL);
while (crm_sysclk_switch_status_get() != CRM_SCLK_PLL);
crm_ahb_div_set(CRM_AHB_DIV_1);
crm_apb2_div_set(CRM_APB2_DIV_2);
crm_apb1_div_set(CRM_APB1_DIV_2);
system_core_clock_update();
}
// GPIO初始化(数码管相关)
void gpio_pins_init(void)
{
crm_periph_clock_enable(CRM_GPIOE_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_GPIOD_PERIPH_CLOCK, TRUE);
gpio_init_type gpio_init_struct;
gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
// 配置PE0 - PE7为段码输出
gpio_init_struct.gpio_pins = GPIO_PINS_0 | GPIO_PINS_1 | GPIO_PINS_2 | GPIO_PINS_3 |
GPIO_PINS_4 | GPIO_PINS_5 | GPIO_PINS_6 | GPIO_PINS_7;
gpio_init(GPIOE, &gpio_init_struct);
// 配置PD2 - PD5为位选输出
gpio_init_struct.gpio_pins = GPIO_PINS_2 | GPIO_PINS_3 | GPIO_PINS_4 | GPIO_PINS_5;
gpio_init(GPIOD, &gpio_init_struct);
}
// 定时器TMR6初始化,用于数码管动态扫描和自动计数计时
void tmr6_init(void)
{
crm_periph_clock_enable(CRM_TMR6_PERIPH_CLOCK, TRUE);
tmr_base_init(TMR6, 1000 - 1, 64 - 1); // 1ms定时
tmr_cnt_dir_set(TMR6, TMR_COUNT_UP);
tmr_interrupt_enable(TMR6, TMR_OVF_INT, TRUE);
nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
nvic_irq_enable(TMR6_GLOBAL_IRQn, 0, 0);
tmr_counter_enable(TMR6, TRUE);
}
// TMR6中断服务函数,调用数码管扫描,同时实现自动计数计时
void TMR6_GLOBAL_IRQHandler(void)
{
if (tmr_flag_get(TMR6, TMR_OVF_FLAG) != RESET)
{
display_scan();
auto_count_tick++;
if (auto_count_tick >= AUTO_COUNT_INTERVAL)
{
auto_count_tick = 0;
num++;
if (num > 9999)
{
num = 0;
}
display_dec_int(num);
}
tmr_flag_clear(TMR6, TMR_OVF_FLAG);
}
}
int main(void)
{
uint8_t key_val;
// 初始化
system_clock_config();
gpio_pins_init();
tmr6_init();
key_gpio_init();
// 初始显示0
display_dec_int(num);
while (1)
{
// 扫描按键
key_val = key_scan();
if (key_val == 1)
{
// 按键1按下,减1
num--;
if (num < 0)
{
num = 9999;
}
display_dec_int(num);
}
else if (key_val == 2)
{
// 按键2按下,加1
num++;
if (num > 9999)
{
num = 0;
}
display_dec_int(num);
}
}
}
#include "at32f403a_407_conf.h"
// 显示缓冲区,存储4位数码管的段码(共阳极)
uint8_t disp_buf[4];
// 共阳极数码管段码表,0 - 9对应的段码
const uint8_t seg_table[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90};
// 将整数分解为各位并更新显示缓冲区
void display_dec_int(int num)
{
disp_buf[0] = seg_table[num / 1000 % 10]; // 千位
disp_buf[1] = seg_table[num / 100 % 10]; // 百位
disp_buf[2] = seg_table[num / 10 % 10]; // 十位
disp_buf[3] = seg_table[num % 10]; // 个位
}
// 数码管动态扫描函数,利用定时器中断调用,实现视觉暂留
void display_scan(void)
{
static uint8_t cur_digit = 0;
// 关闭所有位选
gpio_bits_set(GPIOD, GPIO_PINS_2 | GPIO_PINS_3 | GPIO_PINS_4 | GPIO_PINS_5);
// 输出当前位的段码
gpio_bits_reset(GPIOE, 0xFF);
gpio_bits_set(GPIOE, disp_buf[cur_digit]);
// 打开当前位选
gpio_bits_reset(GPIOD, GPIO_PINS_2 << cur_digit);
// 切换到下一位
cur_digit = (cur_digit + 1) % 4;
}
#include "at32f403a_407_conf.h"
// 微秒级延时函数
void delay_us(int us)
{
SysTick->LOAD = system_core_clock / 1000000 * us - 1;
SysTick->VAL = 0;
SysTick->CTRL = 0x5;
while ((SysTick->CTRL & (1 << 16)) == 0);
SysTick->CTRL = 0;
}
// 毫秒级延时函数
void delay_ms(int ms)
{
for (; ms > 0; ms--)
delay_us(1000);
}
#include "at32f403a_407_conf.h"
// 声明全局计数变量,供其他文件修改
extern int num;
// 按键消抖延时(单位:毫秒)
#define KEY_DELAY_MS 20
// 按键 GPIO 初始化:按键1接PD6,按键2接PD7,上拉输入
void key_gpio_init(void)
{
// 使能GPIOD时钟
crm_periph_clock_enable(CRM_GPIOD_PERIPH_CLOCK, TRUE);
gpio_init_type gpio_init_struct;
gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
gpio_init_struct.gpio_pull = GPIO_PULL_UP;
// 配置PD6(按键1)和PD7(按键2)引脚
gpio_init_struct.gpio_pins = GPIO_PINS_6 | GPIO_PINS_7;
gpio_init(GPIOD, &gpio_init_struct);
}
// 按键消抖函数
uint8_t key_debounce(uint16_t pin)
{
if (gpio_input_data_bit_read(GPIOD, pin) == RESET)
{
// 延时消抖
delay_ms(KEY_DELAY_MS);
if (gpio_input_data_bit_read(GPIOD, pin) == RESET)
{
// 等待按键释放
while (gpio_input_data_bit_read(GPIOD, pin) == RESET);
return 1;
}
}
return 0;
}
// 按键扫描函数,返回按键值:1(按键1按下,减1)、2(按键2按下,加1)、0(无按键)
uint8_t key_scan(void)
{
if (key_debounce(GPIO_PINS_6))
{
return 1;
}
else if (key_debounce(GPIO_PINS_7))
{
return 2;
}
return 0;
}
在这几个代码的基础上 进行整合修改 要求为 led进行pwm亮灭 数码管同步显示亮度百分比 示例为100.0 99.9 0.0
将第一个代码改为此代码#include "at32f403a_407_conf.h"
// 四个LED对应引脚(GPIOB_6~9)
#define LED_PINS GPIO_PINS_6 | GPIO_PINS_7 | GPIO_PINS_8 | GPIO_PINS_9
#define LED_PORT GPIOB
// 对应TMR4通道(PB6=CH1、PB7=CH2、PB8=CH3、PB9=CH4)
#define TMR_CHANNEL1 TMR_SELECT_CHANNEL_1
#define TMR_CHANNEL2 TMR_SELECT_CHANNEL_2
#define TMR_CHANNEL3 TMR_SELECT_CHANNEL_3
#define TMR_CHANNEL4 TMR_SELECT_CHANNEL_4
void gpio_pins_init(void)
{
// 使能GPIOB时钟
crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
gpio_init_type gpio_init_struct;
gpio_default_para_init(&gpio_init_struct);
// 配置PB6~9为复用模式(TMR4 PWM输出)
gpio_init_struct.gpio_pins = LED_PINS;
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init(LED_PORT, &gpio_init_struct);
}
void tmr4_pwm_init(void)
{
uint16_t tmr_pr = 999; // 降低PWM频率,增强亮度变化感知
uint16_t prescaler_value = 0;
// 使能TMR4时钟
crm_periph_clock_enable(CRM_TMR4_PERIPH_CLOCK, TRUE);
tmr_output_config_type tmr_oc_init_structure;
prescaler_value = 0;
// TMR4时基配置
tmr_base_init(TMR4, tmr_pr, prescaler_value);
tmr_cnt_dir_set(TMR4, TMR_COUNT_UP);
tmr_clock_source_div_set(TMR4, TMR_CLOCK_DIV1);
// PWM输出配置(共阳LED:低电平点亮,用ACTIVE_LOW;共阴则改为ACTIVE_HIGH)
tmr_output_default_para_init(&tmr_oc_init_structure);
tmr_oc_init_structure.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
tmr_oc_init_structure.oc_idle_state = FALSE;
tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_LOW;
tmr_oc_init_structure.oc_output_state = TRUE;
// 配置四个通道
tmr_output_channel_config(TMR4, TMR_CHANNEL1, &tmr_oc_init_structure);
tmr_output_channel_config(TMR4, TMR_CHANNEL2, &tmr_oc_init_structure);
tmr_output_channel_config(TMR4, TMR_CHANNEL3, &tmr_oc_init_structure);
tmr_output_channel_config(TMR4, TMR_CHANNEL4, &tmr_oc_init_structure);
// 初始熄灭所有LED
tmr_channel_value_set(TMR4, TMR_CHANNEL1, 0);
tmr_channel_value_set(TMR4, TMR_CHANNEL2, 0);
tmr_channel_value_set(TMR4, TMR_CHANNEL3, 0);
tmr_channel_value_set(TMR4, TMR_CHANNEL4, 0);
// 使能通道缓冲和定时器
tmr_output_channel_buffer_enable(TMR4, TMR_CHANNEL1, TRUE);
tmr_output_channel_buffer_enable(TMR4, TMR_CHANNEL2, TRUE);
tmr_output_channel_buffer_enable(TMR4, TMR_CHANNEL3, TRUE);
tmr_output_channel_buffer_enable(TMR4, TMR_CHANNEL4, TRUE);
tmr_period_buffer_enable(TMR4, TRUE);
tmr_counter_enable(TMR4, TRUE);
}
void delay_us(int us)
{
SysTick->LOAD = us * system_core_clock / 1000000;
SysTick->VAL = 0;
SysTick->CTRL = 0x5;
while ((SysTick->CTRL & (1 << 16)) == 0);
SysTick->CTRL = 0;
}
void delay_ms(int ms)
{
for (; ms > 0; ms--)
delay_us(1000);
}
// 同步呼吸渐变效果(四个LED同时亮灭,平滑过渡)
void sync_breathe_effect(void)
{
// 同时从灭到最亮(慢渐变)
for (int i = 0; i <= 999; i += 2)
{
tmr_channel_value_set(TMR4, TMR_CHANNEL1, i);
tmr_channel_value_set(TMR4, TMR_CHANNEL2, i);
tmr_channel_value_set(TMR4, TMR_CHANNEL3, i);
tmr_channel_value_set(TMR4, TMR_CHANNEL4, i);
delay_ms(2);
}
delay_ms(400); // 保持最亮状态
// 同时从最亮到灭(慢渐变)
for (int i = 999; i >= 0; i -= 2)
{
tmr_channel_value_set(TMR4, TMR_CHANNEL1, i);
tmr_channel_value_set(TMR4, TMR_CHANNEL2, i);
tmr_channel_value_set(TMR4, TMR_CHANNEL3, i);
tmr_channel_value_set(TMR4, TMR_CHANNEL4, i);
delay_ms(2);
}
delay_ms(400); // 保持熄灭状态
}
int main(void)
{
gpio_pins_init();
tmr4_pwm_init();
// 循环执行同步呼吸渐变
for (;;)
{
sync_breathe_effect();
}
}
摈弃第一个代码的示例