[feat] add ate
This commit is contained in:
parent
8c5616fbce
commit
6103e0d628
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,5 +1,6 @@
|
|||||||
bootloader/build/*
|
bootloader/build/*
|
||||||
lark1fq/build/*
|
lark1fq/build/*
|
||||||
|
ate/build/*
|
||||||
test/build/*
|
test/build/*
|
||||||
tools/*.exe
|
tools/*.exe
|
||||||
tools/*.xls
|
tools/*.xls
|
||||||
|
|||||||
87
ate/CMakeLists.txt
Executable file
87
ate/CMakeLists.txt
Executable file
@ -0,0 +1,87 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
set(PROJ_NAME "lark1fq")
|
||||||
|
set(BIN_FILE ${PROJ_NAME}.bin)
|
||||||
|
set(ASM_FILE ${PROJ_NAME}.asm)
|
||||||
|
project(${PROJ_NAME} VERSION 0.1)
|
||||||
|
|
||||||
|
# toolchain path
|
||||||
|
set(TOOLCHAIN "arm-none-eabi-")
|
||||||
|
set(CMAKE_C_COMPILER "${TOOLCHAIN}gcc")
|
||||||
|
set(CMAKE_ASM_COMPILER "${TOOLCHAIN}gcc")
|
||||||
|
set(CMAKE_OBJCOPY "${TOOLCHAIN}objcopy")
|
||||||
|
set(CMAKE_OBJDUMP "${TOOLCHAIN}objdump")
|
||||||
|
set(CMAKE_AR "${TOOLCHAIN}ar")
|
||||||
|
set(CMAKE_RANLIB "${TOOLCHAIN}ranlib")
|
||||||
|
set(LINKER_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/flash.ld")
|
||||||
|
|
||||||
|
set(CMAKE_C_FLAGS " \
|
||||||
|
-mcpu=cortex-m4 \
|
||||||
|
-mthumb \
|
||||||
|
-g3 \
|
||||||
|
-O2 \
|
||||||
|
-Wall \
|
||||||
|
-nostartfiles \
|
||||||
|
-mfloat-abi=hard \
|
||||||
|
-mfpu=vfpv4-d16 \
|
||||||
|
-ffunction-sections \
|
||||||
|
-fdata-sections \
|
||||||
|
")
|
||||||
|
|
||||||
|
set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS}")
|
||||||
|
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS " \
|
||||||
|
-ffunction-sections \
|
||||||
|
-fdata-sections \
|
||||||
|
-Wl,--gc-sections \
|
||||||
|
-T${LINKER_SCRIPT} \
|
||||||
|
-Wl,-Map=${PROJ_NAME}.map \
|
||||||
|
--specs=nano.specs \
|
||||||
|
-Wl,--print-memory-usage \
|
||||||
|
-Wl,--print-output-format \
|
||||||
|
")
|
||||||
|
|
||||||
|
add_definitions(-DSTM32F40_41xxx)
|
||||||
|
add_definitions(-DUSE_STDPERIPH_DRIVER)
|
||||||
|
|
||||||
|
enable_language(ASM)
|
||||||
|
add_executable(${PROJ_NAME}.elf main.c)
|
||||||
|
target_sources(${PROJ_NAME}.elf PUBLIC ${CMAKE_CURRENT_LIST_DIR}/start.S)
|
||||||
|
|
||||||
|
add_subdirectory(../driver driver)
|
||||||
|
target_link_libraries(${PROJ_NAME}.elf driver)
|
||||||
|
target_include_directories(${PROJ_NAME}.elf PUBLIC ../driver/stddriver/inc)
|
||||||
|
target_include_directories(${PROJ_NAME}.elf PUBLIC ../driver/cmsis/inc)
|
||||||
|
|
||||||
|
add_subdirectory(../component/fatfs component/fatfs)
|
||||||
|
target_link_libraries(${PROJ_NAME}.elf fatfs)
|
||||||
|
|
||||||
|
add_subdirectory(src src)
|
||||||
|
target_link_libraries(${PROJ_NAME}.elf src)
|
||||||
|
target_include_directories(${PROJ_NAME}.elf PUBLIC src)
|
||||||
|
|
||||||
|
target_link_libraries(${PROJ_NAME}.elf m) # math library
|
||||||
|
|
||||||
|
add_custom_command(TARGET ${PROJ_NAME}.elf POST_BUILD
|
||||||
|
COMMAND ${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:${PROJ_NAME}.elf> ${BIN_FILE}
|
||||||
|
COMMAND ${CMAKE_OBJDUMP} -d -S $<TARGET_FILE:${PROJ_NAME}.elf> >${ASM_FILE}
|
||||||
|
# COMMENT "Generate ${BIN_FILE}\r\n"
|
||||||
|
COMMAND size ${PROJ_NAME}.elf
|
||||||
|
COMMAND echo "Calculating SHA-256 checksum for ${BIN_FILE}:"
|
||||||
|
COMMAND sha256sum ${BIN_FILE}
|
||||||
|
)
|
||||||
|
|
||||||
|
# get git tag
|
||||||
|
execute_process(
|
||||||
|
COMMAND git describe --abbrev=40 --tags --dirty --always
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
OUTPUT_VARIABLE GIT_TAG
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
ERROR_QUIET
|
||||||
|
)
|
||||||
|
if(GIT_TAG)
|
||||||
|
set(PROJECT_SDK_VERSION ${GIT_TAG})
|
||||||
|
else()
|
||||||
|
message(WARNING "No Valid version info found for SDK!")
|
||||||
|
set(PROJECT_SDK_VERSION "version-unknown-panic")
|
||||||
|
endif()
|
||||||
|
message(STATUS "Project SDK Version: ${PROJECT_SDK_VERSION}")
|
||||||
18
ate/Makefile
Normal file
18
ate/Makefile
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
CMAKE = cmake # use user cmake
|
||||||
|
cmake_generator = "Unix Makefiles"
|
||||||
|
RM = $(CMAKE) -E remove_directory
|
||||||
|
MAKEFLAGS += --no-print-directory
|
||||||
|
|
||||||
|
TOOLCHAIN ?= arm-none-eabi-
|
||||||
|
|
||||||
|
#cmake definition config
|
||||||
|
cmake_definition+= -DTOOLCHAIN=${TOOLCHAIN}
|
||||||
|
|
||||||
|
build:Makefile
|
||||||
|
$(CMAKE) -S . -B build -G $(cmake_generator) $(cmake_definition)
|
||||||
|
$(MAKE) -C build -j
|
||||||
|
|
||||||
|
clean::
|
||||||
|
$(RM) build
|
||||||
|
|
||||||
|
.PHONY:build clean
|
||||||
80
ate/flash.ld
Executable file
80
ate/flash.ld
Executable file
@ -0,0 +1,80 @@
|
|||||||
|
ENTRY(Reset_Handler)
|
||||||
|
|
||||||
|
StackSize = 0x4000; /* 16KB */
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
FLASH (rx) :ORIGIN = 0x08020000, LENGTH = 384K
|
||||||
|
RAM (xrw) :ORIGIN = 0x20000000, LENGTH = 112K
|
||||||
|
CCM (rw) :ORIGIN = 0x10000000, LENGTH = 64K - StackSize
|
||||||
|
}
|
||||||
|
|
||||||
|
_stack_top = ORIGIN(CCM) + LENGTH(CCM) + StackSize;
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.isr_vector :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
KEEP(*(.isr_vector))
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >FLASH
|
||||||
|
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
*(.text) /* .text sections (code) */
|
||||||
|
*(.text*) /* .text* sections (code) */
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >FLASH
|
||||||
|
|
||||||
|
.rodata :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
*(.rodata)
|
||||||
|
*(.rodata*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >FLASH
|
||||||
|
|
||||||
|
_data_load = LOADADDR(.data);
|
||||||
|
.data :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_data_run = .;
|
||||||
|
*(.data)
|
||||||
|
*(.data.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_data_run_end = .;
|
||||||
|
} >RAM AT>FLASH
|
||||||
|
|
||||||
|
_data_ccm_load = LOADADDR(.data_ccm);
|
||||||
|
.data_ccm :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_data_ccm_run = .;
|
||||||
|
*(.data_ccm)
|
||||||
|
*(.data_ccm*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_data_ccm_run_end = .;
|
||||||
|
} >CCM AT>FLASH
|
||||||
|
|
||||||
|
.bss (NOLOAD) :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_bss_run = .;
|
||||||
|
*(.bss)
|
||||||
|
*(.bss.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_bss_run_end = .;
|
||||||
|
} >RAM
|
||||||
|
|
||||||
|
.bss_ccm (NOLOAD) :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_bss_ccm_run = .;
|
||||||
|
*(.bss_ccm)
|
||||||
|
*(.bss_ccm.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_bss_ccm_run_end = .;
|
||||||
|
} >CCM
|
||||||
|
}
|
||||||
55
ate/main.c
Executable file
55
ate/main.c
Executable file
@ -0,0 +1,55 @@
|
|||||||
|
#include "led.h"
|
||||||
|
#include "button.h"
|
||||||
|
#include "heat.h"
|
||||||
|
#include "ltc1867.h"
|
||||||
|
#include "modbus.h"
|
||||||
|
#include "ltc2640.h"
|
||||||
|
#include "calc.h"
|
||||||
|
#include "sd.h"
|
||||||
|
#include "stm32f4xx_rcc.h"
|
||||||
|
|
||||||
|
uint32_t system_tick_cnt;
|
||||||
|
|
||||||
|
void system_tick_init(void)
|
||||||
|
{
|
||||||
|
RCC_ClocksTypeDef rcc_clocks;
|
||||||
|
|
||||||
|
system_tick_cnt = 0;
|
||||||
|
RCC_GetClocksFreq(&rcc_clocks);
|
||||||
|
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
|
||||||
|
SysTick_Config(rcc_clocks.HCLK_Frequency / 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void system_init(void)
|
||||||
|
{
|
||||||
|
led_init(LED1 | LED2);
|
||||||
|
button_init();
|
||||||
|
heat_init();
|
||||||
|
ltc1867_init();
|
||||||
|
modbus_init();
|
||||||
|
system_tick_init();
|
||||||
|
ltc2640_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
system_init();
|
||||||
|
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
|
||||||
|
SCB->VTOR = 0x08020000;
|
||||||
|
__enable_irq();
|
||||||
|
while (1) {
|
||||||
|
modbus_loop();
|
||||||
|
led_loop();
|
||||||
|
button_loop();
|
||||||
|
heat_loop();
|
||||||
|
ltc2640_loop();
|
||||||
|
calc_loop();
|
||||||
|
sd_loop();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SysTick_Handler(void)
|
||||||
|
{
|
||||||
|
system_tick_cnt++;
|
||||||
|
}
|
||||||
576
ate/script/ate.py
Normal file
576
ate/script/ate.py
Normal file
@ -0,0 +1,576 @@
|
|||||||
|
import tkinter as tk
|
||||||
|
from tkinter import ttk, messagebox
|
||||||
|
import serial
|
||||||
|
import serial.tools.list_ports
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
from datetime import datetime
|
||||||
|
import crcmod
|
||||||
|
|
||||||
|
class ATEApplication:
|
||||||
|
def __init__(self, root):
|
||||||
|
self.root = root
|
||||||
|
self.root.title("LARK-1FQ ATE设备监控")
|
||||||
|
self.root.geometry("680x480")
|
||||||
|
|
||||||
|
# 串口相关变量
|
||||||
|
self.serial_port = None
|
||||||
|
self.is_connected = False
|
||||||
|
self.read_thread = None
|
||||||
|
self.stop_thread = False
|
||||||
|
self.receive_buffer = bytearray() # 接收缓冲区
|
||||||
|
|
||||||
|
# 创建CRC计算函数
|
||||||
|
self.crc16_func = crcmod.mkCrcFun(0x18005, rev=True, initCrc=0xFFFF, xorOut=0x0000)
|
||||||
|
|
||||||
|
# 数据存储
|
||||||
|
self.frequency_values = [0, 0, 0, 0] # ch0-ch3 频率值
|
||||||
|
self.peak_values = [0, 0, 0, 0] # ch0-ch3 峰峰值
|
||||||
|
self.key_status = 0 # 按键状态
|
||||||
|
self.sd_status = 0 # SD卡状态
|
||||||
|
|
||||||
|
# 上下限设置
|
||||||
|
self.freq_limits = [
|
||||||
|
{"min": 7, "max": 9}, # ch0
|
||||||
|
{"min": 7, "max": 9}, # ch1
|
||||||
|
{"min": 7, "max": 9}, # ch2
|
||||||
|
{"min": 7, "max": 9} # ch3
|
||||||
|
]
|
||||||
|
|
||||||
|
self.peak_limits = [
|
||||||
|
{"min": 2000, "max": 4000}, # ch0
|
||||||
|
{"min": 2000, "max": 4000}, # ch1
|
||||||
|
{"min": 2000, "max": 4000}, # ch2
|
||||||
|
{"min": 2000, "max": 4000} # ch3
|
||||||
|
]
|
||||||
|
|
||||||
|
self.create_widgets()
|
||||||
|
self.refresh_ports()
|
||||||
|
|
||||||
|
# 设置关闭事件
|
||||||
|
self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
|
||||||
|
|
||||||
|
def create_widgets(self):
|
||||||
|
# 1. 串口相关界面
|
||||||
|
serial_frame = ttk.LabelFrame(self.root, text="串口设置", padding=10)
|
||||||
|
serial_frame.pack(fill="x", padx=10, pady=5)
|
||||||
|
|
||||||
|
# 串口号选择
|
||||||
|
ttk.Label(serial_frame, text="串口号:").grid(row=0, column=0, padx=5)
|
||||||
|
self.port_var = tk.StringVar()
|
||||||
|
self.port_combobox = ttk.Combobox(serial_frame, textvariable=self.port_var, width=15)
|
||||||
|
self.port_combobox.grid(row=0, column=1, padx=5)
|
||||||
|
|
||||||
|
self.refresh_btn = ttk.Button(serial_frame, text="刷新", command=self.refresh_ports)
|
||||||
|
self.refresh_btn.grid(row=0, column=2, padx=5)
|
||||||
|
|
||||||
|
# 波特率选择
|
||||||
|
ttk.Label(serial_frame, text="波特率:").grid(row=0, column=3, padx=5)
|
||||||
|
self.baud_var = tk.StringVar(value="19200")
|
||||||
|
baud_combobox = ttk.Combobox(serial_frame, textvariable=self.baud_var,
|
||||||
|
values=["9600", "19200", "38400", "57600", "115200"], width=10)
|
||||||
|
baud_combobox.grid(row=0, column=4, padx=5)
|
||||||
|
|
||||||
|
# 打开关闭按钮
|
||||||
|
self.open_btn = ttk.Button(serial_frame, text="打开串口", command=self.open_serial)
|
||||||
|
self.open_btn.grid(row=0, column=5, padx=5)
|
||||||
|
|
||||||
|
self.close_btn = ttk.Button(serial_frame, text="关闭串口", command=self.close_serial, state="disabled")
|
||||||
|
self.close_btn.grid(row=0, column=6, padx=5)
|
||||||
|
|
||||||
|
# 调试信息显示
|
||||||
|
self.debug_var = tk.StringVar(value="等待连接...")
|
||||||
|
debug_label = ttk.Label(serial_frame, textvariable=self.debug_var, foreground="blue")
|
||||||
|
debug_label.grid(row=1, column=0, columnspan=7, pady=5)
|
||||||
|
|
||||||
|
# 2. 数值比较界面
|
||||||
|
value_frame = ttk.LabelFrame(self.root, text="数值比较", padding=10)
|
||||||
|
value_frame.pack(fill="both", expand=True, padx=10, pady=5)
|
||||||
|
|
||||||
|
# 频率部分(左边)
|
||||||
|
freq_frame = ttk.LabelFrame(value_frame, text="频率 (Hz)")
|
||||||
|
freq_frame.pack(side="left", fill="both", expand=True, padx=5)
|
||||||
|
|
||||||
|
self.freq_widgets = []
|
||||||
|
for i in range(4):
|
||||||
|
ch_frame = ttk.Frame(freq_frame)
|
||||||
|
ch_frame.pack(fill="x", pady=2)
|
||||||
|
|
||||||
|
ttk.Label(ch_frame, text=f"CH{i}:").pack(side="left")
|
||||||
|
|
||||||
|
# 最小值输入
|
||||||
|
min_frame = ttk.Frame(ch_frame)
|
||||||
|
min_frame.pack(side="left", padx=2)
|
||||||
|
ttk.Label(min_frame, text="min:").pack()
|
||||||
|
min_var = tk.StringVar(value="7")
|
||||||
|
min_entry = tk.Entry(min_frame, textvariable=min_var, width=5, bg="white")
|
||||||
|
min_entry.pack()
|
||||||
|
min_entry.bind('<Return>', lambda e, ch=i: self.update_freq_limit(ch))
|
||||||
|
|
||||||
|
# 当前值显示
|
||||||
|
value_label = tk.Label(ch_frame, text="0.0", width=8, relief="sunken", bg="white")
|
||||||
|
value_label.pack(side="left", padx=5)
|
||||||
|
|
||||||
|
# 最大值输入
|
||||||
|
max_frame = ttk.Frame(ch_frame)
|
||||||
|
max_frame.pack(side="left", padx=2)
|
||||||
|
ttk.Label(max_frame, text="max:").pack()
|
||||||
|
max_var = tk.StringVar(value="9")
|
||||||
|
max_entry = tk.Entry(max_frame, textvariable=max_var, width=5, bg="white")
|
||||||
|
max_entry.pack()
|
||||||
|
max_entry.bind('<Return>', lambda e, ch=i: self.update_freq_limit(ch))
|
||||||
|
|
||||||
|
self.freq_widgets.append({
|
||||||
|
"min_var": min_var,
|
||||||
|
"max_var": max_var,
|
||||||
|
"min_entry": min_entry,
|
||||||
|
"max_entry": max_entry,
|
||||||
|
"value_label": value_label
|
||||||
|
})
|
||||||
|
|
||||||
|
# 峰峰值部分(右边)
|
||||||
|
peak_frame = ttk.LabelFrame(value_frame, text="峰峰值 (mV)")
|
||||||
|
peak_frame.pack(side="right", fill="both", expand=True, padx=5)
|
||||||
|
|
||||||
|
self.peak_widgets = []
|
||||||
|
for i in range(4):
|
||||||
|
ch_frame = ttk.Frame(peak_frame)
|
||||||
|
ch_frame.pack(fill="x", pady=2)
|
||||||
|
|
||||||
|
ttk.Label(ch_frame, text=f"CH{i}:").pack(side="left")
|
||||||
|
|
||||||
|
# 最小值输入
|
||||||
|
min_frame = ttk.Frame(ch_frame)
|
||||||
|
min_frame.pack(side="left", padx=2)
|
||||||
|
ttk.Label(min_frame, text="min:").pack()
|
||||||
|
min_var = tk.StringVar(value="2000")
|
||||||
|
min_entry = tk.Entry(min_frame, textvariable=min_var, width=5, bg="white")
|
||||||
|
min_entry.pack()
|
||||||
|
min_entry.bind('<Return>', lambda e, ch=i: self.update_peak_limit(ch))
|
||||||
|
|
||||||
|
# 当前值显示
|
||||||
|
value_label = tk.Label(ch_frame, text="0", width=8, relief="sunken", bg="white")
|
||||||
|
value_label.pack(side="left", padx=5)
|
||||||
|
|
||||||
|
# 最大值输入
|
||||||
|
max_frame = ttk.Frame(ch_frame)
|
||||||
|
max_frame.pack(side="left", padx=2)
|
||||||
|
ttk.Label(max_frame, text="max:").pack()
|
||||||
|
max_var = tk.StringVar(value="4000")
|
||||||
|
max_entry = tk.Entry(max_frame, textvariable=max_var, width=5, bg="white")
|
||||||
|
max_entry.pack()
|
||||||
|
max_entry.bind('<Return>', lambda e, ch=i: self.update_peak_limit(ch))
|
||||||
|
|
||||||
|
self.peak_widgets.append({
|
||||||
|
"min_var": min_var,
|
||||||
|
"max_var": max_var,
|
||||||
|
"min_entry": min_entry,
|
||||||
|
"max_entry": max_entry,
|
||||||
|
"value_label": value_label
|
||||||
|
})
|
||||||
|
|
||||||
|
# 3. 状态显示界面
|
||||||
|
status_frame = ttk.LabelFrame(self.root, text="状态显示", padding=10)
|
||||||
|
status_frame.pack(fill="x", padx=10, pady=5)
|
||||||
|
|
||||||
|
# 通讯状态
|
||||||
|
comm_frame = ttk.Frame(status_frame)
|
||||||
|
comm_frame.pack(side="left", expand=True)
|
||||||
|
ttk.Label(comm_frame, text="通讯状态:").pack()
|
||||||
|
self.comm_status = tk.Label(comm_frame, text="●", font=("Arial", 20), fg="red")
|
||||||
|
self.comm_status.pack()
|
||||||
|
|
||||||
|
# SD卡状态
|
||||||
|
sd_frame = ttk.Frame(status_frame)
|
||||||
|
sd_frame.pack(side="left", expand=True)
|
||||||
|
ttk.Label(sd_frame, text="SD卡状态:").pack()
|
||||||
|
self.sd_status_label = tk.Label(sd_frame, text="●", font=("Arial", 20), fg="red")
|
||||||
|
self.sd_status_label.pack()
|
||||||
|
|
||||||
|
# 按键状态
|
||||||
|
key_frame = ttk.Frame(status_frame)
|
||||||
|
key_frame.pack(side="left", expand=True)
|
||||||
|
ttk.Label(key_frame, text="按键状态:").pack()
|
||||||
|
self.key_status_label = tk.Label(key_frame, text="●", font=("Arial", 20), fg="red")
|
||||||
|
self.key_status_label.pack()
|
||||||
|
|
||||||
|
def refresh_ports(self):
|
||||||
|
"""刷新可用串口列表"""
|
||||||
|
ports = serial.tools.list_ports.comports()
|
||||||
|
port_list = [port.device for port in ports]
|
||||||
|
self.port_combobox['values'] = port_list
|
||||||
|
if port_list and not self.port_var.get():
|
||||||
|
self.port_var.set(port_list[0])
|
||||||
|
|
||||||
|
def open_serial(self):
|
||||||
|
"""打开串口"""
|
||||||
|
port = self.port_var.get()
|
||||||
|
baudrate = self.baud_var.get()
|
||||||
|
|
||||||
|
if not port:
|
||||||
|
messagebox.showerror("错误", "请选择串口号")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.serial_port = serial.Serial(
|
||||||
|
port=port,
|
||||||
|
baudrate=int(baudrate),
|
||||||
|
bytesize=serial.EIGHTBITS,
|
||||||
|
parity=serial.PARITY_NONE,
|
||||||
|
stopbits=serial.STOPBITS_ONE,
|
||||||
|
timeout=0.1
|
||||||
|
)
|
||||||
|
|
||||||
|
# 清空缓冲区
|
||||||
|
self.clear_serial_buffer()
|
||||||
|
self.receive_buffer = bytearray()
|
||||||
|
|
||||||
|
self.is_connected = True
|
||||||
|
self.open_btn.config(state="disabled")
|
||||||
|
self.close_btn.config(state="normal")
|
||||||
|
self.refresh_btn.config(state="disabled")
|
||||||
|
|
||||||
|
# 启动读取线程
|
||||||
|
self.stop_thread = False
|
||||||
|
self.read_thread = threading.Thread(target=self.serial_read_loop)
|
||||||
|
self.read_thread.daemon = True
|
||||||
|
self.read_thread.start()
|
||||||
|
|
||||||
|
self.update_debug_info("串口打开成功,开始发送查询命令...")
|
||||||
|
messagebox.showinfo("成功", "串口打开成功")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
messagebox.showerror("错误", f"打开串口失败: {str(e)}")
|
||||||
|
|
||||||
|
def close_serial(self):
|
||||||
|
"""关闭串口"""
|
||||||
|
self.stop_thread = True
|
||||||
|
self.is_connected = False
|
||||||
|
|
||||||
|
if self.serial_port and self.serial_port.is_open:
|
||||||
|
self.serial_port.close()
|
||||||
|
|
||||||
|
self.open_btn.config(state="normal")
|
||||||
|
self.close_btn.config(state="disabled")
|
||||||
|
self.refresh_btn.config(state="normal")
|
||||||
|
self.comm_status.config(fg="red")
|
||||||
|
self.update_debug_info("串口已关闭")
|
||||||
|
|
||||||
|
def clear_serial_buffer(self):
|
||||||
|
"""清空串口缓冲区"""
|
||||||
|
if self.serial_port and self.serial_port.is_open:
|
||||||
|
try:
|
||||||
|
self.serial_port.reset_input_buffer()
|
||||||
|
self.serial_port.reset_output_buffer()
|
||||||
|
self.receive_buffer.clear()
|
||||||
|
self.update_debug_info("串口缓冲区已清空")
|
||||||
|
except Exception as e:
|
||||||
|
self.update_debug_info(f"清空缓冲区错误: {e}")
|
||||||
|
|
||||||
|
def update_debug_info(self, message):
|
||||||
|
"""更新调试信息"""
|
||||||
|
timestamp = datetime.now().strftime("%H:%M:%S.%f")[:-3]
|
||||||
|
debug_msg = f"[{timestamp}] {message}"
|
||||||
|
self.debug_var.set(debug_msg)
|
||||||
|
print(debug_msg)
|
||||||
|
|
||||||
|
def calculate_crc(self, data):
|
||||||
|
"""计算CRC并返回对调后的两个字节"""
|
||||||
|
if not data:
|
||||||
|
return bytes.fromhex('0000')
|
||||||
|
|
||||||
|
# 计算CRC
|
||||||
|
crc_value = self.crc16_func(data)
|
||||||
|
|
||||||
|
# 转换为两个字节并对调
|
||||||
|
crc_bytes = crc_value.to_bytes(2, byteorder='big')
|
||||||
|
crc_swapped = bytes([crc_bytes[1], crc_bytes[0]])
|
||||||
|
|
||||||
|
return crc_swapped
|
||||||
|
|
||||||
|
def send_and_receive_command(self):
|
||||||
|
"""发送命令并接收响应"""
|
||||||
|
if not (self.serial_port and self.serial_port.is_open):
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 清空接收缓冲区
|
||||||
|
self.clear_serial_buffer()
|
||||||
|
|
||||||
|
# 发送查询命令
|
||||||
|
full_command = bytes.fromhex('5A04123400097991')
|
||||||
|
self.serial_port.write(full_command)
|
||||||
|
self.update_debug_info(f"发送命令: {full_command.hex().upper()}")
|
||||||
|
|
||||||
|
# 等待100ms让设备准备响应
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
# 读取响应数据
|
||||||
|
if self.serial_port.in_waiting:
|
||||||
|
data = self.serial_port.read(self.serial_port.in_waiting)
|
||||||
|
if data:
|
||||||
|
self.update_debug_info(f"收到 {len(data)} 字节响应数据")
|
||||||
|
self.process_received_data(data)
|
||||||
|
else:
|
||||||
|
self.update_debug_info("未收到响应数据")
|
||||||
|
self.root.after(0, lambda: self.comm_status.config(fg="red"))
|
||||||
|
else:
|
||||||
|
self.update_debug_info("无响应数据可读")
|
||||||
|
self.root.after(0, lambda: self.comm_status.config(fg="red"))
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.update_debug_info(f"发送接收命令错误: {e}")
|
||||||
|
self.root.after(0, lambda: self.comm_status.config(fg="red"))
|
||||||
|
|
||||||
|
def serial_read_loop(self):
|
||||||
|
"""串口读取循环"""
|
||||||
|
last_send_time = 0
|
||||||
|
send_interval = 0.2 # 200ms发送一次
|
||||||
|
|
||||||
|
while self.is_connected and not self.stop_thread:
|
||||||
|
current_time = time.time()
|
||||||
|
|
||||||
|
# 发送并接收命令
|
||||||
|
if current_time - last_send_time >= send_interval:
|
||||||
|
self.send_and_receive_command()
|
||||||
|
last_send_time = current_time
|
||||||
|
|
||||||
|
time.sleep(0.01)
|
||||||
|
|
||||||
|
def process_received_data(self, data):
|
||||||
|
"""处理接收到的数据"""
|
||||||
|
hex_data = data.hex().upper()
|
||||||
|
self.update_debug_info(f"原始响应数据: {hex_data}")
|
||||||
|
|
||||||
|
# 检查数据长度
|
||||||
|
if len(data) < 23:
|
||||||
|
self.update_debug_info(f"数据长度不足: {len(data)}字节,期望至少23字节")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 查找帧头
|
||||||
|
frame_start = -1
|
||||||
|
for i in range(len(data) - 2):
|
||||||
|
if data[i] == 0x5A and data[i+1] == 0x04 and data[i+2] == 0x12:
|
||||||
|
frame_start = i
|
||||||
|
break
|
||||||
|
|
||||||
|
if frame_start == -1:
|
||||||
|
self.update_debug_info("未找到帧头 5A0412")
|
||||||
|
return
|
||||||
|
|
||||||
|
self.update_debug_info(f"找到帧头,位置: {frame_start}")
|
||||||
|
|
||||||
|
# 提取完整帧(从帧头开始的23字节)
|
||||||
|
if len(data) - frame_start >= 23:
|
||||||
|
frame_data = data[frame_start:frame_start+23]
|
||||||
|
self.process_received_frame(frame_data)
|
||||||
|
else:
|
||||||
|
self.update_debug_info("帧数据不完整")
|
||||||
|
|
||||||
|
def process_received_frame(self, data):
|
||||||
|
"""处理接收到的完整数据帧(23字节)"""
|
||||||
|
hex_data = data.hex().upper()
|
||||||
|
self.update_debug_info(f"处理数据帧: {hex_data}")
|
||||||
|
|
||||||
|
# CRC校验 - 前21字节计算CRC,最后2字节是CRC
|
||||||
|
if not self.check_crc(data):
|
||||||
|
self.update_debug_info("CRC校验失败")
|
||||||
|
self.root.after(0, lambda: self.comm_status.config(fg="red"))
|
||||||
|
return
|
||||||
|
|
||||||
|
# 解析数据
|
||||||
|
try:
|
||||||
|
# 解析峰峰值 (4个通道,每个2字节)
|
||||||
|
peak_values = []
|
||||||
|
for i in range(4):
|
||||||
|
start_idx = 3 + i * 2 # 跳过帧头5A0412 (3字节)
|
||||||
|
peak_value = (data[start_idx] << 8) | data[start_idx + 1]
|
||||||
|
peak_values.append(peak_value)
|
||||||
|
|
||||||
|
# 解析频率 (4个通道,每个2字节,需要除以10)
|
||||||
|
freq_values = []
|
||||||
|
for i in range(4):
|
||||||
|
start_idx = 11 + i * 2 # 峰峰值后是频率
|
||||||
|
freq_value = (data[start_idx] << 8) | data[start_idx + 1]
|
||||||
|
freq_values.append(freq_value / 10.0)
|
||||||
|
|
||||||
|
# 解析状态
|
||||||
|
key_status = data[19] # 按键状态
|
||||||
|
sd_status = data[20] # SD卡状态
|
||||||
|
|
||||||
|
self.update_debug_info(f"解析成功: 峰峰值{peak_values}, 频率{freq_values}, 按键{key_status}, SD卡{sd_status}")
|
||||||
|
|
||||||
|
# 更新界面
|
||||||
|
self.root.after(0, self.update_display, peak_values, freq_values, key_status, sd_status)
|
||||||
|
|
||||||
|
# 通讯成功,更新状态
|
||||||
|
self.root.after(0, lambda: self.comm_status.config(fg="green"))
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.update_debug_info(f"解析数据错误: {e}")
|
||||||
|
self.root.after(0, lambda: self.comm_status.config(fg="red"))
|
||||||
|
|
||||||
|
def check_crc(self, data):
|
||||||
|
"""CRC校验 - 前21字节计算CRC,最后2字节是CRC(需要对调)"""
|
||||||
|
try:
|
||||||
|
if len(data) < 23:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 分离数据(前21字节)和CRC(最后2字节)
|
||||||
|
data_part = data[:21] # 前21字节是数据
|
||||||
|
crc_received = data[21:23] # 最后2字节是CRC
|
||||||
|
|
||||||
|
# 计算期望的CRC值(对调后的)
|
||||||
|
expected_crc = self.calculate_crc(data_part)
|
||||||
|
|
||||||
|
# 比较CRC
|
||||||
|
result = crc_received == expected_crc
|
||||||
|
if not result:
|
||||||
|
self.update_debug_info(f"CRC不匹配: 收到{crc_received.hex().upper()}, 期望{expected_crc.hex().upper()}")
|
||||||
|
return result
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.update_debug_info(f"CRC校验错误: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def update_display(self, peak_values, freq_values, key_status, sd_status):
|
||||||
|
"""更新显示"""
|
||||||
|
# 更新峰峰值
|
||||||
|
for i in range(4):
|
||||||
|
value = peak_values[i]
|
||||||
|
self.peak_values[i] = value
|
||||||
|
widget = self.peak_widgets[i]
|
||||||
|
widget["value_label"].config(text=str(value))
|
||||||
|
|
||||||
|
# 检查范围并设置颜色
|
||||||
|
in_range = self.peak_limits[i]["min"] <= value <= self.peak_limits[i]["max"]
|
||||||
|
color = "green" if in_range else "red"
|
||||||
|
widget["value_label"].config(bg=color)
|
||||||
|
|
||||||
|
# 如果越界,设置上下限输入框颜色
|
||||||
|
min_color = "red" if value < self.peak_limits[i]["min"] else "white"
|
||||||
|
max_color = "red" if value > self.peak_limits[i]["max"] else "white"
|
||||||
|
widget["min_entry"].config(bg=min_color)
|
||||||
|
widget["max_entry"].config(bg=max_color)
|
||||||
|
|
||||||
|
# 更新频率
|
||||||
|
for i in range(4):
|
||||||
|
value = freq_values[i]
|
||||||
|
self.frequency_values[i] = value
|
||||||
|
widget = self.freq_widgets[i]
|
||||||
|
widget["value_label"].config(text=f"{value:.1f}")
|
||||||
|
|
||||||
|
# 检查范围并设置颜色
|
||||||
|
in_range = self.freq_limits[i]["min"] <= value <= self.freq_limits[i]["max"]
|
||||||
|
color = "green" if in_range else "red"
|
||||||
|
widget["value_label"].config(bg=color)
|
||||||
|
|
||||||
|
# 如果越界,设置上下限输入框颜色
|
||||||
|
min_color = "red" if value < self.freq_limits[i]["min"] else "white"
|
||||||
|
max_color = "red" if value > self.freq_limits[i]["max"] else "white"
|
||||||
|
widget["min_entry"].config(bg=min_color)
|
||||||
|
widget["max_entry"].config(bg=max_color)
|
||||||
|
|
||||||
|
# 更新状态
|
||||||
|
self.key_status = key_status
|
||||||
|
self.sd_status = sd_status
|
||||||
|
|
||||||
|
# 按键状态:0=未按下,1=按下
|
||||||
|
key_color = "green" if key_status == 1 else "red"
|
||||||
|
self.key_status_label.config(fg=key_color)
|
||||||
|
|
||||||
|
# SD卡状态:5=成功,其他=失败
|
||||||
|
sd_color = "green" if sd_status == 5 else "red"
|
||||||
|
self.sd_status_label.config(fg=sd_color)
|
||||||
|
|
||||||
|
self.update_debug_info("界面更新完成")
|
||||||
|
|
||||||
|
def update_freq_limit(self, channel):
|
||||||
|
"""更新频率上下限"""
|
||||||
|
try:
|
||||||
|
min_val = float(self.freq_widgets[channel]["min_var"].get())
|
||||||
|
max_val = float(self.freq_widgets[channel]["max_var"].get())
|
||||||
|
|
||||||
|
# 验证最小值不大于最大值
|
||||||
|
if min_val > max_val:
|
||||||
|
messagebox.showerror("错误", "最小值不能大于最大值")
|
||||||
|
return
|
||||||
|
|
||||||
|
self.freq_limits[channel]["min"] = min_val
|
||||||
|
self.freq_limits[channel]["max"] = max_val
|
||||||
|
|
||||||
|
# 立即检查当前值并更新显示
|
||||||
|
self.check_freq_value(channel)
|
||||||
|
|
||||||
|
except ValueError:
|
||||||
|
messagebox.showerror("错误", "请输入有效的数字")
|
||||||
|
|
||||||
|
def update_peak_limit(self, channel):
|
||||||
|
"""更新峰峰值上下限"""
|
||||||
|
try:
|
||||||
|
min_val = float(self.peak_widgets[channel]["min_var"].get())
|
||||||
|
max_val = float(self.peak_widgets[channel]["max_var"].get())
|
||||||
|
|
||||||
|
# 验证最小值不大于最大值
|
||||||
|
if min_val > max_val:
|
||||||
|
messagebox.showerror("错误", "最小值不能大于最大值")
|
||||||
|
return
|
||||||
|
|
||||||
|
self.peak_limits[channel]["min"] = min_val
|
||||||
|
self.peak_limits[channel]["max"] = max_val
|
||||||
|
|
||||||
|
# 立即检查当前值并更新显示
|
||||||
|
self.check_peak_value(channel)
|
||||||
|
|
||||||
|
except ValueError:
|
||||||
|
messagebox.showerror("错误", "请输入有效的数字")
|
||||||
|
|
||||||
|
def check_freq_value(self, channel):
|
||||||
|
"""检查指定通道的频率值是否在范围内"""
|
||||||
|
value = self.frequency_values[channel]
|
||||||
|
widget = self.freq_widgets[channel]
|
||||||
|
|
||||||
|
# 检查范围并设置颜色
|
||||||
|
in_range = self.freq_limits[channel]["min"] <= value <= self.freq_limits[channel]["max"]
|
||||||
|
color = "green" if in_range else "red"
|
||||||
|
widget["value_label"].config(bg=color)
|
||||||
|
|
||||||
|
# 如果越界,设置上下限输入框颜色
|
||||||
|
min_color = "red" if value < self.freq_limits[channel]["min"] else "white"
|
||||||
|
max_color = "red" if value > self.freq_limits[channel]["max"] else "white"
|
||||||
|
widget["min_entry"].config(bg=min_color)
|
||||||
|
widget["max_entry"].config(bg=max_color)
|
||||||
|
|
||||||
|
def check_peak_value(self, channel):
|
||||||
|
"""检查指定通道的峰峰值是否在范围内"""
|
||||||
|
value = self.peak_values[channel]
|
||||||
|
widget = self.peak_widgets[channel]
|
||||||
|
|
||||||
|
# 检查范围并设置颜色
|
||||||
|
in_range = self.peak_limits[channel]["min"] <= value <= self.peak_limits[channel]["max"]
|
||||||
|
color = "green" if in_range else "red"
|
||||||
|
widget["value_label"].config(bg=color)
|
||||||
|
|
||||||
|
# 如果越界,设置上下限输入框颜色
|
||||||
|
min_color = "red" if value < self.peak_limits[channel]["min"] else "white"
|
||||||
|
max_color = "red" if value > self.peak_limits[channel]["max"] else "white"
|
||||||
|
widget["min_entry"].config(bg=min_color)
|
||||||
|
widget["max_entry"].config(bg=max_color)
|
||||||
|
|
||||||
|
def check_current_values(self):
|
||||||
|
"""检查当前值是否在范围内"""
|
||||||
|
for i in range(4):
|
||||||
|
self.check_freq_value(i)
|
||||||
|
self.check_peak_value(i)
|
||||||
|
|
||||||
|
def on_closing(self):
|
||||||
|
"""程序关闭时的清理工作"""
|
||||||
|
self.stop_thread = True
|
||||||
|
if self.serial_port and self.serial_port.is_open:
|
||||||
|
self.serial_port.close()
|
||||||
|
self.root.destroy()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
root = tk.Tk()
|
||||||
|
app = ATEApplication(root)
|
||||||
|
root.mainloop()
|
||||||
22
ate/src/CMakeLists.txt
Executable file
22
ate/src/CMakeLists.txt
Executable file
@ -0,0 +1,22 @@
|
|||||||
|
include_directories(.)
|
||||||
|
include_directories(../../driver/sdcard)
|
||||||
|
include_directories(../../driver/stddriver/inc)
|
||||||
|
include_directories(../../driver/cmsis/inc)
|
||||||
|
include_directories(../../component/fatfs/inc)
|
||||||
|
|
||||||
|
file(GLOB FILELIST
|
||||||
|
device.c
|
||||||
|
led.c
|
||||||
|
button.c
|
||||||
|
heat.c
|
||||||
|
ltc1867.c
|
||||||
|
ltc2640.c
|
||||||
|
rs485.c
|
||||||
|
modbus.c
|
||||||
|
calc.c
|
||||||
|
sd.c
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(src STATIC ${FILELIST})
|
||||||
|
target_link_libraries(src driver)
|
||||||
|
target_link_libraries(src fatfs)
|
||||||
39
ate/src/button.c
Executable file
39
ate/src/button.c
Executable file
@ -0,0 +1,39 @@
|
|||||||
|
#include "stm32f4xx_rcc.h"
|
||||||
|
#include "stm32f4xx_gpio.h"
|
||||||
|
#include "button.h"
|
||||||
|
#include "device.h"
|
||||||
|
|
||||||
|
void button_init(void)
|
||||||
|
{
|
||||||
|
GPIO_InitTypeDef GPIO_InitStructure = {
|
||||||
|
.GPIO_Pin = PIN_BUTTON,
|
||||||
|
.GPIO_Mode = GPIO_Mode_IN,
|
||||||
|
.GPIO_OType = GPIO_OType_PP,
|
||||||
|
.GPIO_Speed = GPIO_Speed_2MHz,
|
||||||
|
.GPIO_PuPd = GPIO_PuPd_UP,
|
||||||
|
};
|
||||||
|
|
||||||
|
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
|
||||||
|
GPIO_Init(PORT_BUTTON, &GPIO_InitStructure);
|
||||||
|
}
|
||||||
|
|
||||||
|
int button_is_pressed(void)
|
||||||
|
{
|
||||||
|
if (GPIO_ReadInputDataBit(PORT_BUTTON, PIN_BUTTON)) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void button_loop(void)
|
||||||
|
{
|
||||||
|
static uint32_t ms = 0;
|
||||||
|
|
||||||
|
if (system_tick_cnt < (ms + 100)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ms = system_tick_cnt;
|
||||||
|
|
||||||
|
device_data.button = button_is_pressed() ? 1 : 0;
|
||||||
|
}
|
||||||
23
ate/src/button.h
Executable file
23
ate/src/button.h
Executable file
@ -0,0 +1,23 @@
|
|||||||
|
#ifndef __BUTTON_H__
|
||||||
|
#define __BUTTON_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
|
||||||
|
#define PORT_BUTTON (GPIOB)
|
||||||
|
#define PIN_BUTTON (GPIO_Pin_14)
|
||||||
|
|
||||||
|
extern uint32_t system_tick_cnt;
|
||||||
|
|
||||||
|
void button_init(void);
|
||||||
|
int button_is_pressed(void);
|
||||||
|
void button_loop(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __BUTTON_H__ */
|
||||||
54
ate/src/calc.c
Executable file
54
ate/src/calc.c
Executable file
@ -0,0 +1,54 @@
|
|||||||
|
#include "calc.h"
|
||||||
|
#include "device.h"
|
||||||
|
#include "ltc1867.h"
|
||||||
|
|
||||||
|
uint16_t calc_freq(uint32_t pre, uint32_t now)
|
||||||
|
{
|
||||||
|
uint32_t freq;
|
||||||
|
|
||||||
|
if (now > pre) {
|
||||||
|
freq = now - pre;
|
||||||
|
} else {
|
||||||
|
freq = pre - now;
|
||||||
|
}
|
||||||
|
freq = (LEDIR_FREQ * SAMPLES_PER_PERIOD * 10 + freq / 2) / freq;
|
||||||
|
|
||||||
|
return (uint16_t)freq;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t calc_peak(int ch, uint32_t pre, uint32_t now)
|
||||||
|
{
|
||||||
|
uint16_t min, max, val;
|
||||||
|
|
||||||
|
min = 65535;
|
||||||
|
max = 0;
|
||||||
|
for (uint32_t i = data_ltc1867.sample_pre[ch]; i < data_ltc1867.sample_now[ch]; i++) {
|
||||||
|
val = data_ltc1867_raw[ch][i % LTC1867_RAW_BUFF_SIZE];
|
||||||
|
if (min > val) {
|
||||||
|
min = val;
|
||||||
|
}
|
||||||
|
if (max < val) {
|
||||||
|
max = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (max - min + 8) / 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
void calc_loop(void)
|
||||||
|
{
|
||||||
|
static uint32_t sample_cnt = 0;
|
||||||
|
static uint32_t pre[LTC1867_CH_CNT] = {0, 0, 0, 0};
|
||||||
|
|
||||||
|
if (sample_cnt == data_ltc1867.sample_cnt) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sample_cnt = data_ltc1867.sample_cnt;
|
||||||
|
|
||||||
|
for (int i = 0; i < LTC1867_CH_CNT; i++) {
|
||||||
|
if (pre[i] != data_ltc1867.sample_pre[i]) {
|
||||||
|
pre[i] = data_ltc1867.sample_pre[i];
|
||||||
|
device_data.freq[i] = calc_freq(data_ltc1867.sample_pre[i], data_ltc1867.sample_now[i]);
|
||||||
|
device_data.peak[i] = calc_peak(i, data_ltc1867.sample_pre[i], data_ltc1867.sample_now[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
ate/src/calc.h
Executable file
17
ate/src/calc.h
Executable file
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef __CALC_H__
|
||||||
|
#define __CALC_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
|
||||||
|
uint16_t calc_freq(uint32_t pre, uint32_t now);
|
||||||
|
void calc_loop(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __CALC_H__ */
|
||||||
15
ate/src/config.h
Executable file
15
ate/src/config.h
Executable file
@ -0,0 +1,15 @@
|
|||||||
|
#ifndef __CONFIG_H__
|
||||||
|
#define __CONFIG_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LEDIR_FREQ (8)
|
||||||
|
#define SAMPLES_PER_PERIOD (64)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __CONFIG_H__ */
|
||||||
29
ate/src/device.c
Executable file
29
ate/src/device.c
Executable file
@ -0,0 +1,29 @@
|
|||||||
|
#include "device.h"
|
||||||
|
|
||||||
|
#define BITMAP_GAS_ADDR (0x080A0000)
|
||||||
|
#define BITMAP_MAIN_ADDR (BITMAP_GAS_ADDR + 20 * 1024 * 4)
|
||||||
|
|
||||||
|
#define OFFSET_DATA (0x0000 * 2)
|
||||||
|
|
||||||
|
struct device_data_s device_data __attribute__((section(".bss_ccm")));
|
||||||
|
|
||||||
|
const uint8_t * const modbus_map_ro[] = {
|
||||||
|
[OFFSET_DATA + 0] = (uint8_t *)&(device_data.peak[0]) + 1,
|
||||||
|
[OFFSET_DATA + 1] = (uint8_t *)&(device_data.peak[0]) + 0,
|
||||||
|
[OFFSET_DATA + 2] = (uint8_t *)&(device_data.peak[1]) + 1,
|
||||||
|
[OFFSET_DATA + 3] = (uint8_t *)&(device_data.peak[1]) + 0,
|
||||||
|
[OFFSET_DATA + 4] = (uint8_t *)&(device_data.peak[2]) + 1,
|
||||||
|
[OFFSET_DATA + 5] = (uint8_t *)&(device_data.peak[2]) + 0,
|
||||||
|
[OFFSET_DATA + 6] = (uint8_t *)&(device_data.peak[3]) + 1,
|
||||||
|
[OFFSET_DATA + 7] = (uint8_t *)&(device_data.peak[3]) + 0,
|
||||||
|
[OFFSET_DATA + 8] = (uint8_t *)&(device_data.freq[0]) + 1,
|
||||||
|
[OFFSET_DATA + 9] = (uint8_t *)&(device_data.freq[0]) + 0,
|
||||||
|
[OFFSET_DATA + 10] = (uint8_t *)&(device_data.freq[1]) + 1,
|
||||||
|
[OFFSET_DATA + 11] = (uint8_t *)&(device_data.freq[1]) + 0,
|
||||||
|
[OFFSET_DATA + 12] = (uint8_t *)&(device_data.freq[2]) + 1,
|
||||||
|
[OFFSET_DATA + 13] = (uint8_t *)&(device_data.freq[2]) + 0,
|
||||||
|
[OFFSET_DATA + 14] = (uint8_t *)&(device_data.freq[3]) + 1,
|
||||||
|
[OFFSET_DATA + 15] = (uint8_t *)&(device_data.freq[3]) + 0,
|
||||||
|
[OFFSET_DATA + 16] = (uint8_t *)&(device_data.button) + 0,
|
||||||
|
[OFFSET_DATA + 17] = (uint8_t *)&(device_data.sd) + 0,
|
||||||
|
};
|
||||||
25
ate/src/device.h
Executable file
25
ate/src/device.h
Executable file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef __DEVICE_H__
|
||||||
|
#define __DEVICE_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
|
||||||
|
/******************* device data *******************/
|
||||||
|
struct device_data_s {
|
||||||
|
uint16_t peak[4];
|
||||||
|
uint16_t freq[4];
|
||||||
|
uint8_t button;
|
||||||
|
uint8_t sd;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const uint8_t * const modbus_map_ro[];
|
||||||
|
extern struct device_data_s device_data;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __DEVICE_H__ */
|
||||||
45
ate/src/heat.c
Executable file
45
ate/src/heat.c
Executable file
@ -0,0 +1,45 @@
|
|||||||
|
#include "heat.h"
|
||||||
|
#include "stm32f4xx_rcc.h"
|
||||||
|
#include "stm32f4xx_gpio.h"
|
||||||
|
|
||||||
|
void heat_init(void)
|
||||||
|
{
|
||||||
|
GPIO_InitTypeDef GPIO_InitStructure = {
|
||||||
|
.GPIO_Pin = PIN_HEAT,
|
||||||
|
.GPIO_Mode = GPIO_Mode_OUT,
|
||||||
|
.GPIO_OType = GPIO_OType_PP,
|
||||||
|
.GPIO_Speed = GPIO_Speed_2MHz,
|
||||||
|
.GPIO_PuPd = GPIO_PuPd_NOPULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
|
||||||
|
GPIO_Init(PORT_HEAT, &GPIO_InitStructure);
|
||||||
|
heat_off();
|
||||||
|
}
|
||||||
|
|
||||||
|
void heat_on(void)
|
||||||
|
{
|
||||||
|
GPIO_SetBits(PORT_HEAT, PIN_HEAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void heat_off(void)
|
||||||
|
{
|
||||||
|
GPIO_ResetBits(PORT_HEAT, PIN_HEAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void heat_toggle(void)
|
||||||
|
{
|
||||||
|
GPIO_ToggleBits(PORT_HEAT, PIN_HEAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void heat_loop(void)
|
||||||
|
{
|
||||||
|
static uint32_t ms = 0;
|
||||||
|
|
||||||
|
if (system_tick_cnt < (ms + 62)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ms = system_tick_cnt;
|
||||||
|
|
||||||
|
heat_toggle();
|
||||||
|
}
|
||||||
25
ate/src/heat.h
Executable file
25
ate/src/heat.h
Executable file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef __HEAT_H__
|
||||||
|
#define __HEAT_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
|
||||||
|
#define PORT_HEAT (GPIOB)
|
||||||
|
#define PIN_HEAT (GPIO_Pin_1)
|
||||||
|
|
||||||
|
extern uint32_t system_tick_cnt;
|
||||||
|
|
||||||
|
void heat_init(void);
|
||||||
|
void heat_on(void);
|
||||||
|
void heat_off(void);
|
||||||
|
void heat_toggle(void);
|
||||||
|
void heat_loop(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __HEAT_H__ */
|
||||||
48
ate/src/led.c
Executable file
48
ate/src/led.c
Executable file
@ -0,0 +1,48 @@
|
|||||||
|
#include "led.h"
|
||||||
|
#include "stm32f4xx_rcc.h"
|
||||||
|
#include "stm32f4xx_gpio.h"
|
||||||
|
|
||||||
|
void led_init(uint16_t led)
|
||||||
|
{
|
||||||
|
GPIO_InitTypeDef GPIO_InitStructure = {
|
||||||
|
.GPIO_Pin = led,
|
||||||
|
.GPIO_Mode = GPIO_Mode_OUT,
|
||||||
|
.GPIO_OType = GPIO_OType_PP,
|
||||||
|
.GPIO_Speed = GPIO_Speed_2MHz,
|
||||||
|
.GPIO_PuPd = GPIO_PuPd_NOPULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
|
||||||
|
GPIO_Init(PORT_LED, &GPIO_InitStructure);
|
||||||
|
led_off(led);
|
||||||
|
}
|
||||||
|
|
||||||
|
void led_off(uint16_t led)
|
||||||
|
{
|
||||||
|
GPIO_SetBits(PORT_LED, led);
|
||||||
|
}
|
||||||
|
|
||||||
|
void led_on(uint16_t led)
|
||||||
|
{
|
||||||
|
GPIO_ResetBits(PORT_LED, led);
|
||||||
|
}
|
||||||
|
|
||||||
|
void led_loop(void)
|
||||||
|
{
|
||||||
|
static uint32_t ms = 0;
|
||||||
|
static uint32_t led_cnt = 0;
|
||||||
|
|
||||||
|
if (system_tick_cnt < (ms + 200)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ms = system_tick_cnt;
|
||||||
|
|
||||||
|
led_cnt = led_cnt & 3;
|
||||||
|
switch (led_cnt) {
|
||||||
|
case 0: led_off(LED1 | LED2); break;
|
||||||
|
case 1: led_off(LED1); led_on(LED2);break;
|
||||||
|
case 2: led_on(LED1); led_off(LED2); break;
|
||||||
|
case 3: led_on(LED1 | LED2); break;
|
||||||
|
}
|
||||||
|
led_cnt++;
|
||||||
|
}
|
||||||
25
ate/src/led.h
Executable file
25
ate/src/led.h
Executable file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef __LED_H__
|
||||||
|
#define __LED_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
|
||||||
|
#define PORT_LED (GPIOC)
|
||||||
|
#define LED1 (GPIO_Pin_4)
|
||||||
|
#define LED2 (GPIO_Pin_5)
|
||||||
|
|
||||||
|
extern uint32_t system_tick_cnt;
|
||||||
|
|
||||||
|
void led_init(uint16_t led);
|
||||||
|
void led_off(uint16_t led);
|
||||||
|
void led_on(uint16_t led);
|
||||||
|
void led_loop(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __LED_H__ */
|
||||||
195
ate/src/ltc1867.c
Executable file
195
ate/src/ltc1867.c
Executable file
@ -0,0 +1,195 @@
|
|||||||
|
#include "ltc1867.h"
|
||||||
|
#include "stm32f4xx_rcc.h"
|
||||||
|
#include "stm32f4xx_gpio.h"
|
||||||
|
#include "stm32f4xx_tim.h"
|
||||||
|
#include "stm32f4xx_spi.h"
|
||||||
|
|
||||||
|
uint16_t data_ltc1867_raw[LTC1867_CH_CNT][LTC1867_RAW_BUFF_SIZE] __attribute__((section(".bss_ccm")));
|
||||||
|
struct data_ltc1867_s data_ltc1867 __attribute__((section(".bss_ccm")));
|
||||||
|
__attribute__((section(".data_ccm"))) uint16_t ltc1867_spi_data[LTC1867_CH_CNT] = {0xC400, 0x9400, 0xD400, 0x8400}; /* order: ch1, ch2, ch3, ch0 */
|
||||||
|
|
||||||
|
void ltc1867_init(void)
|
||||||
|
{
|
||||||
|
GPIO_InitTypeDef GPIO_InitStructure;
|
||||||
|
NVIC_InitTypeDef NVIC_InitStructure;
|
||||||
|
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||||||
|
SPI_InitTypeDef SPI_InitStructure;
|
||||||
|
|
||||||
|
/* TIM2 32bit for sample */
|
||||||
|
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
|
||||||
|
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
|
||||||
|
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
|
||||||
|
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
||||||
|
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||||
|
NVIC_Init(&NVIC_InitStructure);
|
||||||
|
// NVIC_SetPriority(PendSV_IRQn, 1); /* priority is just lower than sample, for write cali data to flash */
|
||||||
|
/* Time base configuration */
|
||||||
|
TIM_TimeBaseStructure.TIM_Period = TIMER_PERIOD_SAMPLE;
|
||||||
|
TIM_TimeBaseStructure.TIM_Prescaler = 0;
|
||||||
|
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
|
||||||
|
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||||||
|
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
|
||||||
|
/* Prescaler configuration */
|
||||||
|
TIM_PrescalerConfig(TIM2, 0, TIM_PSCReloadMode_Immediate);
|
||||||
|
/* TIM2 Interrupts enable */
|
||||||
|
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
|
||||||
|
/* TIM2 enable counter */
|
||||||
|
TIM_Cmd(TIM2, ENABLE);
|
||||||
|
|
||||||
|
/* TIM3 16bit for ADC conversion */
|
||||||
|
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
|
||||||
|
/* Time base configuration */
|
||||||
|
TIM_TimeBaseStructure.TIM_Period = TIMER_PERIOD_DELAY;
|
||||||
|
TIM_TimeBaseStructure.TIM_Prescaler = 0;
|
||||||
|
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
|
||||||
|
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||||||
|
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
|
||||||
|
/* Prescaler configuration */
|
||||||
|
TIM_PrescalerConfig(TIM3, 0, TIM_PSCReloadMode_Immediate);
|
||||||
|
/* TIM3 disable counter, start when ltc1867 need delay */
|
||||||
|
TIM_Cmd(TIM3, DISABLE);
|
||||||
|
|
||||||
|
/* LEDIR pin configure */
|
||||||
|
GPIO_InitStructure.GPIO_Pin = PIN_LEDIR;
|
||||||
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||||
|
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||||
|
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
|
||||||
|
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||||
|
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
|
||||||
|
GPIO_Init(PORT_LEDIR, &GPIO_InitStructure);
|
||||||
|
ltc1867_ledir_off();
|
||||||
|
|
||||||
|
/* LTC1867 conv pin configure */
|
||||||
|
GPIO_InitStructure.GPIO_Pin = PIN_CONV;
|
||||||
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||||
|
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||||
|
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
|
||||||
|
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||||
|
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
|
||||||
|
GPIO_Init(PORT_LTC1867, &GPIO_InitStructure);
|
||||||
|
/* config SPI for LTC1867 communication */
|
||||||
|
GPIO_PinAFConfig(PORT_SPI, GPIO_PinSource5, GPIO_AF_SPI1);
|
||||||
|
GPIO_PinAFConfig(PORT_SPI, GPIO_PinSource6, GPIO_AF_SPI1);
|
||||||
|
GPIO_PinAFConfig(PORT_SPI, GPIO_PinSource7, GPIO_AF_SPI1);
|
||||||
|
GPIO_InitStructure.GPIO_Pin = PIN_SPI_SCK | PIN_SPI_SDI | PIN_SPI_SDO;
|
||||||
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||||
|
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||||
|
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||||
|
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
|
||||||
|
GPIO_Init(PORT_SPI, &GPIO_InitStructure);
|
||||||
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
|
||||||
|
SPI_I2S_DeInit(SPI1);
|
||||||
|
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
|
||||||
|
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
|
||||||
|
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
|
||||||
|
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
|
||||||
|
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
|
||||||
|
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
|
||||||
|
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
|
||||||
|
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
|
||||||
|
SPI_InitStructure.SPI_CRCPolynomial = 7;
|
||||||
|
SPI_Init(SPI1, &SPI_InitStructure);
|
||||||
|
SPI_Cmd(SPI1, ENABLE);
|
||||||
|
ltc1867_spi_select();
|
||||||
|
ltc1867_transfer(ltc1867_spi_data[LTC1867_CH_CNT - 1]);
|
||||||
|
|
||||||
|
data_ltc1867.ledir_cnt = 0; /* index of led count, for togglr IR led */
|
||||||
|
data_ltc1867.sample_cnt = 0; /* index for search point of 32768 */
|
||||||
|
for (uint8_t i = 0; i < LTC1867_CH_CNT; i++) {
|
||||||
|
data_ltc1867.sample_pre[i] = 0;
|
||||||
|
data_ltc1867.sample_now[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ltc1867_ledir_on(void)
|
||||||
|
{
|
||||||
|
GPIO_SetBits(PORT_LEDIR, PIN_LEDIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ltc1867_ledir_off(void)
|
||||||
|
{
|
||||||
|
GPIO_ResetBits(PORT_LEDIR, PIN_LEDIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ltc1867_ledir_toggle(void)
|
||||||
|
{
|
||||||
|
GPIO_ToggleBits(PORT_LEDIR, PIN_LEDIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ltc1867_delay(void)
|
||||||
|
{
|
||||||
|
FlagStatus sts;
|
||||||
|
|
||||||
|
TIM_SetCounter(TIM3, 0);
|
||||||
|
TIM_ClearFlag(TIM3, TIM_FLAG_Update);
|
||||||
|
TIM_Cmd(TIM3, ENABLE);
|
||||||
|
while (1) {
|
||||||
|
sts = TIM_GetFlagStatus(TIM3, TIM_FLAG_Update);
|
||||||
|
if (sts != RESET) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TIM_Cmd(TIM3, DISABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ltc1867_conv(void)
|
||||||
|
{
|
||||||
|
GPIO_SetBits(PORT_LTC1867, PIN_CONV);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ltc1867_spi_select(void)
|
||||||
|
{
|
||||||
|
GPIO_ResetBits(PORT_LTC1867, PIN_SPI_CS);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t ltc1867_transfer(uint16_t data_send)
|
||||||
|
{
|
||||||
|
FlagStatus flag;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
flag = SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE);
|
||||||
|
if (flag != RESET) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SPI_I2S_SendData(SPI1, data_send);
|
||||||
|
while (1) {
|
||||||
|
flag = SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE);
|
||||||
|
if (flag != RESET) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SPI_I2S_ReceiveData(SPI1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TIM2_IRQHandler(void)
|
||||||
|
{
|
||||||
|
static uint16_t pre_val[LTC1867_CH_CNT];
|
||||||
|
static uint16_t val[LTC1867_CH_CNT] = {65535, 65535, 65535, 65535};
|
||||||
|
|
||||||
|
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
|
||||||
|
|
||||||
|
/* for control led IR */
|
||||||
|
data_ltc1867.ledir_cnt++;
|
||||||
|
if (data_ltc1867.ledir_cnt == (SAMPLES_PER_PERIOD / 2)) {
|
||||||
|
ltc1867_ledir_on();
|
||||||
|
} else if (data_ltc1867.ledir_cnt >= SAMPLES_PER_PERIOD) {
|
||||||
|
ltc1867_ledir_off();
|
||||||
|
data_ltc1867.ledir_cnt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sample 4 channel adc data */
|
||||||
|
for (uint8_t i = 0; i < LTC1867_CH_CNT; i++) {
|
||||||
|
ltc1867_conv(); /* this point start convert */
|
||||||
|
ltc1867_delay(); /* delay 3.5us for convert time, reference for LTC1867 datasheet */
|
||||||
|
ltc1867_spi_select(); /* convert complete, make convert pin low for reading sample data by SPI */
|
||||||
|
pre_val[i] = val[i];
|
||||||
|
val[i] = ltc1867_transfer(ltc1867_spi_data[i]); /* read convert data and send next channel information */
|
||||||
|
data_ltc1867_raw[i][data_ltc1867.sample_cnt % LTC1867_RAW_BUFF_SIZE] = val[i];
|
||||||
|
if (pre_val[i] < 32768 && val[i] >= 32768) {
|
||||||
|
data_ltc1867.sample_pre[i] = data_ltc1867.sample_now[i];
|
||||||
|
data_ltc1867.sample_now[i] = data_ltc1867.sample_cnt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data_ltc1867.sample_cnt++;
|
||||||
|
}
|
||||||
52
ate/src/ltc1867.h
Executable file
52
ate/src/ltc1867.h
Executable file
@ -0,0 +1,52 @@
|
|||||||
|
#ifndef __LTC1867_H__
|
||||||
|
#define __LTC1867_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#define TIMER_SRC_FREQ (84 * 1000 * 1000)
|
||||||
|
#define TIMER_PERIOD_SAMPLE (TIMER_SRC_FREQ / LEDIR_FREQ / SAMPLES_PER_PERIOD - 1)
|
||||||
|
#define TIMER_PERIOD_DELAY (TIMER_SRC_FREQ / 1000 / 1000 * 35 / 10 - 1) /* 3.5us */
|
||||||
|
|
||||||
|
#define LTC1867_CH_CNT (4)
|
||||||
|
|
||||||
|
#define LTC1867_RAW_BUFF_SIZE (SAMPLES_PER_PERIOD * LEDIR_FREQ)
|
||||||
|
|
||||||
|
#define PORT_LEDIR (GPIOB)
|
||||||
|
#define PIN_LEDIR (GPIO_Pin_0)
|
||||||
|
#define PORT_LTC1867 (GPIOA)
|
||||||
|
#define PIN_CONV (GPIO_Pin_4)
|
||||||
|
#define PORT_SPI (GPIOA)
|
||||||
|
#define PIN_SPI_CS (GPIO_Pin_4)
|
||||||
|
#define PIN_SPI_SCK (GPIO_Pin_5)
|
||||||
|
#define PIN_SPI_SDO (GPIO_Pin_6)
|
||||||
|
#define PIN_SPI_SDI (GPIO_Pin_7)
|
||||||
|
|
||||||
|
struct data_ltc1867_s {
|
||||||
|
uint16_t ledir_cnt; /* index of led count, for togglr IR led */
|
||||||
|
uint32_t sample_cnt; /* index of sample */
|
||||||
|
uint32_t sample_pre[4]; /* index of pre sample rasing edge */
|
||||||
|
uint32_t sample_now[4]; /* index of now sample rasing edge */
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct data_ltc1867_s data_ltc1867;
|
||||||
|
extern uint16_t data_ltc1867_raw[LTC1867_CH_CNT][LTC1867_RAW_BUFF_SIZE];
|
||||||
|
|
||||||
|
void ltc1867_init(void);
|
||||||
|
void ltc1867_ledir_on(void);
|
||||||
|
void ltc1867_ledir_off(void);
|
||||||
|
void ltc1867_ledir_toggle(void);
|
||||||
|
void ltc1867_delay(void);
|
||||||
|
void ltc1867_conv(void);
|
||||||
|
void ltc1867_spi_select(void);
|
||||||
|
uint16_t ltc1867_transfer(uint16_t data_send);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __LTC1867_H__ */
|
||||||
110
ate/src/ltc2640.c
Executable file
110
ate/src/ltc2640.c
Executable file
@ -0,0 +1,110 @@
|
|||||||
|
#include "ltc2640.h"
|
||||||
|
#include "stm32f4xx_rcc.h"
|
||||||
|
#include "stm32f4xx_gpio.h"
|
||||||
|
#include "stm32f4xx_spi.h"
|
||||||
|
#include "stm32f4xx_dma.h"
|
||||||
|
#include "device.h"
|
||||||
|
|
||||||
|
uint8_t data_ltc2640_output[LTC2640_OUTPUT_LEN];
|
||||||
|
uint16_t data_ltc2640[] = {
|
||||||
|
VOLTAGE_200MV,
|
||||||
|
VOLTAGE_300MV,
|
||||||
|
VOLTAGE_400MV,
|
||||||
|
VOLTAGE_1000MV,
|
||||||
|
VOLTAGE_1200MV,
|
||||||
|
VOLTAGE_1500MV,
|
||||||
|
VOLTAGE_1800MV,
|
||||||
|
VOLTAGE_2000MV,
|
||||||
|
VOLTAGE_2400MV,
|
||||||
|
VOLTAGE_2500MV,
|
||||||
|
};
|
||||||
|
|
||||||
|
void ltc2640_init(void)
|
||||||
|
{
|
||||||
|
GPIO_InitTypeDef GPIO_InitStructure;
|
||||||
|
SPI_InitTypeDef SPI_InitStructure;
|
||||||
|
DMA_InitTypeDef DMA_InitStructure;
|
||||||
|
|
||||||
|
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
|
||||||
|
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
|
||||||
|
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
|
||||||
|
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);
|
||||||
|
|
||||||
|
/* config ltc2640 pin */
|
||||||
|
GPIO_InitStructure.GPIO_Pin = LTC2640_PIN_CS;
|
||||||
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||||
|
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||||
|
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||||
|
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||||
|
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||||
|
GPIO_InitStructure.GPIO_Pin = LTC2640_PIN_SCK | LTC2640_PIN_SDI;
|
||||||
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||||
|
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||||
|
GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_SPI3);
|
||||||
|
GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_SPI3);
|
||||||
|
/* config ltc2640 clr pin */
|
||||||
|
GPIO_InitStructure.GPIO_Pin = LTC2640_PIN_CLR;
|
||||||
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||||
|
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||||
|
GPIO_SetBits(GPIOB, LTC2640_PIN_CLR);
|
||||||
|
|
||||||
|
/* config SPI function */
|
||||||
|
SPI_I2S_DeInit(SPI3);
|
||||||
|
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
|
||||||
|
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
|
||||||
|
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
|
||||||
|
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
|
||||||
|
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
|
||||||
|
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
|
||||||
|
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
|
||||||
|
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
|
||||||
|
SPI_InitStructure.SPI_CRCPolynomial = 7;
|
||||||
|
SPI_Init(SPI3, &SPI_InitStructure);
|
||||||
|
SPI_Cmd(SPI3, ENABLE);
|
||||||
|
SPI_I2S_DMACmd(SPI3, SPI_I2S_DMAReq_Tx, ENABLE);
|
||||||
|
|
||||||
|
/* Configure DMA controller to manage SPI request */
|
||||||
|
DMA_InitStructure.DMA_BufferSize = LTC2640_OUTPUT_LEN;
|
||||||
|
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
|
||||||
|
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
|
||||||
|
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
|
||||||
|
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
|
||||||
|
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
|
||||||
|
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
|
||||||
|
DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t)(&(SPI3->DR));
|
||||||
|
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
|
||||||
|
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
|
||||||
|
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
|
||||||
|
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
|
||||||
|
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
|
||||||
|
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
|
||||||
|
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)data_ltc2640_output;
|
||||||
|
DMA_Init(DMA1_Stream5, &DMA_InitStructure);
|
||||||
|
ltc2640_send_data(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ltc2640_send_data(uint16_t data)
|
||||||
|
{
|
||||||
|
data_ltc2640_output[0] = 0x30;
|
||||||
|
data_ltc2640_output[1] = (uint8_t)((data >> 4) & 0xFF);
|
||||||
|
data_ltc2640_output[2] = (uint8_t)((data << 4) & 0xFF);
|
||||||
|
DMA_ClearFlag(DMA1_Stream5, DMA_FLAG_FEIF5 | DMA_FLAG_DMEIF5 | DMA_FLAG_TEIF5 | DMA_FLAG_HTIF5 | DMA_FLAG_TCIF5);
|
||||||
|
DMA_SetCurrDataCounter(DMA1_Stream5, LTC2640_OUTPUT_LEN);
|
||||||
|
DMA_Cmd(DMA1_Stream5, ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ltc2640_loop(void)
|
||||||
|
{
|
||||||
|
static uint32_t ms = 0;
|
||||||
|
static uint32_t cnt = 0;
|
||||||
|
|
||||||
|
if (system_tick_cnt < (ms + 100)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GPIO_SetBits(GPIOA, LTC2640_PIN_CS);
|
||||||
|
ms = system_tick_cnt;
|
||||||
|
cnt = cnt % (sizeof(data_ltc2640) / sizeof(data_ltc2640[0]));
|
||||||
|
GPIO_ResetBits(GPIOA, LTC2640_PIN_CS);
|
||||||
|
ltc2640_send_data(data_ltc2640[cnt]);
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
38
ate/src/ltc2640.h
Executable file
38
ate/src/ltc2640.h
Executable file
@ -0,0 +1,38 @@
|
|||||||
|
#ifndef __LTC2640_H__
|
||||||
|
#define __LTC2640_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
|
||||||
|
#define LTC2640_PIN_CLR (GPIO_Pin_7)
|
||||||
|
#define LTC2640_PIN_CS (GPIO_Pin_15)
|
||||||
|
#define LTC2640_PIN_SCK (GPIO_Pin_3)
|
||||||
|
#define LTC2640_PIN_SDI (GPIO_Pin_5)
|
||||||
|
|
||||||
|
#define LTC2640_OUTPUT_LEN (3)
|
||||||
|
|
||||||
|
#define VOLTAGE_200MV (328)
|
||||||
|
#define VOLTAGE_300MV (492)
|
||||||
|
#define VOLTAGE_400MV (655)
|
||||||
|
#define VOLTAGE_1000MV (1638)
|
||||||
|
#define VOLTAGE_1200MV (1966)
|
||||||
|
#define VOLTAGE_1500MV (2458)
|
||||||
|
#define VOLTAGE_1800MV (2949)
|
||||||
|
#define VOLTAGE_2000MV (3277)
|
||||||
|
#define VOLTAGE_2400MV (3932)
|
||||||
|
#define VOLTAGE_2500MV (4095)
|
||||||
|
|
||||||
|
extern uint32_t system_tick_cnt;
|
||||||
|
|
||||||
|
void ltc2640_init(void);
|
||||||
|
void ltc2640_send_data(uint16_t data);
|
||||||
|
void ltc2640_loop(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __LTC2640_H__ */
|
||||||
185
ate/src/modbus.c
Executable file
185
ate/src/modbus.c
Executable file
@ -0,0 +1,185 @@
|
|||||||
|
#include "device.h"
|
||||||
|
#include "rs485.h"
|
||||||
|
#include "modbus.h"
|
||||||
|
|
||||||
|
const uint8_t crc_tabl[] = { //CRC low Value Table
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||||||
|
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x00, 0xC1, 0x81, 0x40,
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t crc_tabh[] = { //CRC high Value Table
|
||||||
|
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
|
||||||
|
0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
|
||||||
|
0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
|
||||||
|
0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
|
||||||
|
0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
|
||||||
|
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
|
||||||
|
0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
|
||||||
|
0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
|
||||||
|
0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
|
||||||
|
0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
|
||||||
|
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
|
||||||
|
0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
|
||||||
|
0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
|
||||||
|
0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
|
||||||
|
0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
|
||||||
|
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
|
||||||
|
0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
|
||||||
|
0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
|
||||||
|
0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
|
||||||
|
0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
|
||||||
|
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
|
||||||
|
0x41, 0x81, 0x80, 0x40,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* polynomial: x16+x15+x2+x1 */
|
||||||
|
void crc16_8005_calc(uint8_t * p, uint16_t len, struct crc16_result_s *ret)
|
||||||
|
{
|
||||||
|
struct crc16_result_s crc = {0xFF, 0xFF};
|
||||||
|
uint8_t i, index;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
index = crc.crcl ^ p[i];
|
||||||
|
crc.crcl = crc.crch ^ crc_tabl[index];
|
||||||
|
crc.crch = crc_tabh[index];
|
||||||
|
}
|
||||||
|
ret->crcl = crc.crcl;
|
||||||
|
ret->crch = crc.crch;
|
||||||
|
}
|
||||||
|
|
||||||
|
void modbus_init(void)
|
||||||
|
{
|
||||||
|
rs485_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t modbus_data_big2little16(uint8_t *buff)
|
||||||
|
{
|
||||||
|
uint16_t val;
|
||||||
|
|
||||||
|
val = (uint16_t)(buff[0]);
|
||||||
|
val <<= 8;
|
||||||
|
val |= (uint16_t)(buff[1]);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t modbus_data_big2little32(uint8_t *buff)
|
||||||
|
{
|
||||||
|
uint32_t val;
|
||||||
|
|
||||||
|
val = (uint32_t)(buff[0]);
|
||||||
|
val <<= 8;
|
||||||
|
val |= (uint32_t)(buff[1]);
|
||||||
|
val <<= 8;
|
||||||
|
val |= (uint32_t)(buff[2]);
|
||||||
|
val <<= 8;
|
||||||
|
val |= (uint32_t)(buff[3]);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pr: point of rx buffer
|
||||||
|
pt: point of tx buffer
|
||||||
|
err_type: reference for MODBUS_ERROR_CODE_XXX
|
||||||
|
return: length of tx data need send */
|
||||||
|
uint16_t modbus_error_process(uint8_t *pr, uint8_t *pt, uint8_t err_type)
|
||||||
|
{
|
||||||
|
struct crc16_result_s crc;
|
||||||
|
|
||||||
|
pt[0] = pr[0];
|
||||||
|
pt[1] = pr[1] + 0x80;
|
||||||
|
pt[2] = err_type;
|
||||||
|
crc16_8005_calc(pt, 3, &crc);
|
||||||
|
pt[3] = crc.crcl;
|
||||||
|
pt[4] = crc.crch;
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pr: point of rx buffer
|
||||||
|
pt: point of tx buffer
|
||||||
|
len: length of rx data in buffer
|
||||||
|
return: length of tx data need send */
|
||||||
|
uint16_t modbus_func_read_input(uint8_t *pr, uint8_t *pt, uint16_t len)
|
||||||
|
{
|
||||||
|
uint16_t cnt, addr_s, i;
|
||||||
|
struct crc16_result_s crc;
|
||||||
|
|
||||||
|
/* modbus register count */
|
||||||
|
cnt = modbus_data_big2little16(pr + 4);
|
||||||
|
if (cnt != MODBUS_LENGTH_RO) {
|
||||||
|
/* modbus register count error */
|
||||||
|
return modbus_error_process(pr, pt, MODBUS_ERROR_CODE_VALUE);
|
||||||
|
}
|
||||||
|
addr_s = modbus_data_big2little16(pr + 2);
|
||||||
|
if (addr_s != MODBUS_ADDR_RO_S) {
|
||||||
|
/* modbus register address error */
|
||||||
|
return modbus_error_process(pr, pt, MODBUS_ERROR_CODE_ADDR);
|
||||||
|
}
|
||||||
|
pt[0] = pr[0];
|
||||||
|
pt[1] = pr[1];
|
||||||
|
pt[2] = (uint8_t)(cnt * 2);
|
||||||
|
for (i = 0; i < cnt * 2; i++) {
|
||||||
|
pt[3 + i] = *(modbus_map_ro[i]);
|
||||||
|
}
|
||||||
|
i += 3;
|
||||||
|
crc16_8005_calc(pt, i, &crc);
|
||||||
|
pt[i++] = crc.crcl;
|
||||||
|
pt[i++] = crc.crch;
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void modbus_loop(void)
|
||||||
|
{
|
||||||
|
static uint32_t frame_cnt = 0;
|
||||||
|
struct crc16_result_s crc;
|
||||||
|
|
||||||
|
/* no new complete frame */
|
||||||
|
if (rs485_data.frame_cnt == frame_cnt) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* one new frame occur */
|
||||||
|
frame_cnt = rs485_data.frame_cnt;
|
||||||
|
/* step 1: calc CRC */
|
||||||
|
crc16_8005_calc(rs485_data.buff_rx, rs485_data.rx_len - 2, &crc);
|
||||||
|
if (crc.crcl != rs485_data.buff_rx[rs485_data.rx_len - 2] || \
|
||||||
|
crc.crch != rs485_data.buff_rx[rs485_data.rx_len - 1]) {
|
||||||
|
/* CRC calc error */
|
||||||
|
rs485_data.rx_len = 0;
|
||||||
|
rs485_mode_rx();
|
||||||
|
rs485_rx_start();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* step 2: process data according function code */
|
||||||
|
if (rs485_data.buff_rx[1] == MODBUS_FUNCTION_CODE_READ_INPUT) {
|
||||||
|
rs485_data.tx_len = modbus_func_read_input(rs485_data.buff_rx, rs485_data.buff_tx, rs485_data.rx_len);
|
||||||
|
} else {
|
||||||
|
rs485_data.tx_len = modbus_error_process(rs485_data.buff_rx, rs485_data.buff_tx, MODBUS_ERROR_CODE_FUNCTION);
|
||||||
|
}
|
||||||
|
if (rs485_data.tx_len == 0) {
|
||||||
|
rs485_data.rx_len = 0;
|
||||||
|
rs485_mode_rx();
|
||||||
|
rs485_rx_start();
|
||||||
|
} else {
|
||||||
|
rs485_send_data(rs485_data.tx_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
37
ate/src/modbus.h
Executable file
37
ate/src/modbus.h
Executable file
@ -0,0 +1,37 @@
|
|||||||
|
#ifndef __MODBUS_H__
|
||||||
|
#define __MODBUS_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
|
||||||
|
#define MODBUS_FUNCTION_CODE_READ_INPUT (0x04)
|
||||||
|
#define MODBUS_FUNCTION_CODE_WRITE_SINGLE (0x06)
|
||||||
|
#define MODBUS_FUNCTION_CODE_WRITE_MULTI (0x10)
|
||||||
|
|
||||||
|
#define MODBUS_ERROR_CODE_FUNCTION (0x01)
|
||||||
|
#define MODBUS_ERROR_CODE_ADDR (0x02)
|
||||||
|
#define MODBUS_ERROR_CODE_VALUE (0x03)
|
||||||
|
#define MODBUS_ERROR_CODE_EXECUTE (0x04)
|
||||||
|
|
||||||
|
#define MODBUS_ADDR_RO_S (0x1234)
|
||||||
|
#define MODBUS_LENGTH_RO (9)
|
||||||
|
|
||||||
|
struct crc16_result_s {
|
||||||
|
uint8_t crch;
|
||||||
|
uint8_t crcl;
|
||||||
|
};
|
||||||
|
|
||||||
|
void crc16_8005_calc(uint8_t * p, uint16_t len, struct crc16_result_s *ret);
|
||||||
|
void modbus_init(void);
|
||||||
|
uint16_t modbus_data_big2little16(uint8_t *buff);
|
||||||
|
uint32_t modbus_data_big2little32(uint8_t *buff);
|
||||||
|
void modbus_loop(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __MODBUS_H__ */
|
||||||
208
ate/src/rs485.c
Executable file
208
ate/src/rs485.c
Executable file
@ -0,0 +1,208 @@
|
|||||||
|
#include "rs485.h"
|
||||||
|
#include "stm32f4xx_rcc.h"
|
||||||
|
#include "stm32f4xx_gpio.h"
|
||||||
|
#include "stm32f4xx_tim.h"
|
||||||
|
#include "stm32f4xx_usart.h"
|
||||||
|
#include "stm32f4xx_dma.h"
|
||||||
|
|
||||||
|
struct rs485_data_s rs485_data;
|
||||||
|
uint8_t rs485_buff_tx[RS485_BUFF_TX_LEN] __attribute__((aligned(16)));
|
||||||
|
uint8_t rs485_buff_rx[RS485_BUFF_RX_LEN];
|
||||||
|
|
||||||
|
void rs485_init(void)
|
||||||
|
{
|
||||||
|
GPIO_InitTypeDef GPIO_InitStructure;
|
||||||
|
USART_InitTypeDef USART_InitStructure;
|
||||||
|
DMA_InitTypeDef DMA_InitStructure;
|
||||||
|
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||||||
|
NVIC_InitTypeDef NVIC_InitStructure;
|
||||||
|
|
||||||
|
/* init struct data */
|
||||||
|
rs485_data.baudrate = RS485_DEFAULT_BAUDRATE;
|
||||||
|
rs485_data.parity = RS485_DEFAULT_PARITY;
|
||||||
|
rs485_data.stopbits = RS485_DEFAULT_STOPBITS;
|
||||||
|
rs485_data.addr = 0x5A;
|
||||||
|
rs485_data.rx_len = 0;
|
||||||
|
rs485_data.tx_len = 0;
|
||||||
|
rs485_data.buff_rx = rs485_buff_rx;
|
||||||
|
rs485_data.buff_tx = rs485_buff_tx;
|
||||||
|
rs485_data.frame_cnt = 0;
|
||||||
|
|
||||||
|
/* config modbus direction pin */
|
||||||
|
GPIO_InitStructure.GPIO_Pin = RS485_PIN_DIR,
|
||||||
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT,
|
||||||
|
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP,
|
||||||
|
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz,
|
||||||
|
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL,
|
||||||
|
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
|
||||||
|
GPIO_Init(RS485_PORT, &GPIO_InitStructure);
|
||||||
|
rs485_mode_rx();
|
||||||
|
|
||||||
|
/* config rs485 uart pin */
|
||||||
|
GPIO_PinAFConfig(RS485_PORT, GPIO_PinSource9, GPIO_AF_USART1);
|
||||||
|
GPIO_PinAFConfig(RS485_PORT, GPIO_PinSource10, GPIO_AF_USART1);
|
||||||
|
GPIO_InitStructure.GPIO_Pin = RS485_PIN_TX | RS485_PIN_RX;
|
||||||
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||||
|
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||||
|
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||||
|
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
|
||||||
|
GPIO_Init(RS485_PORT, &GPIO_InitStructure);
|
||||||
|
/* config rs485 uart function */
|
||||||
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
|
||||||
|
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
|
||||||
|
USART_DeInit(USART1);
|
||||||
|
USART_OverSampling8Cmd(USART1, ENABLE);
|
||||||
|
USART_InitStructure.USART_BaudRate = rs485_data.baudrate;
|
||||||
|
/* When using Parity the word length must be configured to 9 bits */
|
||||||
|
if (rs485_data.parity == RS485_PARITY_ODD) {
|
||||||
|
USART_InitStructure.USART_WordLength = USART_WordLength_9b;
|
||||||
|
USART_InitStructure.USART_Parity = USART_Parity_Odd;
|
||||||
|
} else if (rs485_data.parity == RS485_PARITY_EVEN) {
|
||||||
|
USART_InitStructure.USART_WordLength = USART_WordLength_9b;
|
||||||
|
USART_InitStructure.USART_Parity = USART_Parity_Even;
|
||||||
|
} else {
|
||||||
|
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
|
||||||
|
USART_InitStructure.USART_Parity = USART_Parity_No;
|
||||||
|
}
|
||||||
|
if (rs485_data.stopbits == 2) {
|
||||||
|
USART_InitStructure.USART_StopBits = USART_StopBits_2;
|
||||||
|
} else {
|
||||||
|
USART_InitStructure.USART_StopBits = USART_StopBits_1;
|
||||||
|
}
|
||||||
|
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
|
||||||
|
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
|
||||||
|
USART_Init(USART1, &USART_InitStructure);
|
||||||
|
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
|
||||||
|
USART_Cmd(USART1, ENABLE);
|
||||||
|
/* Configure DMA controller to manage USART TX request */
|
||||||
|
DMA_InitStructure.DMA_BufferSize = RS485_BUFF_TX_LEN;
|
||||||
|
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
|
||||||
|
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
|
||||||
|
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
|
||||||
|
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
|
||||||
|
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
|
||||||
|
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
|
||||||
|
DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t)(&(USART1->DR));
|
||||||
|
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
|
||||||
|
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
|
||||||
|
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
|
||||||
|
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
|
||||||
|
DMA_InitStructure.DMA_Channel = DMA_Channel_4;
|
||||||
|
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
|
||||||
|
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)rs485_buff_tx;
|
||||||
|
DMA_Init(DMA2_Stream7, &DMA_InitStructure);
|
||||||
|
/* Configure interrupt for USART1 RX */
|
||||||
|
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
|
||||||
|
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
|
||||||
|
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
||||||
|
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||||
|
NVIC_Init(&NVIC_InitStructure);
|
||||||
|
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
|
||||||
|
USART_ITConfig(USART1, USART_IT_TC, ENABLE);
|
||||||
|
|
||||||
|
/* config TIM4 for modbus recv timeout, 3.5 frame time */
|
||||||
|
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
|
||||||
|
if (rs485_data.baudrate >= 19200) {
|
||||||
|
TIM_TimeBaseStructure.TIM_Period = 1750;
|
||||||
|
} else {
|
||||||
|
TIM_TimeBaseStructure.TIM_Period = 1000 * 1000 * 35 / rs485_data.baudrate;
|
||||||
|
}
|
||||||
|
TIM_TimeBaseStructure.TIM_Prescaler = 84 - 1;
|
||||||
|
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
|
||||||
|
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||||||
|
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
|
||||||
|
/* Prescaler configuration */
|
||||||
|
TIM_PrescalerConfig(TIM4, 84 - 1, TIM_PSCReloadMode_Immediate);
|
||||||
|
/* TIM4 disable counter, start after reciving every uart data */
|
||||||
|
TIM_Cmd(TIM4, DISABLE);
|
||||||
|
TIM_ITConfig(TIM4, TIM_IT_Update, DISABLE);
|
||||||
|
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
|
||||||
|
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
|
||||||
|
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
||||||
|
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||||
|
NVIC_Init(&NVIC_InitStructure);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rs485_timer_restart(void)
|
||||||
|
{
|
||||||
|
TIM_ITConfig(TIM4, TIM_IT_Update, DISABLE);
|
||||||
|
TIM_SetCounter(TIM4, 0);
|
||||||
|
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
|
||||||
|
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
|
||||||
|
TIM_Cmd(TIM4, ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rs485_timer_stop(void)
|
||||||
|
{
|
||||||
|
TIM_Cmd(TIM4, DISABLE);
|
||||||
|
TIM_ITConfig(TIM4, TIM_IT_Update, DISABLE);
|
||||||
|
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rs485_mode_tx(void)
|
||||||
|
{
|
||||||
|
GPIO_SetBits(RS485_PORT, RS485_PIN_DIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rs485_mode_rx(void)
|
||||||
|
{
|
||||||
|
GPIO_ResetBits(RS485_PORT, RS485_PIN_DIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rs485_rx_start(void)
|
||||||
|
{
|
||||||
|
/* clear PE, FE, NE, ORE and IDLE flags, reference USART_ClearFlag function */
|
||||||
|
USART_GetITStatus(USART1, USART_IT_RXNE);
|
||||||
|
USART_ReceiveData(USART1);
|
||||||
|
USART_ClearFlag(USART1, USART_FLAG_RXNE);
|
||||||
|
/* enable USART receive interrupt */
|
||||||
|
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rs485_rx_stop(void)
|
||||||
|
{
|
||||||
|
USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
|
||||||
|
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rs485_send_data(uint16_t len)
|
||||||
|
{
|
||||||
|
rs485_mode_tx();
|
||||||
|
DMA_SetCurrDataCounter(DMA2_Stream7, len);
|
||||||
|
USART_ClearITPendingBit(USART1, USART_IT_TC);
|
||||||
|
DMA_Cmd(DMA2_Stream7, ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void USART1_IRQHandler(void)
|
||||||
|
{
|
||||||
|
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
|
||||||
|
rs485_timer_restart();
|
||||||
|
if (rs485_data.rx_len < RS485_BUFF_RX_LEN) {
|
||||||
|
rs485_buff_rx[rs485_data.rx_len++] = USART_ReceiveData(USART1);
|
||||||
|
} else {
|
||||||
|
/* exception, has recevered too much data, drop */
|
||||||
|
rs485_data.rx_len = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* one tx frame complete */
|
||||||
|
if (USART_GetITStatus(USART1, USART_IT_TC) != RESET) {
|
||||||
|
USART_ClearITPendingBit(USART1, USART_IT_TC);
|
||||||
|
DMA_ClearFlag(DMA2_Stream7, DMA_FLAG_TCIF7);
|
||||||
|
rs485_data.rx_len = 0;
|
||||||
|
rs485_mode_rx();
|
||||||
|
rs485_rx_start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TIM4_IRQHandler(void)
|
||||||
|
{
|
||||||
|
rs485_timer_stop();
|
||||||
|
if (rs485_data.buff_rx[0] == rs485_data.addr && rs485_data.rx_len > 3) {
|
||||||
|
/* one completed frame, need processing */
|
||||||
|
rs485_rx_stop();
|
||||||
|
rs485_data.frame_cnt++;
|
||||||
|
} else {
|
||||||
|
/* address not match, drop */
|
||||||
|
rs485_data.rx_len = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
53
ate/src/rs485.h
Executable file
53
ate/src/rs485.h
Executable file
@ -0,0 +1,53 @@
|
|||||||
|
#ifndef __RS485_H__
|
||||||
|
#define __RS485_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
|
||||||
|
#define RS485_PORT (GPIOA)
|
||||||
|
#define RS485_PIN_DIR (GPIO_Pin_8)
|
||||||
|
#define RS485_PIN_TX (GPIO_Pin_9)
|
||||||
|
#define RS485_PIN_RX (GPIO_Pin_10)
|
||||||
|
|
||||||
|
#define RS485_PARITY_NONE (0)
|
||||||
|
#define RS485_PARITY_ODD (1)
|
||||||
|
#define RS485_PARITY_EVEN (2)
|
||||||
|
|
||||||
|
#define RS485_DEFAULT_BAUDRATE (19200)
|
||||||
|
#define RS485_DEFAULT_PARITY (RS485_PARITY_NONE)
|
||||||
|
#define RS485_DEFAULT_STOPBITS (1)
|
||||||
|
|
||||||
|
#define RS485_BUFF_TX_LEN (1024)
|
||||||
|
#define RS485_BUFF_RX_LEN (1024)
|
||||||
|
|
||||||
|
struct rs485_data_s {
|
||||||
|
uint32_t baudrate;
|
||||||
|
uint8_t parity;
|
||||||
|
uint8_t stopbits;
|
||||||
|
uint8_t addr;
|
||||||
|
uint16_t rx_len;
|
||||||
|
uint16_t tx_len;
|
||||||
|
uint8_t *buff_rx;
|
||||||
|
uint8_t *buff_tx;
|
||||||
|
uint32_t frame_cnt;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct rs485_data_s rs485_data;
|
||||||
|
|
||||||
|
void rs485_init(void);
|
||||||
|
void rs485_timer_restart(void);
|
||||||
|
void rs485_timer_stop(void);
|
||||||
|
void rs485_mode_tx(void);
|
||||||
|
void rs485_mode_rx(void);
|
||||||
|
void rs485_rx_start(void);
|
||||||
|
void rs485_rx_stop(void);
|
||||||
|
void rs485_send_data(uint16_t len);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __RS485_H__ */
|
||||||
76
ate/src/sd.c
Executable file
76
ate/src/sd.c
Executable file
@ -0,0 +1,76 @@
|
|||||||
|
#include "ff.h"
|
||||||
|
#include "sd.h"
|
||||||
|
#include "sdio_sd.h"
|
||||||
|
#include "device.h"
|
||||||
|
|
||||||
|
#define RETRY_MAX (3)
|
||||||
|
|
||||||
|
FATFS fs;
|
||||||
|
TCHAR file_name[FILE_NAME_LEN];
|
||||||
|
|
||||||
|
uint8_t sd_detect(void)
|
||||||
|
{
|
||||||
|
SD_Error sd_err;
|
||||||
|
FRESULT ret;
|
||||||
|
uint32_t retry;
|
||||||
|
DIR dir;
|
||||||
|
TCHAR name[FILE_NAME_LEN];
|
||||||
|
|
||||||
|
retry = RETRY_MAX;
|
||||||
|
while (retry--) {
|
||||||
|
sd_err = SD_Init();
|
||||||
|
if (sd_err == SD_OK) {
|
||||||
|
break;
|
||||||
|
} else if (retry == 0) {
|
||||||
|
SD_DeInit();
|
||||||
|
return SD_STS_ERR_INIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
retry = RETRY_MAX;
|
||||||
|
while (retry--) {
|
||||||
|
ret = f_mount(0, &fs);
|
||||||
|
if (ret == FR_OK) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
SD_DeInit();
|
||||||
|
return SD_STS_ERR_MOUNT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
retry = RETRY_MAX;
|
||||||
|
while (retry--) {
|
||||||
|
ret = f_getcwd(name, sizeof(name));
|
||||||
|
if (ret == FR_OK) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
SD_DeInit();
|
||||||
|
return SD_STS_ERR_GETCWD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
retry = RETRY_MAX;
|
||||||
|
while (retry--) {
|
||||||
|
ret = f_opendir(&dir, name);
|
||||||
|
if (ret == FR_OK) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
SD_DeInit();
|
||||||
|
return SD_STS_ERR_OPENDIR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SD_STS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sd_loop(void)
|
||||||
|
{
|
||||||
|
static uint32_t ms = 0;
|
||||||
|
|
||||||
|
if (system_tick_cnt < (ms + 500)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ms = system_tick_cnt;
|
||||||
|
|
||||||
|
device_data.sd = sd_detect();
|
||||||
|
}
|
||||||
29
ate/src/sd.h
Executable file
29
ate/src/sd.h
Executable file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef __SD_H__
|
||||||
|
#define __SD_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
#include "ff.h"
|
||||||
|
|
||||||
|
#define SD_STS_NULL (0)
|
||||||
|
#define SD_STS_ERR_INIT (1)
|
||||||
|
#define SD_STS_ERR_MOUNT (2)
|
||||||
|
#define SD_STS_ERR_GETCWD (3)
|
||||||
|
#define SD_STS_ERR_OPENDIR (4)
|
||||||
|
#define SD_STS_OK (5)
|
||||||
|
|
||||||
|
#define FILE_NAME_LEN (13)
|
||||||
|
|
||||||
|
extern uint32_t system_tick_cnt;
|
||||||
|
|
||||||
|
uint8_t sd_detect(void);
|
||||||
|
void sd_loop(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __SD_H__ */
|
||||||
370
ate/start.S
Executable file
370
ate/start.S
Executable file
@ -0,0 +1,370 @@
|
|||||||
|
.syntax unified
|
||||||
|
.cpu cortex-m4
|
||||||
|
.thumb
|
||||||
|
|
||||||
|
.global g_pfnVectors
|
||||||
|
.global Default_Handler
|
||||||
|
.global Reset_Handler
|
||||||
|
|
||||||
|
.section .text.Reset_Handler
|
||||||
|
.weak Reset_Handler
|
||||||
|
.type Reset_Handler, %function
|
||||||
|
Reset_Handler:
|
||||||
|
cpsid i /* disable irq */
|
||||||
|
ldr r0, =_stack_top
|
||||||
|
msr msp, r0
|
||||||
|
/* load data section */
|
||||||
|
ldr r0, =_data_load
|
||||||
|
ldr r1, =_data_run
|
||||||
|
ldr r2, =_data_run_end
|
||||||
|
cmp r1, r2
|
||||||
|
bhs 2f
|
||||||
|
1:
|
||||||
|
ldr r3, [r0], #4
|
||||||
|
str r3, [r1], #4
|
||||||
|
cmp r1, r2
|
||||||
|
blo 1b
|
||||||
|
2:
|
||||||
|
/* clear bss section */
|
||||||
|
ldr r0, =0
|
||||||
|
ldr r1, =_bss_run
|
||||||
|
ldr r2, =_bss_run_end
|
||||||
|
cmp r1, r2
|
||||||
|
bhs 2f
|
||||||
|
1:
|
||||||
|
str r0, [r1], #4
|
||||||
|
cmp r1, r2
|
||||||
|
blo 1b
|
||||||
|
2:
|
||||||
|
/* load data_ccm section */
|
||||||
|
ldr r0, =_data_ccm_load
|
||||||
|
ldr r1, =_data_ccm_run
|
||||||
|
ldr r2, =_data_ccm_run_end
|
||||||
|
cmp r1, r2
|
||||||
|
bhs 2f
|
||||||
|
1:
|
||||||
|
ldr r3, [r0], #4
|
||||||
|
str r3, [r1], #4
|
||||||
|
cmp r1, r2
|
||||||
|
blo 1b
|
||||||
|
2:
|
||||||
|
/* clear bss_ccm section */
|
||||||
|
ldr r0, =0
|
||||||
|
ldr r1, =_bss_ccm_run
|
||||||
|
ldr r2, =_bss_ccm_run_end
|
||||||
|
cmp r1, r2
|
||||||
|
bhs 2f
|
||||||
|
1:
|
||||||
|
str r0, [r1], #4
|
||||||
|
cmp r1, r2
|
||||||
|
blo 1b
|
||||||
|
2:
|
||||||
|
bl SystemInit
|
||||||
|
bl main
|
||||||
|
b .
|
||||||
|
.size Reset_Handler, .-Reset_Handler
|
||||||
|
|
||||||
|
.section .text.Default_Handler,"ax",%progbits
|
||||||
|
Default_Handler:
|
||||||
|
MRS r0, msp
|
||||||
|
STMFD r0!, {r4 - r11}
|
||||||
|
STMFD r0!, {lr}
|
||||||
|
MSR msp, r0
|
||||||
|
|
||||||
|
PUSH {lr}
|
||||||
|
BL coredump
|
||||||
|
POP {lr}
|
||||||
|
|
||||||
|
POP {lr}
|
||||||
|
POP {r4 - r11}
|
||||||
|
|
||||||
|
BX lr
|
||||||
|
.size Default_Handler, .-Default_Handler
|
||||||
|
|
||||||
|
.section .isr_vector,"a",%progbits
|
||||||
|
.type g_pfnVectors, %object
|
||||||
|
.size g_pfnVectors, .-g_pfnVectors
|
||||||
|
g_pfnVectors:
|
||||||
|
.word _stack_top
|
||||||
|
.word Reset_Handler
|
||||||
|
.word NMI_Handler
|
||||||
|
.word HardFault_Handler
|
||||||
|
.word MemManage_Handler
|
||||||
|
.word BusFault_Handler
|
||||||
|
.word UsageFault_Handler
|
||||||
|
.word 0
|
||||||
|
.word 0
|
||||||
|
.word 0
|
||||||
|
.word 0
|
||||||
|
.word SVC_Handler
|
||||||
|
.word DebugMon_Handler
|
||||||
|
.word 0
|
||||||
|
.word PendSV_Handler
|
||||||
|
.word SysTick_Handler
|
||||||
|
/* External Interrupts */
|
||||||
|
.word WWDG_IRQHandler /* Window WatchDog */
|
||||||
|
.word PVD_IRQHandler /* PVD through EXTI Line detection */
|
||||||
|
.word TAMP_STAMP_IRQHandler /* Tamper and TimeStamps through the EXTI line */
|
||||||
|
.word RTC_WKUP_IRQHandler /* RTC Wakeup through the EXTI line */
|
||||||
|
.word FLASH_IRQHandler /* FLASH */
|
||||||
|
.word RCC_IRQHandler /* RCC */
|
||||||
|
.word EXTI0_IRQHandler /* EXTI Line0 */
|
||||||
|
.word EXTI1_IRQHandler /* EXTI Line1 */
|
||||||
|
.word EXTI2_IRQHandler /* EXTI Line2 */
|
||||||
|
.word EXTI3_IRQHandler /* EXTI Line3 */
|
||||||
|
.word EXTI4_IRQHandler /* EXTI Line4 */
|
||||||
|
.word DMA1_Stream0_IRQHandler /* DMA1 Stream 0 */
|
||||||
|
.word DMA1_Stream1_IRQHandler /* DMA1 Stream 1 */
|
||||||
|
.word DMA1_Stream2_IRQHandler /* DMA1 Stream 2 */
|
||||||
|
.word DMA1_Stream3_IRQHandler /* DMA1 Stream 3 */
|
||||||
|
.word DMA1_Stream4_IRQHandler /* DMA1 Stream 4 */
|
||||||
|
.word DMA1_Stream5_IRQHandler /* DMA1 Stream 5 */
|
||||||
|
.word DMA1_Stream6_IRQHandler /* DMA1 Stream 6 */
|
||||||
|
.word ADC_IRQHandler /* ADC1, ADC2 and ADC3s */
|
||||||
|
.word CAN1_TX_IRQHandler /* CAN1 TX */
|
||||||
|
.word CAN1_RX0_IRQHandler /* CAN1 RX0 */
|
||||||
|
.word CAN1_RX1_IRQHandler /* CAN1 RX1 */
|
||||||
|
.word CAN1_SCE_IRQHandler /* CAN1 SCE */
|
||||||
|
.word EXTI9_5_IRQHandler /* External Line[9:5]s */
|
||||||
|
.word TIM1_BRK_TIM9_IRQHandler /* TIM1 Break and TIM9 */
|
||||||
|
.word TIM1_UP_TIM10_IRQHandler /* TIM1 Update and TIM10 */
|
||||||
|
.word TIM1_TRG_COM_TIM11_IRQHandler /* TIM1 Trigger and Commutation and TIM11 */
|
||||||
|
.word TIM1_CC_IRQHandler /* TIM1 Capture Compare */
|
||||||
|
.word TIM2_IRQHandler /* TIM2 */
|
||||||
|
.word TIM3_IRQHandler /* TIM3 */
|
||||||
|
.word TIM4_IRQHandler /* TIM4 */
|
||||||
|
.word I2C1_EV_IRQHandler /* I2C1 Event */
|
||||||
|
.word I2C1_ER_IRQHandler /* I2C1 Error */
|
||||||
|
.word I2C2_EV_IRQHandler /* I2C2 Event */
|
||||||
|
.word I2C2_ER_IRQHandler /* I2C2 Error */
|
||||||
|
.word SPI1_IRQHandler /* SPI1 */
|
||||||
|
.word SPI2_IRQHandler /* SPI2 */
|
||||||
|
.word USART1_IRQHandler /* USART1 */
|
||||||
|
.word USART2_IRQHandler /* USART2 */
|
||||||
|
.word USART3_IRQHandler /* USART3 */
|
||||||
|
.word EXTI15_10_IRQHandler /* External Line[15:10]s */
|
||||||
|
.word RTC_Alarm_IRQHandler /* RTC Alarm (A and B) through EXTI Line */
|
||||||
|
.word OTG_FS_WKUP_IRQHandler /* USB OTG FS Wakeup through EXTI line */
|
||||||
|
.word TIM8_BRK_TIM12_IRQHandler /* TIM8 Break and TIM12 */
|
||||||
|
.word TIM8_UP_TIM13_IRQHandler /* TIM8 Update and TIM13 */
|
||||||
|
.word TIM8_TRG_COM_TIM14_IRQHandler /* TIM8 Trigger and Commutation and TIM14 */
|
||||||
|
.word TIM8_CC_IRQHandler /* TIM8 Capture Compare */
|
||||||
|
.word DMA1_Stream7_IRQHandler /* DMA1 Stream7 */
|
||||||
|
.word FSMC_IRQHandler /* FSMC */
|
||||||
|
.word SDIO_IRQHandler /* SDIO */
|
||||||
|
.word TIM5_IRQHandler /* TIM5 */
|
||||||
|
.word SPI3_IRQHandler /* SPI3 */
|
||||||
|
.word UART4_IRQHandler /* UART4 */
|
||||||
|
.word UART5_IRQHandler /* UART5 */
|
||||||
|
.word TIM6_DAC_IRQHandler /* TIM6 and DAC1&2 underrun errors */
|
||||||
|
.word TIM7_IRQHandler /* TIM7 */
|
||||||
|
.word DMA2_Stream0_IRQHandler /* DMA2 Stream 0 */
|
||||||
|
.word DMA2_Stream1_IRQHandler /* DMA2 Stream 1 */
|
||||||
|
.word DMA2_Stream2_IRQHandler /* DMA2 Stream 2 */
|
||||||
|
.word DMA2_Stream3_IRQHandler /* DMA2 Stream 3 */
|
||||||
|
.word DMA2_Stream4_IRQHandler /* DMA2 Stream 4 */
|
||||||
|
.word ETH_IRQHandler /* Ethernet */
|
||||||
|
.word ETH_WKUP_IRQHandler /* Ethernet Wakeup through EXTI line */
|
||||||
|
.word CAN2_TX_IRQHandler /* CAN2 TX */
|
||||||
|
.word CAN2_RX0_IRQHandler /* CAN2 RX0 */
|
||||||
|
.word CAN2_RX1_IRQHandler /* CAN2 RX1 */
|
||||||
|
.word CAN2_SCE_IRQHandler /* CAN2 SCE */
|
||||||
|
.word OTG_FS_IRQHandler /* USB OTG FS */
|
||||||
|
.word DMA2_Stream5_IRQHandler /* DMA2 Stream 5 */
|
||||||
|
.word DMA2_Stream6_IRQHandler /* DMA2 Stream 6 */
|
||||||
|
.word DMA2_Stream7_IRQHandler /* DMA2 Stream 7 */
|
||||||
|
.word USART6_IRQHandler /* USART6 */
|
||||||
|
.word I2C3_EV_IRQHandler /* I2C3 event */
|
||||||
|
.word I2C3_ER_IRQHandler /* I2C3 error */
|
||||||
|
.word OTG_HS_EP1_OUT_IRQHandler /* USB OTG HS End Point 1 Out */
|
||||||
|
.word OTG_HS_EP1_IN_IRQHandler /* USB OTG HS End Point 1 In */
|
||||||
|
.word OTG_HS_WKUP_IRQHandler /* USB OTG HS Wakeup through EXTI */
|
||||||
|
.word OTG_HS_IRQHandler /* USB OTG HS */
|
||||||
|
.word DCMI_IRQHandler /* DCMI */
|
||||||
|
.word CRYP_IRQHandler /* CRYP crypto */
|
||||||
|
.word HASH_RNG_IRQHandler /* Hash and Rng */
|
||||||
|
.word FPU_IRQHandler /* FPU */
|
||||||
|
|
||||||
|
.weak NMI_Handler
|
||||||
|
.thumb_set NMI_Handler,Default_Handler
|
||||||
|
.weak HardFault_Handler
|
||||||
|
.thumb_set HardFault_Handler,Default_Handler
|
||||||
|
.weak MemManage_Handler
|
||||||
|
.thumb_set MemManage_Handler,Default_Handler
|
||||||
|
.weak BusFault_Handler
|
||||||
|
.thumb_set BusFault_Handler,Default_Handler
|
||||||
|
.weak UsageFault_Handler
|
||||||
|
.thumb_set UsageFault_Handler,Default_Handler
|
||||||
|
.weak SVC_Handler
|
||||||
|
.thumb_set SVC_Handler,Default_Handler
|
||||||
|
.weak DebugMon_Handler
|
||||||
|
.thumb_set DebugMon_Handler,Default_Handler
|
||||||
|
.weak PendSV_Handler
|
||||||
|
.thumb_set PendSV_Handler,Default_Handler
|
||||||
|
.weak SysTick_Handler
|
||||||
|
.thumb_set SysTick_Handler,Default_Handler
|
||||||
|
/* External Interrupts */
|
||||||
|
.weak WWDG_IRQHandler
|
||||||
|
.thumb_set WWDG_IRQHandler,Default_Handler
|
||||||
|
.weak PVD_IRQHandler
|
||||||
|
.thumb_set PVD_IRQHandler,Default_Handler
|
||||||
|
.weak TAMP_STAMP_IRQHandler
|
||||||
|
.thumb_set TAMP_STAMP_IRQHandler,Default_Handler
|
||||||
|
.weak RTC_WKUP_IRQHandler
|
||||||
|
.thumb_set RTC_WKUP_IRQHandler,Default_Handler
|
||||||
|
.weak FLASH_IRQHandler
|
||||||
|
.thumb_set FLASH_IRQHandler,Default_Handler
|
||||||
|
.weak RCC_IRQHandler
|
||||||
|
.thumb_set RCC_IRQHandler,Default_Handler
|
||||||
|
.weak EXTI0_IRQHandler
|
||||||
|
.thumb_set EXTI0_IRQHandler,Default_Handler
|
||||||
|
.weak EXTI1_IRQHandler
|
||||||
|
.thumb_set EXTI1_IRQHandler,Default_Handler
|
||||||
|
.weak EXTI2_IRQHandler
|
||||||
|
.thumb_set EXTI2_IRQHandler,Default_Handler
|
||||||
|
.weak EXTI3_IRQHandler
|
||||||
|
.thumb_set EXTI3_IRQHandler,Default_Handler
|
||||||
|
.weak EXTI4_IRQHandler
|
||||||
|
.thumb_set EXTI4_IRQHandler,Default_Handler
|
||||||
|
.weak DMA1_Stream0_IRQHandler
|
||||||
|
.thumb_set DMA1_Stream0_IRQHandler,Default_Handler
|
||||||
|
.weak DMA1_Stream1_IRQHandler
|
||||||
|
.thumb_set DMA1_Stream1_IRQHandler,Default_Handler
|
||||||
|
.weak DMA1_Stream2_IRQHandler
|
||||||
|
.thumb_set DMA1_Stream2_IRQHandler,Default_Handler
|
||||||
|
.weak DMA1_Stream3_IRQHandler
|
||||||
|
.thumb_set DMA1_Stream3_IRQHandler,Default_Handler
|
||||||
|
.weak DMA1_Stream4_IRQHandler
|
||||||
|
.thumb_set DMA1_Stream4_IRQHandler,Default_Handler
|
||||||
|
.weak DMA1_Stream5_IRQHandler
|
||||||
|
.thumb_set DMA1_Stream5_IRQHandler,Default_Handler
|
||||||
|
.weak DMA1_Stream6_IRQHandler
|
||||||
|
.thumb_set DMA1_Stream6_IRQHandler,Default_Handler
|
||||||
|
.weak ADC_IRQHandler
|
||||||
|
.thumb_set ADC_IRQHandler,Default_Handler
|
||||||
|
.weak CAN1_TX_IRQHandler
|
||||||
|
.thumb_set CAN1_TX_IRQHandler,Default_Handler
|
||||||
|
.weak CAN1_RX0_IRQHandler
|
||||||
|
.thumb_set CAN1_RX0_IRQHandler,Default_Handler
|
||||||
|
.weak CAN1_RX1_IRQHandler
|
||||||
|
.thumb_set CAN1_RX1_IRQHandler,Default_Handler
|
||||||
|
.weak CAN1_SCE_IRQHandler
|
||||||
|
.thumb_set CAN1_SCE_IRQHandler,Default_Handler
|
||||||
|
.weak EXTI9_5_IRQHandler
|
||||||
|
.thumb_set EXTI9_5_IRQHandler,Default_Handler
|
||||||
|
.weak TIM1_BRK_TIM9_IRQHandler
|
||||||
|
.thumb_set TIM1_BRK_TIM9_IRQHandler,Default_Handler
|
||||||
|
.weak TIM1_UP_TIM10_IRQHandler
|
||||||
|
.thumb_set TIM1_UP_TIM10_IRQHandler,Default_Handler
|
||||||
|
.weak TIM1_TRG_COM_TIM11_IRQHandler
|
||||||
|
.thumb_set TIM1_TRG_COM_TIM11_IRQHandler,Default_Handler
|
||||||
|
.weak TIM1_CC_IRQHandler
|
||||||
|
.thumb_set TIM1_CC_IRQHandler,Default_Handler
|
||||||
|
.weak TIM2_IRQHandler
|
||||||
|
.thumb_set TIM2_IRQHandler,Default_Handler
|
||||||
|
.weak TIM3_IRQHandler
|
||||||
|
.thumb_set TIM3_IRQHandler,Default_Handler
|
||||||
|
.weak TIM4_IRQHandler
|
||||||
|
.thumb_set TIM4_IRQHandler,Default_Handler
|
||||||
|
.weak I2C1_EV_IRQHandler
|
||||||
|
.thumb_set I2C1_EV_IRQHandler,Default_Handler
|
||||||
|
.weak I2C1_ER_IRQHandler
|
||||||
|
.thumb_set I2C1_ER_IRQHandler,Default_Handler
|
||||||
|
.weak I2C2_EV_IRQHandler
|
||||||
|
.thumb_set I2C2_EV_IRQHandler,Default_Handler
|
||||||
|
.weak I2C2_ER_IRQHandler
|
||||||
|
.thumb_set I2C2_ER_IRQHandler,Default_Handler
|
||||||
|
.weak SPI1_IRQHandler
|
||||||
|
.thumb_set SPI1_IRQHandler,Default_Handler
|
||||||
|
.weak SPI2_IRQHandler
|
||||||
|
.thumb_set SPI2_IRQHandler,Default_Handler
|
||||||
|
.weak USART1_IRQHandler
|
||||||
|
.thumb_set USART1_IRQHandler,Default_Handler
|
||||||
|
.weak USART2_IRQHandler
|
||||||
|
.thumb_set USART2_IRQHandler,Default_Handler
|
||||||
|
.weak USART3_IRQHandler
|
||||||
|
.thumb_set USART3_IRQHandler,Default_Handler
|
||||||
|
.weak EXTI15_10_IRQHandler
|
||||||
|
.thumb_set EXTI15_10_IRQHandler,Default_Handler
|
||||||
|
.weak RTC_Alarm_IRQHandler
|
||||||
|
.thumb_set RTC_Alarm_IRQHandler,Default_Handler
|
||||||
|
.weak OTG_FS_WKUP_IRQHandler
|
||||||
|
.thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler
|
||||||
|
.weak TIM8_BRK_TIM12_IRQHandler
|
||||||
|
.thumb_set TIM8_BRK_TIM12_IRQHandler,Default_Handler
|
||||||
|
.weak TIM8_UP_TIM13_IRQHandler
|
||||||
|
.thumb_set TIM8_UP_TIM13_IRQHandler,Default_Handler
|
||||||
|
.weak TIM8_TRG_COM_TIM14_IRQHandler
|
||||||
|
.thumb_set TIM8_TRG_COM_TIM14_IRQHandler,Default_Handler
|
||||||
|
.weak TIM8_CC_IRQHandler
|
||||||
|
.thumb_set TIM8_CC_IRQHandler,Default_Handler
|
||||||
|
.weak DMA1_Stream7_IRQHandler
|
||||||
|
.thumb_set DMA1_Stream7_IRQHandler,Default_Handler
|
||||||
|
.weak FSMC_IRQHandler
|
||||||
|
.thumb_set FSMC_IRQHandler,Default_Handler
|
||||||
|
.weak SDIO_IRQHandler
|
||||||
|
.thumb_set SDIO_IRQHandler,Default_Handler
|
||||||
|
.weak TIM5_IRQHandler
|
||||||
|
.thumb_set TIM5_IRQHandler,Default_Handler
|
||||||
|
.weak SPI3_IRQHandler
|
||||||
|
.thumb_set SPI3_IRQHandler,Default_Handler
|
||||||
|
.weak UART4_IRQHandler
|
||||||
|
.thumb_set UART4_IRQHandler,Default_Handler
|
||||||
|
.weak UART5_IRQHandler
|
||||||
|
.thumb_set UART5_IRQHandler,Default_Handler
|
||||||
|
.weak TIM6_DAC_IRQHandler
|
||||||
|
.thumb_set TIM6_DAC_IRQHandler,Default_Handler
|
||||||
|
.weak TIM7_IRQHandler
|
||||||
|
.thumb_set TIM7_IRQHandler,Default_Handler
|
||||||
|
.weak DMA2_Stream0_IRQHandler
|
||||||
|
.thumb_set DMA2_Stream0_IRQHandler,Default_Handler
|
||||||
|
.weak DMA2_Stream1_IRQHandler
|
||||||
|
.thumb_set DMA2_Stream1_IRQHandler,Default_Handler
|
||||||
|
.weak DMA2_Stream2_IRQHandler
|
||||||
|
.thumb_set DMA2_Stream2_IRQHandler,Default_Handler
|
||||||
|
.weak DMA2_Stream3_IRQHandler
|
||||||
|
.thumb_set DMA2_Stream3_IRQHandler,Default_Handler
|
||||||
|
.weak DMA2_Stream4_IRQHandler
|
||||||
|
.thumb_set DMA2_Stream4_IRQHandler,Default_Handler
|
||||||
|
.weak ETH_IRQHandler
|
||||||
|
.thumb_set ETH_IRQHandler,Default_Handler
|
||||||
|
.weak ETH_WKUP_IRQHandler
|
||||||
|
.thumb_set ETH_WKUP_IRQHandler,Default_Handler
|
||||||
|
.weak CAN2_TX_IRQHandler
|
||||||
|
.thumb_set CAN2_TX_IRQHandler,Default_Handler
|
||||||
|
.weak CAN2_RX0_IRQHandler
|
||||||
|
.thumb_set CAN2_RX0_IRQHandler,Default_Handler
|
||||||
|
.weak CAN2_RX1_IRQHandler
|
||||||
|
.thumb_set CAN2_RX1_IRQHandler,Default_Handler
|
||||||
|
.weak CAN2_SCE_IRQHandler
|
||||||
|
.thumb_set CAN2_SCE_IRQHandler,Default_Handler
|
||||||
|
.weak OTG_FS_IRQHandler
|
||||||
|
.thumb_set OTG_FS_IRQHandler,Default_Handler
|
||||||
|
.weak DMA2_Stream5_IRQHandler
|
||||||
|
.thumb_set DMA2_Stream5_IRQHandler,Default_Handler
|
||||||
|
.weak DMA2_Stream6_IRQHandler
|
||||||
|
.thumb_set DMA2_Stream6_IRQHandler,Default_Handler
|
||||||
|
.weak DMA2_Stream7_IRQHandler
|
||||||
|
.thumb_set DMA2_Stream7_IRQHandler,Default_Handler
|
||||||
|
.weak USART6_IRQHandler
|
||||||
|
.thumb_set USART6_IRQHandler,Default_Handler
|
||||||
|
.weak I2C3_EV_IRQHandler
|
||||||
|
.thumb_set I2C3_EV_IRQHandler,Default_Handler
|
||||||
|
.weak I2C3_ER_IRQHandler
|
||||||
|
.thumb_set I2C3_ER_IRQHandler,Default_Handler
|
||||||
|
.weak OTG_HS_EP1_OUT_IRQHandler
|
||||||
|
.thumb_set OTG_HS_EP1_OUT_IRQHandler,Default_Handler
|
||||||
|
.weak OTG_HS_EP1_IN_IRQHandler
|
||||||
|
.thumb_set OTG_HS_EP1_IN_IRQHandler,Default_Handler
|
||||||
|
.weak OTG_HS_WKUP_IRQHandler
|
||||||
|
.thumb_set OTG_HS_WKUP_IRQHandler,Default_Handler
|
||||||
|
.weak OTG_HS_IRQHandler
|
||||||
|
.thumb_set OTG_HS_IRQHandler,Default_Handler
|
||||||
|
.weak DCMI_IRQHandler
|
||||||
|
.thumb_set DCMI_IRQHandler,Default_Handler
|
||||||
|
.weak CRYP_IRQHandler
|
||||||
|
.thumb_set CRYP_IRQHandler,Default_Handler
|
||||||
|
.weak HASH_RNG_IRQHandler
|
||||||
|
.thumb_set HASH_RNG_IRQHandler,Default_Handler
|
||||||
|
.weak FPU_IRQHandler
|
||||||
|
.thumb_set FPU_IRQHandler,Default_Handler
|
||||||
Loading…
Reference in New Issue
Block a user