/* add user code begin Header */
/**
**************************************************************************
* @file at32a423_int.c
* @brief main interrupt service routines.
**************************************************************************
* Copyright notice & Disclaimer
*
* The software Board Support Package (BSP) that is made available to
* download from Artery official website is the copyrighted work of Artery.
* Artery authorizes customers to use, copy, and distribute the BSP
* software and its related documentation for the purpose of design and
* development in conjunction with Artery microcontrollers. Use of the
* software is governed by this copyright notice and the following disclaimer.
*
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
*
**************************************************************************
*/
/* add user code end Header */
/* includes ------------------------------------------------------------------*/
#include "at32a423_int.h"
#include "wk_system.h"
volatile uint32_t flow_pulse_count = 0; // 脉冲计数
volatile uint32_t flow_frequency_hz = 0; // 测量频率(Hz)
float flow_rate_l_min = 0.0f; // 流量值(L/min)
uint32_t last_measure_time = 0;// 上次测量时间戳
static uint32_t interrupt_count = 0;
#define FRAME_MAX_LEN 64 // 定义最大帧长度
typedef enum {
UART_RX_IDLE = 0, // 空闲状态
UART_RX_RECEIVING, // 接收中状态
UART_RX_COMPLETE // 接收完成状态
} UART_RX_Status;
typedef struct {
uint8_t buffer[FRAME_MAX_LEN]; // 接收缓冲区
uint16_t index; // 当前接收位置
uint16_t length; // 帧长度
UART_RX_Status status; // 接收状态
uint8_t frameComplete; // 帧接收完成标志
} UART_RX_Handler;
UART_RX_Handler uart3_rx;
//#define PULSES_PER_LITER 450 // 每升水对应的脉冲数
//#define MEASURE_INTERVAL 1000 // 测量间隔(ms)
/* private includes ----------------------------------------------------------*/
/* add user code begin private includes */
/* add user code end private includes */
/* private typedef -----------------------------------------------------------*/
/* add user code begin private typedef */
/* add user code end private typedef */
/* private define ------------------------------------------------------------*/
/* add user code begin private define */
/* add user code end private define */
/* private macro -------------------------------------------------------------*/
/* add user code begin private macro */
/* add user code end private macro */
/* private variables ---------------------------------------------------------*/
/* add user code begin private variables */
/* add user code end private variables */
/* private function prototypes --------------------------------------------*/
/* add user code begin function prototypes */
/* add user code end function prototypes */
/* private user code ---------------------------------------------------------*/
/* add user code begin 0 */
/* add user code end 0 */
/* external variables ---------------------------------------------------------*/
/* add user code begin external variables */
/* add user code end external variables */
/**
* @brief this function handles nmi exception.
* @param none
* @retval none
*/
void NMI_Handler(void)
{
/* add user code begin NonMaskableInt_IRQ 0 */
/* add user code end NonMaskableInt_IRQ 0 */
/* add user code begin NonMaskableInt_IRQ 1 */
/* add user code end NonMaskableInt_IRQ 1 */
}
/**
* @brief this function handles hard fault exception.
* @param none
* @retval none
*/
void HardFault_Handler(void)
{
/* add user code begin HardFault_IRQ 0 */
/* add user code end HardFault_IRQ 0 */
/* go to infinite loop when hard fault exception occurs */
while (1)
{
/* add user code begin W1_HardFault_IRQ 0 */
/* add user code end W1_HardFault_IRQ 0 */
}
}
/**
* @brief this function handles memory manage exception.
* @param none
* @retval none
*/
void MemManage_Handler(void)
{
/* add user code begin MemoryManagement_IRQ 0 */
/* add user code end MemoryManagement_IRQ 0 */
/* go to infinite loop when memory manage exception occurs */
while (1)
{
/* add user code begin W1_MemoryManagement_IRQ 0 */
/* add user code end W1_MemoryManagement_IRQ 0 */
}
}
/**
* @brief this function handles bus fault exception.
* @param none
* @retval none
*/
void BusFault_Handler(void)
{
/* add user code begin BusFault_IRQ 0 */
/* add user code end BusFault_IRQ 0 */
/* go to infinite loop when bus fault exception occurs */
while (1)
{
/* add user code begin W1_BusFault_IRQ 0 */
/* add user code end W1_BusFault_IRQ 0 */
}
}
/**
* @brief this function handles usage fault exception.
* @param none
* @retval none
*/
void UsageFault_Handler(void)
{
/* add user code begin UsageFault_IRQ 0 */
/* add user code end UsageFault_IRQ 0 */
/* go to infinite loop when usage fault exception occurs */
while (1)
{
/* add user code begin W1_UsageFault_IRQ 0 */
/* add user code end W1_UsageFault_IRQ 0 */
}
}
/**
* @brief this function handles svcall exception.
* @param none
* @retval none
*/
void SVC_Handler(void)
{
/* add user code begin SVCall_IRQ 0 */
/* add user code end SVCall_IRQ 0 */
/* add user code begin SVCall_IRQ 1 */
/* add user code end SVCall_IRQ 1 */
}
/**
* @brief this function handles debug monitor exception.
* @param none
* @retval none
*/
void DebugMon_Handler(void)
{
/* add user code begin DebugMonitor_IRQ 0 */
/* add user code end DebugMonitor_IRQ 0 */
/* add user code begin DebugMonitor_IRQ 1 */
/* add user code end DebugMonitor_IRQ 1 */
}
/**
* @brief this function handles pendsv_handler exception.
* @param none
* @retval none
*/
void PendSV_Handler(void)
{
/* add user code begin PendSV_IRQ 0 */
/* add user code end PendSV_IRQ 0 */
/* add user code begin PendSV_IRQ 1 */
/* add user code end PendSV_IRQ 1 */
}
/**
* @brief this function handles systick handler.
* @param none
* @retval none
*/
void SysTick_Handler(void)
{
/* add user code begin SysTick_IRQ 0 */
/* add user code end SysTick_IRQ 0 */
wk_timebase_handler();
/* add user code begin SysTick_IRQ 1 */
/* add user code end SysTick_IRQ 1 */
}
/**
* @brief this function handles ADC1 handler.
* @param none
* @retval none
*/
void ADC1_IRQHandler(void)
{
/* add user code begin ADC1_IRQ 0 */
/* add user code end ADC1_IRQ 0 */
/* add user code begin ADC1_IRQ 1 */
/* add user code end ADC1_IRQ 1 */
}
void USART3_IRQHandler(void)
{
/* add user code begin USART1_IRQ 0 */
uint16_t reval;
// time_ira_cnt = 0;
/* clear upgrade time out flag */
if(usart_flag_get(USART3, USART_RDBF_FLAG) != RESET)
{
reval = usart_data_receive(USART3);
if(reval == 0x5A&& uart3_rx.status == UART_RX_IDLE) //帧头5A
{
uart3_rx.status = UART_RX_RECEIVING;
uart3_rx.index = 0;
uart3_rx.buffer[uart3_rx.index++] = reval;
}
else if(uart3_rx.status == UART_RX_RECEIVING)
{
// 保存接收到的
uart3_rx.buffer[uart3_rx.index++] = reval;
// 帧尾检测 (假设帧尾是0xA5)
if(reval == 0xA5)
{
uart3_rx.length = uart3_rx.index;
uart3_rx.status = UART_RX_COMPLETE;
uart3_rx.frameComplete = 1;
}
// 检查是否超出最大长度
else if(uart3_rx.index >= FRAME_MAX_LEN)
{
uart3_rx.status = UART_RX_IDLE;
uart3_rx.index = 0;
}
}
}
/* add user code end USART1_IRQ 0 */
/* add user code begin USART1_IRQ 1 */
if(usart_flag_get(USART3, USART_RDBF_FLAG) != RESET)
{
usart_flag_clear(USART3, USART_RDBF_FLAG);
}
/* add user code end USART1_IRQ 1 */
}
void Process_UART_Frame(void)
{
// int i;
if(uart3_rx.frameComplete)
{
uint8_t amd;
// 解析帧数据
// 示例:假设帧格式为 [0xAA][命令][数据1][数据2]...[0x55]
amd = uart3_rx.buffer[1]; // 命令字节
switch(amd) {
case 0x03: // 处理03命令
if(uart3_rx.buffer[0] == 0x5A && uart3_rx.buffer[2] == 0xA5) {
Send_FlowData_To_USART3(); // 发送流量数据
}
break;
// case 13:Trigger_Usart_Read(USART_TARGET_2);break;
// case 23:Trigger_Usart_Read(USART_TARGET_1);break;
// case 33:Trigger_Usart_Read(USART_TARGET_5);break;
// case 43: Send_Feedback_Frame(0x03);break;
}
// 处理完成后重置接收状态
uart3_rx.frameComplete = 0;
uart3_rx.status = UART_RX_IDLE;
uart3_rx.index = 0;
// buffer_position = 0;
// 重新启动接收
}
}
/* add user code begin 1 */
//gpio_init_type gpio_init_struct = {0};
//crm_clocks_freq_type crm_clocks_freq_struct = {0};
//tmr_input_config_type tmr_input_config_struct;
//void delay(uint32_t time);
//void uart_init(uint32_t bound);
//__IO uint32_t tmr3freq = 0;
//__IO uint32_t sys_counter = 0;
__IO uint16_t capture_count = 0;
__IO uint16_t first_capture = 0, second_capture = 0;
__IO uint32_t capture_value = 0;
volatile uint32_t overflow_count = 0; // 软件溢出计数器
/* add user code end 1 */
void TMR2_IRQHandler(void) {
if (tmr_interrupt_flag_get(TMR2, TMR_C1_FLAG) == SET) {
tmr_flag_clear(TMR2, TMR_C1_FLAG);
if (capture_count == 0) {
first_capture = tmr_channel_value_get(TMR2, TMR_SELECT_CHANNEL_1);
capture_count = 1;
} else {
second_capture = tmr_channel_value_get(TMR2, TMR_SELECT_CHANNEL_1);
if (second_capture > first_capture) {
capture_value = second_capture - first_capture;
} else {
capture_value = (0xFFFF - first_capture) + second_capture;
}
if (capture_value > 0) {
uint32_t timer_freq = 24000000; // 假设TMR2时钟为24MHz
flow_frequency_hz = timer_freq / capture_value;
flow_pulse_count ++; // 每个完整周期计数一次
}
capture_count = 0;
}
}
}
void TMR2_GLOBAL_IRQHandler(void) {
// interrupt_count++;
if (tmr_interrupt_flag_get(TMR2, TMR_OVF_FLAG) == SET) {
tmr_flag_clear(TMR2, TMR_OVF_FLAG); // 清除溢出标志
overflow_count++; // 溢出次数加1
}
if (tmr_interrupt_flag_get(TMR2, TMR_C1_FLAG) == SET) {
// 通过串口输出调试信息
tmr_flag_clear(TMR2, TMR_C1_FLAG);
flow_pulse_count ++;
}
}
void Calculate_FlowRate(void)
{
static uint32_t last_pulse_count = 0;
uint32_t pulses_in_interval;
// 计算时间间隔内的脉冲数
pulses_in_interval = flow_pulse_count - last_pulse_count;
last_pulse_count = flow_pulse_count;
// 计算频率 (Hz)
flow_frequency_hz = (pulses_in_interval * 1000) / MEASURE_INTERVAL;
// 计算流量 (L/min) = (脉冲数/脉冲每升) × (60/时间间隔秒)
flow_rate_l_min = (pulses_in_interval / (float)PULSES_PER_LITER) *
(60.0f / (MEASURE_INTERVAL / 1000.0f));
}
void Send_FlowData_To_USART3(void)
{
uint8_t tx_buffer[10]; // 发送缓冲区
uint8_t checksum = 0; // 校验和
uint8_t i;
uint8_t j;
// 1. 获取流量数据(根据你的实际数据源选择)
uint32_t flow_data = flow_pulse_count; // 使用脉冲计数
// 或者: uint32_t flow_data = (uint32_t)(flow_rate_l_min * 100); // 使用流量值(放大100倍)
// 2. 构建数据帧
tx_buffer[0] = 0x5A; // 帧头
tx_buffer[1] = 0x03; // 命令字(请求流量数据)
tx_buffer[2] = 0x04; // 数据长度(4字节)
// 将32位流量数据分解为4个字节(小端序)
tx_buffer[3] = (flow_data >> 0) & 0xFF; // 最低字节
tx_buffer[4] = (flow_data >> 8) & 0xFF;
tx_buffer[5] = (flow_data >> 16) & 0xFF;
tx_buffer[6] = (flow_data >> 24) & 0xFF; // 最高字节
// 3. 计算校验和(从命令字到数据末尾)
for( j = 1; j < 7; j++) {
checksum ^= tx_buffer[j]; // 异或校验
}
tx_buffer[7] = checksum;
tx_buffer[8] = 0xA5; // 帧尾
// 4. 通过USART3发送数据
for( i = 0; i < 9; i++) {
// 等待发送缓冲区为空
while(usart_flag_get(USART3, USART_TDBE_FLAG) == RESET) {
// 可添加超时处理
}
// 发送数据字节[6](@ref)
usart_data_transmit(USART3, tx_buffer[i]);
}
// 5. 等待最后字节发送完成
// while(usart_flag_get(USART3, USART_FLAG_TC) == RESET) {
// 确保所有数据都已物理发送完成
}
/* add user code begin Header */
/**
**************************************************************************
* @file at32a423_wk_config.c
* @brief work bench config program
**************************************************************************
* Copyright notice & Disclaimer
*
* The software Board Support Package (BSP) that is made available to
* download from Artery official website is the copyrighted work of Artery.
* Artery authorizes customers to use, copy, and distribute the BSP
* software and its related documentation for the purpose of design and
* development in conjunction with Artery microcontrollers. Use of the
* software is governed by this copyright notice and the following disclaimer.
*
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
*
**************************************************************************
*/
/* add user code end Header */
#include "at32a423_wk_config.h"
//#define PULSES_PER_LITER 450 // 每升水对应的脉冲数
//volatile uint32_t pulse_count = 0;
//float flow_rate_l_min = 0.0f;
static __IO uint32_t fac_us;
static __IO uint32_t fac_ms;
#define STEP_DELAY_MS 50
gpio_init_type gpio_init_struct = {0};
crm_clocks_freq_type crm_clocks_freq_struct = {0};
/* private includes ----------------------------------------------------------*/
/* add user code begin private includes */
/* add user code end private includes */
/* private typedef -----------------------------------------------------------*/
/* add user code begin private typedef */
/* add user code end private typedef */
/* private define ------------------------------------------------------------*/
/* add user code begin private define */
/* add user code end private define */
/* private macro -------------------------------------------------------------*/
/* add user code begin private macro */
/* add user code end private macro */
/* private variables ---------------------------------------------------------*/
/* add user code begin private variables */
/* add user code end private variables */
/* private function prototypes --------------------------------------------*/
/* add user code begin function prototypes */
/* add user code end function prototypes */
/* private user code ---------------------------------------------------------*/
/* add user code begin 0 */
/* add user code end 0 */
/**
* @brief system clock config program
* @note the system clock is configured as follow:
* system clock (sclk) = (hick / 6 * pll_ns)/(pll_ms * pll_fr)
* system clock source = HICK_VALUE
* - lick = on
* - lext = off
* - hick = on
* - hext = off
* - sclk = 150000000
* - ahbdiv = 1
* - ahbclk = 150000000
* - apb1div = 2
* - apb1clk = 75000000
* - apb2div = 1
* - apb2clk = 150000000
* - pll_ns = 75
* - pll_ms = 1
* - pll_fr = 2
* @param none
* @retval none
*/
void wk_system_clock_config(void)
{
/* reset crm */
crm_reset();
/* config flash psr register */
flash_psr_set(FLASH_WAIT_CYCLE_4);
/* enable pwc periph clock */
crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE);
/* config ldo voltage */
pwc_ldo_output_voltage_set(PWC_LDO_OUTPUT_1V3);
/* enable lick */
crm_clock_source_enable(CRM_CLOCK_SOURCE_LICK, TRUE);
/* wait till lick is ready */
while(crm_flag_get(CRM_LICK_STABLE_FLAG) != SET)
{
}
/* enable hick */
crm_clock_source_enable(CRM_CLOCK_SOURCE_HICK, TRUE);
/* wait till hick is ready */
while(crm_flag_get(CRM_HICK_STABLE_FLAG) != SET)
{
}
/* config pll clock resource
common frequency config list: pll source selected hick or hext(8mhz)
_____________________________________________________________________________
| | | | | | | | |
| sysclk | 150 | 144 | 120 | 108 | 96 | 72 | 36 |
|________|_________|_________|_________|_________|_________|_________________|
| | | | | | | | |
|pll_ns | 75 | 72 | 120 | 108 | 96 | 72 | 72 |
| | | | | | | | |
|pll_ms | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
| | | | | | | | |
|pll_fr | FR_2 | FR_2 | FR_4 | FR_4 | FR_4 | FR_4 | FR_8 |
|________|_________|_________|_________|_________|_________|________|________|
if pll clock source selects hext with other frequency values, or configure pll to other
frequency values, please use the at32 new clock configuration tool for configuration. */
crm_pll_config(CRM_PLL_SOURCE_HICK, 75, 1, CRM_PLL_FR_2);
/* enable pll */
crm_clock_source_enable(CRM_CLOCK_SOURCE_PLL, TRUE);
/* wait till pll is ready */
while(crm_flag_get(CRM_PLL_STABLE_FLAG) != SET)
{
}
/* config ahbclk */
crm_ahb_div_set(CRM_AHB_DIV_1);
/* config apb2clk, the maximum frequency of APB2 clock is 150 MHz */
crm_apb2_div_set(CRM_APB2_DIV_1);
/* config apb1clk, the maximum frequency of APB1 clock is 120 MHz */
crm_apb1_div_set(CRM_APB1_DIV_2);
/* enable auto step mode */
crm_auto_step_mode_enable(TRUE);
/* select pll as system clock source */
crm_sysclk_switch(CRM_SCLK_PLL);
/* wait till pll is used as system clock source */
while(crm_sysclk_switch_status_get() != CRM_SCLK_PLL)
{
}
/* disable auto step mode */
crm_auto_step_mode_enable(FALSE);
/* update system_core_clock global variable */
system_core_clock_update();
}
/**
* @brief config periph clock
* @param none
* @retval none
*/
void wk_periph_clock_config(void)
{
/* enable gpioa periph clock */
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
/* enable gpiob periph clock */
crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
/* enable gpiof periph clock */
crm_periph_clock_enable(CRM_GPIOF_PERIPH_CLOCK, TRUE);
/* enable tmr2 periph clock */
crm_periph_clock_enable(CRM_TMR2_PERIPH_CLOCK, TRUE);
/* enable usart3 periph clock */
crm_periph_clock_enable(CRM_USART3_PERIPH_CLOCK, TRUE);
/* enable usart1 periph clock */
crm_periph_clock_enable(CRM_USART1_PERIPH_CLOCK, TRUE);
/* enable adc1 periph clock */
crm_periph_clock_enable(CRM_ADC1_PERIPH_CLOCK, TRUE);
}
/**
* @brief nvic config
* @param none
* @retval none
*/
void wk_nvic_config(void)
{
nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0));
nvic_irq_enable(ADC1_IRQn, 0, 0);
}
/**
* @brief init usart1 function
* @param none
* @retval none
*/
void wk_usart1_init(void)
{
/* add user code begin usart1_init 0 */
/* add user code end usart1_init 0 */
gpio_init_type gpio_init_struct;
gpio_default_para_init(&gpio_init_struct);
/* add user code begin usart1_init 1 */
/* add user code end usart1_init 1 */
/* configure the TX pin */
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
gpio_init_struct.gpio_pins = GPIO_PINS_9;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init(GPIOA, &gpio_init_struct);
gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE9, GPIO_MUX_7);
/* configure the RX pin */
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
gpio_init_struct.gpio_pins = GPIO_PINS_10;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init(GPIOA, &gpio_init_struct);
gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE10, GPIO_MUX_7);
/* config usart1 clock source */
crm_usart_clock_select(CRM_USART1, CRM_USART_CLOCK_SOURCE_PCLK);
/* configure param */
usart_init(USART1, 115200, USART_DATA_8BITS, USART_STOP_1_BIT);
usart_transmitter_enable(USART1, TRUE);
usart_receiver_enable(USART1, TRUE);
usart_parity_selection_config(USART1, USART_PARITY_NONE);
usart_hardware_flow_control_set(USART1, USART_HARDWARE_FLOW_NONE);
usart_enable(USART1, TRUE);
/* add user code begin usart1_init 2 */
/* add user code end usart1_init 2 */
}
/**
* @brief init usart3 function
* @param none
* @retval none
*/
void wk_usart3_init(void)
{
/* add user code begin usart3_init 0 */
/* add user code end usart3_init 0 */
gpio_init_type gpio_init_struct;
gpio_default_para_init(&gpio_init_struct);
/* add user code begin usart3_init 1 */
/* add user code end usart3_init 1 */
/* configure the TX pin */
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
gpio_init_struct.gpio_pins = GPIO_PINS_7;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init(GPIOA, &gpio_init_struct);
gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE7, GPIO_MUX_7);
/* configure the RX pin */
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
gpio_init_struct.gpio_pins = GPIO_PINS_5;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init(GPIOA, &gpio_init_struct);
gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE5, GPIO_MUX_7);
/* config usart3 clock source */
crm_usart_clock_select(CRM_USART3, CRM_USART_CLOCK_SOURCE_PCLK);
/* configure param */
usart_init(USART3, 115200, USART_DATA_8BITS, USART_STOP_1_BIT);
usart_transmitter_enable(USART3, TRUE);
usart_receiver_enable(USART3, TRUE);
usart_parity_selection_config(USART3, USART_PARITY_NONE);
usart_hardware_flow_control_set(USART3, USART_HARDWARE_FLOW_NONE);
usart_enable(USART3, TRUE);
usart_interrupt_enable(USART3, USART_RDBF_INT, TRUE);
nvic_irq_enable(USART3_IRQn, 0, 0); // 设置合适的中断优先级
usart_enable(USART3, TRUE);
/* add user code begin usart3_init 2 */
/* add user code end usart3_init 2 */
}
/**
* @brief init adc1 function.
* @param none
* @retval none
*/
void wk_adc1_init(void)
{
/* add user code begin adc1_init 0 */
/* add user code end adc1_init 0 */
gpio_init_type gpio_init_struct;
adc_common_config_type adc_common_struct;
adc_base_config_type adc_base_struct;
gpio_default_para_init(&gpio_init_struct);
/* add user code begin adc1_init 1 */
/* add user code end adc1_init 1 */
/* configure the IN0 pin */
gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
gpio_init_struct.gpio_pins = GPIO_PINS_0;
gpio_init(GPIOA, &gpio_init_struct);
/* configure the IN1 pin */
gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
gpio_init_struct.gpio_pins = GPIO_PINS_1;
gpio_init(GPIOA, &gpio_init_struct);
/* configure the IN2 pin */
gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
gpio_init_struct.gpio_pins = GPIO_PINS_2;
gpio_init(GPIOA, &gpio_init_struct);
/* configure the IN3 pin */
gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
gpio_init_struct.gpio_pins = GPIO_PINS_3;
gpio_init(GPIOA, &gpio_init_struct);
/* configure the IN4 pin */
gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
gpio_init_struct.gpio_pins = GPIO_PINS_4;
gpio_init(GPIOA, &gpio_init_struct);
/* adc_common_settings--------------------------------------------------------------*/
/* config adc clock source */
crm_adc_clock_select(CRM_ADC_CLOCK_SOURCE_HCLK);
adc_common_default_para_init(&adc_common_struct);
/* config adc clock division */
adc_common_struct.div = ADC_HCLK_DIV_2;
/* config inner temperature sensor and vintrv */
adc_common_struct.tempervintrv_state = FALSE;
adc_common_config(&adc_common_struct);
/* adc_settings------------------------------------------------------------------- */
adc_base_default_para_init(&adc_base_struct);
adc_base_struct.sequence_mode = FALSE;
adc_base_struct.repeat_mode = FALSE;
adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT;
adc_base_struct.ordinary_channel_length = 1;
adc_base_config(ADC1, &adc_base_struct);
/* adc_ordinary_conversionmode---------------------------------------------------- */
adc_ordinary_channel_set(ADC1, ADC_CHANNEL_0, 1, ADC_SAMPLETIME_6_5);
adc_ordinary_conversion_trigger_set(ADC1, ADC_ORDINARY_TRIG_SOFTWARE, ADC_ORDINARY_TRIG_EDGE_NONE);
/**
* Users need to configure ADC1 interrupt functions according to the actual application.
* 1. Call the below function to enable the corresponding ADC1 interrupt.
* --adc_interrupt_enable(...)
* 2. Add the user's interrupt handler code into the below function in the at32a423_int.c file.
* --void ADC1_IRQHandler(void)
*/
adc_enable(ADC1, TRUE);
while(adc_flag_get(ADC1, ADC_RDY_FLAG) == RESET);
/* adc calibration---------------------------------------------------------------- */
adc_calibration_init(ADC1);
while(adc_calibration_init_status_get(ADC1));
adc_calibration_start(ADC1);
while(adc_calibration_status_get(ADC1));
/* add user code begin adc1_init 2 */
/* add user code end adc1_init 2 */
}
/**
* @brief init tmr2 function.
* @param none
* @retval none
*/
void wk_tmr2_init(void)
{
/* add user code begin tmr2_init 0 */
/* add user code end tmr2_init 0 */
gpio_init_type gpio_init_struct;
tmr_input_config_type tmr_ic_init_struct;
gpio_default_para_init(&gpio_init_struct);
crm_periph_clock_enable(CRM_GPIOF_PERIPH_CLOCK, TRUE); // GPIOA时钟
crm_periph_clock_enable(CRM_TMR2_PERIPH_CLOCK, TRUE); // TIM2时钟
// crm_periph_clock_enable(CRM_IOMUX_PERIPH_CLOCK, TRUE); // IO复用时钟
/* add user code begin tmr2_init 1 */
/* add user code end tmr2_init 1 */
/* configure the tmr2 CH1 pin */
gpio_init_struct.gpio_pins = GPIO_PINS_6;
gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_pull = GPIO_PULL_UP;
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
gpio_init(GPIOF, &gpio_init_struct);
gpio_pin_mux_config(GPIOF, GPIO_PINS_SOURCE6, GPIO_MUX_1);
/* configure counter settings */
tmr_base_init(TMR2, 0xffff, 0);
tmr_cnt_dir_set(TMR2, TMR_COUNT_UP);
tmr_clock_source_div_set(TMR2, TMR_CLOCK_DIV1);
tmr_period_buffer_enable(TMR2, FALSE);
/* configure primary mode settings */
tmr_sub_sync_mode_set(TMR2, FALSE);
tmr_primary_mode_select(TMR2, TMR_PRIMARY_SEL_RESET);
/* configure pwm input with ch1 */
// 配置输入捕获
tmr_ic_init_struct.input_filter_value = 0x0f;
tmr_ic_init_struct.input_channel_select = TMR_SELECT_CHANNEL_1;
tmr_ic_init_struct.input_mapped_select = TMR_CC_CHANNEL_MAPPED_DIRECT;
tmr_ic_init_struct.input_polarity_select = TMR_INPUT_RISING_EDGE;
tmr_pwm_input_config(TMR2, &tmr_ic_init_struct, TMR_CHANNEL_INPUT_DIV_1);
tmr_trigger_input_select(TMR2, TMR_SUB_INPUT_SEL_C1DF1);
tmr_sub_mode_select(TMR2, TMR_SUB_RESET_MODE);
nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
// 启动计数器
nvic_irq_enable(TMR2_GLOBAL_IRQn, 1, 0);
tmr_interrupt_enable(TMR2, TMR_C1_INT, TRUE);
tmr_interrupt_enable(TMR2, TMR_OVF_INT, TRUE);
// 启动计数器
tmr_counter_enable(TMR2, TRUE);
/* add user code begin tmr2_init 2 */
/* add user code end tmr2_init 2 */
}
void wk_tmr3_init(void)
{
/* add user code begin tmr3_init 0 */
/* add user code end tmr3_init 0 */
gpio_init_type gpio_init_struct;
tmr_input_config_type tmr_input_struct;
tmr_input_config_type tmr_ic_init_struct;
gpio_default_para_init(&gpio_init_struct);
/* add user code begin tmr3_init 1 */
/* add user code end tmr3_init 1 */
/* configure the tmr3 CH1 pin */
gpio_init_struct.gpio_pins = GPIO_PINS_6;
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
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_MODERATE;
gpio_init(GPIOA, &gpio_init_struct);
gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE6, GPIO_MUX_2);
/* configure the tmr3 CH3 pin */
gpio_init_struct.gpio_pins = GPIO_PINS_0;
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
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_MODERATE;
gpio_init(GPIOB, &gpio_init_struct);
gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE0, GPIO_MUX_2);
/* configure counter settings */
tmr_base_init(TMR3, 65535, 0);
tmr_cnt_dir_set(TMR3, TMR_COUNT_UP);
tmr_clock_source_div_set(TMR3, TMR_CLOCK_DIV1);
tmr_period_buffer_enable(TMR3, FALSE);
/* configure primary mode settings */
tmr_sub_sync_mode_set(TMR3, FALSE);
tmr_primary_mode_select(TMR3, TMR_PRIMARY_SEL_RESET);
/* configure channel 3 input settings */
tmr_input_struct.input_channel_select = TMR_SELECT_CHANNEL_3;
tmr_input_struct.input_mapped_select = TMR_CC_CHANNEL_MAPPED_DIRECT;
tmr_input_struct.input_polarity_select = TMR_INPUT_RISING_EDGE;
tmr_input_struct.input_filter_value = 0;
tmr_input_channel_init(TMR3, &tmr_input_struct, TMR_CHANNEL_INPUT_DIV_1);
/* configure pwm input with ch1 */
tmr_ic_init_struct.input_filter_value = 0;
tmr_ic_init_struct.input_channel_select = TMR_SELECT_CHANNEL_1;
tmr_ic_init_struct.input_mapped_select = TMR_CC_CHANNEL_MAPPED_DIRECT;
tmr_ic_init_struct.input_polarity_select = TMR_INPUT_RISING_EDGE;
tmr_pwm_input_config(TMR3, &tmr_ic_init_struct, TMR_CHANNEL_INPUT_DIV_1);
tmr_trigger_input_select(TMR3, TMR_SUB_INPUT_SEL_C1DF1);
tmr_sub_mode_select(TMR3, TMR_SUB_RESET_MODE);
tmr_counter_enable(TMR3, TRUE);
/* add user code begin tmr3_init 2 */
/* add user code end tmr3_init 2 */
}
//void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {
// if (htim->Instance == TIM2) {
// pulse_count++; // 脉冲计数加1
// }
//}void Calculate_FlowRate(void) {
// static uint32_t last_pulse_count = 0;
// uint32_t pulses_in_interval;
// float time_interval_s = 1.0f; // 计算间隔1秒
//
// pulses_in_interval = pulse_count - last_pulse_count;
// last_pulse_count = pulse_count;
//
// // 流量计算公式:流量(L/min) = (脉冲数/脉冲每升) × (60/时间间隔秒)
// flow_rate_l_min = (pulses_in_interval / (float)PULSES_PER_LITER) * (60.0f / time_interval_s);
//}
/* add user code begin 1 */
/* add user code end 1 */
void delay_init(void)
{
/* configure systick */
systick_clock_source_config(SYSTICK_CLOCK_SOURCE_AHBCLK_NODIV);
fac_us = system_core_clock / (1000000U);
fac_ms = fac_us * (1000U);
}
void delay_us(uint32_t nus)
{
uint32_t temp = 0;
SysTick->LOAD = (uint32_t)(nus * fac_us);
SysTick->VAL = 0x00;
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk ;
do
{
temp = SysTick->CTRL;
}while((temp & 0x01) && !(temp & (1 << 16)));
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
SysTick->VAL = 0x00;
}
/**
* @brief inserts a delay time.
* @param nms: specifies the delay time length, in milliseconds.
* @retval none
*/
void delay_ms(uint16_t nms)
{
uint32_t temp = 0;
while(nms)
{
if(nms > STEP_DELAY_MS)
{
SysTick->LOAD = (uint32_t)(STEP_DELAY_MS * fac_ms);
nms -= STEP_DELAY_MS;
}
else
{
SysTick->LOAD = (uint32_t)(nms * fac_ms);
nms = 0;
}
SysTick->VAL = 0x00;
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
do
{
temp = SysTick->CTRL;
}while((temp & 0x01) && !(temp & (1 << 16)));
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
SysTick->VAL = 0x00;
}
}
/**
* @brief inserts a delay time.
* @param sec: specifies the delay time, in seconds.
* @retval none
*/
void delay_sec(uint16_t sec)
{
uint16_t index;
for(index = 0; index < sec; index++)
{
delay_ms(500);
delay_ms(500);
}
}
怎么过虑占空比40到60之外脉冲波形
最新发布