#include "ti_msp_dl_config.h"
#include "tjc_usart_hmi.h"
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <ti/driverlib/dl_uart.h>
#include <ti/devices/msp/msp.h>
#include <ti/driverlib/driverlib.h>
#include <ti/driverlib/dl_common.h>
// 红外协议时序宏 (单位:微秒)
#define LEADER_HIGH 9000 // 引导码高电平9ms
#define LEADER_LOW 4500 // 引导码低电平4.5ms
#define BIT_HIGH 560 // 数据位高电平560μs
#define BIT_ONE_LOW 1690 // 逻辑"1"低电平1690μs
#define BIT_ZERO_LOW 560 // 逻辑"0"低电平560μs
#define TOLERANCE 150 // 时序容差±150μs
#define SYSTEM_CLOCK 32000000 //// 32MHz
// 安全参数
#define MAX_RETRY 3 // 最大重试次数
#define LOCK_TIME 15000 // 锁定时间(ms)
#define TIME_WINDOW 3000 // 时间容错窗口(±3000ms)
// 淘晶驰屏定义
#define TJC_PAGE_MAIN 0
#define TJC_TEXT_STATUS "t0"
#define TJC_TEXT_TIME "t1"
#define TJC_BUTTON_RESET "b0"
// 全局变量
volatile uint32_t delay_value __attribute__((section(".bss")));
volatile uint8_t retry_count __attribute__((section(".bss")));
volatile uint32_t last_fail_time __attribute__((section(".bss")));
volatile uint32_t rtc_counter __attribute__((section(".bss")));
volatile uint32_t now_time __attribute__((section(".bss")));
#define GLOBAL_VARS_BASE 0x20000000
typedef struct {
volatile uint32_t delay_value;
volatile uint8_t retry_count;
volatile uint32_t last_fail_time;
volatile uint32_t rtc_counter;
volatile uint32_t now_time;
volatile uint32_t last_time;
volatile uint32_t counter;
char str[50];
} GlobalVars;
volatile GlobalVars* const globals = (GlobalVars*)GLOBAL_VARS_BASE;
/******************** 淘晶驰串口屏驱动 ********************/
void tjc_send_cmd(const char *cmd)
{
// 发送命令主体
const char *p = cmd;
while(*p)
{
while(!DL_UART_isTXFIFOEmpty(UART_0_INST)); // 等待发送完成
DL_UART_transmitData(UART_0_INST, *p++);
}
// 发送TJC协议结束符(0xFF 0xFF 0xFF)
for(uint8_t i = 0; i < 3; i++)
{
while(!DL_UART_isTXFIFOEmpty(UART_0_INST));
DL_UART_transmitData(UART_0_INST, 0xFF);
}
}
void tjc_set_text(const char *obj_name, const char *text)
{
char cmd[128];
snprintf(cmd, sizeof(cmd), "%s.txt=\"%s\"", obj_name, text);
tjc_send_cmd(cmd);
}
void tjc_change_page(uint8_t page_id)
{
char cmd[16];
snprintf(cmd, sizeof(cmd), "page %d", page_id);
tjc_send_cmd(cmd);
}
void tjc_beep(uint16_t duration_ms)
{
char cmd[16];
snprintf(cmd, sizeof(cmd), "beep %u", duration_ms);
tjc_send_cmd(cmd);
}
/******************** 系统基础功能 ********************/
void delay_us(uint32_t us)
{
delay_value = us;
while(delay_value != 0);
}
void SysTick_Handler(void)
{
if(delay_value > 0) delay_value--;
rtc_counter++; // 简单的RTC计数器(每毫秒增加1)
now_time = rtc_counter; // 更新全局时间
}
uint32_t get_timestamp(void)
{
return rtc_counter;
}
/******************** 红外解码功能(8位) ********************/
bool validate_dynamic_code(uint8_t rx_code)
{
uint32_t current_seed = get_timestamp();
for(int offset = -TIME_WINDOW; offset <= TIME_WINDOW; offset++)
{
uint32_t seed = current_seed + offset;
uint32_t calc_code = (seed * 0x5DEECE66D) & 0xFFFFFFFF;
// 比较低8位
if(rx_code == (calc_code & 0xFF))
return true;
}
return false;
}
uint8_t ir_receive_packet(void)
{
uint8_t data = 0;
uint32_t start_time = 0;
uint32_t duration = 0;
// 1. 检测引导码
while(DL_GPIO_readPins(GPIOA, DL_GPIO_PIN_9) == 1); // 等待高电平结束
start_time = get_timestamp();
while(DL_GPIO_readPins(GPIOA, DL_GPIO_PIN_9) == 0); // 等待低电平结束
duration = get_timestamp() - start_time;
// 检查引导码低电平部分是否符合要求(转换为毫秒)
if(duration < (LEADER_HIGH/1000 - TOLERANCE/1000) || duration > (LEADER_HIGH/1000 + TOLERANCE/1000))
return 0xFF;
// 2. 检测引导码高电平部分
start_time = get_timestamp();
while(DL_GPIO_readPins(GPIOA, DL_GPIO_PIN_9) == 1);
duration = get_timestamp() - start_time;
if(duration < (LEADER_LOW/1000 - TOLERANCE/1000) || duration > (LEADER_LOW/1000 + TOLERANCE/1000))
return 0xFF;
// 3. 接收8位数据
for(int i = 0; i < 8; i++)
{
start_time = get_timestamp();
while(DL_GPIO_readPins(GPIOA, DL_GPIO_PIN_9) == 0);
duration = get_timestamp() - start_time;
// 检查数据位高电平部分
if(duration < (BIT_HIGH/1000 - TOLERANCE/1000) || duration > (BIT_HIGH/1000 + TOLERANCE/1000))
return 0xFF;
start_time = get_timestamp();
while(DL_GPIO_readPins(GPIOA, DL_GPIO_PIN_9) == 1);
duration = get_timestamp() - start_time;
// 判断逻辑位
if(duration >= (BIT_ONE_LOW/1000 - TOLERANCE/1000) && duration <= (BIT_ONE_LOW/1000 + TOLERANCE/1000))
{
data |= (1 << (7 - i)); // 设置逻辑"1"
}
else if(duration >= (BIT_ZERO_LOW/1000 - TOLERANCE/1000) && duration <= (BIT_ZERO_LOW/1000 + TOLERANCE/1000))
{
// 逻辑"0"不需要设置,默认为0
}
else
{
return 0xFF; // 无效时序
}
}
return data;
}
/******************** 系统初始化 ********************/
void init_system(void)
{
// 添加SysTick初始化(1ms中断)
DL_SYSTICK_config(32000);
// 设置SysTick中断优先级
NVIC_SetPriority(SysTick_IRQn, 3);
DL_GPIO_initDigitalInput(DL_GPIO_PIN_9);
// 设置
NVIC_SetPriority(SysTick_IRQn, 3);
// 启用全局中断
__enable_irq();
// 初始化串口屏
delay_us(2000000); // 等待串口屏启动(2秒)
tjc_change_page(TJC_PAGE_MAIN);
tjc_set_text(TJC_TEXT_STATUS, "等待红外信号");
tjc_set_text(TJC_TEXT_TIME, "系统启动完成");
tjc_send_cmd("vis b0,1"); // 显示复位按钮
}
/******************** 主业务逻辑 ********************/
void security_fsm(void)
{
// 1. 检测锁定状态
if(retry_count >= MAX_RETRY) {
if(get_timestamp() - last_fail_time < LOCK_TIME)
{
tjc_set_text(TJC_TEXT_STATUS, "锁定中,请稍候");
return;
}
retry_count = 0;
}
// 2. 尝试接收数据包
uint8_t rx_code = ir_receive_packet();
if(rx_code == 0xFF)
{
tjc_set_text(TJC_TEXT_STATUS, "信号接收失败");
tjc_beep(200);
return;
}
// 3. 动态解码验证
if(validate_dynamic_code(rx_code))
{
tjc_set_text(TJC_TEXT_STATUS, "认证成功");
tjc_beep(100);
delay_us(50000); // 50ms延迟
tjc_beep(100);
retry_count = 0;
}
else
{
char msg[30];
snprintf(msg, sizeof(msg), "失败(剩余%d次)", MAX_RETRY - retry_count - 1);
tjc_set_text(TJC_TEXT_STATUS, msg);
tjc_beep(500);
retry_count++;
last_fail_time = get_timestamp();
}
}
/******************** 主函数 ********************/
int main(void)
{ // 系统初始化 - 必须先调用
SYSCFG_DL_init();
// 初始化系统
init_system();
//rx_code =ir_receive_packet();
// 清除中断标志
NVIC_ClearPendingIRQ(UART_0_INST_INT_IRQN);
NVIC_EnableIRQ(UART_0_INST_INT_IRQN);
char str[50];
uint32_t last_time = 0;
uint32_t counter = 0;
uint8_t rx_code ;
// 添加调试信息
#ifdef DEBUG
printf("SystemCoreClock: %lu Hz\n", SystemCoreClock);
printf("SysTick LOAD: 0x%08lX\n", SysTick->LOAD);
printf("SysTick CTRL: 0x%08lX\n", SysTick->CTRL);
#endif
while(1)
{
// 每秒更新显示
if(now_time - last_time >= 1000)
{
last_time = now_time;
counter++;
// 更新显示内容
snprintf(str, sizeof(str), "t1.txt=\"运行: %d秒\"", counter);
tjc_send_cmd(str);
}
// 红外信号检测
security_fsm();
// 低功耗等待
__WFI();
}
}同样原因