[feat] add ate
This commit is contained in:
parent
8c5616fbce
commit
6103e0d628
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,5 +1,6 @@
|
||||
bootloader/build/*
|
||||
lark1fq/build/*
|
||||
ate/build/*
|
||||
test/build/*
|
||||
tools/*.exe
|
||||
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