# 应用示例 ## 红外收发 ### 初始化 IR 寄存器基地址通过设备句柄配置,句柄中还可以配置一些中断回调函数,供中断触发时调用。初始化参数为 \ref GX_HAL_IR_CFG_T,初始化接口为 \ref gx_hal_ir_init。 ```c GX_IR_CFG_T cfg = {0}; memset(&cfg, 0, sizeof(cfg)); cfg.tx_carrier_duty = 30; cfg.tx_carrier_freq = 38000; cfg.std_rx_done_cb = gx_ir_test_recv_std_cb; cfg.std_rx_err_cb = gx_ir_test_recv_std_err_cb; cfg.ud_rx_thr_cb = gx_ir_test_recv_ud_thr_cb; cfg.ud_rx_done_cb = gx_ir_test_recv_ud_cb; cfg.ud_tx_done_cb = gx_ir_test_send_ud_done_cb; cfg.std_tx_done_cb = gx_ir_test_std_tx_done_cb; cfg.ud_rx_full_cb = gx_ir_test_ud_rx_full_cb; cfg.ud_rx_empty_cb = gx_ir_test_ud_rx_empty_cb; cfg.ud_tx_thr_cb = gx_ir_test_ud_tx_thr_cb; cfg.ud_tx_full_cb = gx_ir_test_ud_tx_full_cb; cfg.ud_tx_empty_cb = gx_ir_test_ud_tx_empty_cb; cfg.user_data = &gx_ir_test_ring_buff; gx_ir_init(&hal_cfg); ``` ### 标准协议接收 接收配置参数 \ref GX_HAL_IR_RX_CFG_T,配置接口为 \ref gx_hal_ir_recv_cfg,接收接口为 \ref gx_hal_ir_recv_data_std,不同参数接收的方式参考示例代码中的标准协议接收实现。 ```c GX_HAL_IR_RX_CFG_T rx; uint32_t data = 0; uint8_t type = 0; uint8_t repeat = 0; int ret =0; memset(&rx, 0, sizeof(rx)); rx.rx_thr_start = 0xbff; rx.rx_thr_data = 0xbff; rx.deb_legth = 0x17; rx.demod_legth = 0x07; rx.std_rx_tov = 180*1000; rx.demod_en = 1; rx.invert_en = 1; //翻转电平 rx.deb_en = 1; gx_ir_recv_cfg(&rx, GX_HAL_IR_RECV_STD_MODE, GX_HAL_IR_ON); while(1) { ret = gx_ir_recv_data_std(&rx, (void*)&data, &type, 0); repeat = !!(type & 0x80); type = type & 0x7f; printf("%s(%x),recv type: %s %s, data: %x\r\n", ((ret==0)||(ret==0x10)) ? "Done" : "Error", ret, type == 0 ? "9012" : type == 1 ? "NEC" : type == 2 ? "RC5" : type == 3 ? "RC6" : "unknown", repeat ? "REPEAT" : "", data); //bit0~6, 0:9012,1:NEC,2:RC5,3:RC6; bit7, 1:重复码,0:键值 } ``` ### 标准协议发送 发送配置参数 \ref GX_HAL_IR_TX_CFG_T,接收接口为 \ref gx_hal_ir_send_data_std,不同参数发送的方式参考示例代码中的标准协议发送实现。 ```c void gx_mdelay(unsigned int msec) { uint32_t i = 5000; while (msec--) while(i--); } GX_HAL_IR_TX_CFG_T tx = {0}; uint32_t data[4] = {0x23456789,0xeeff1122,0x1b2b3b4b,0x90441c02}; memset(&tx, 0, sizeof(tx)); tx.type = 1; //NEC 协议类型 tx.modulation_en = 1; //使能调制 tx.data = (void*)data; tx.data_len = 4; gx_ir_send_data_std(&tx, gx_mdelay, 200); return 0; ``` ### 灵活模式接收 灵活模式接收可获取到连续的波形数据,包括波形周期计数和高电平计数,计数乘以分频后的 tick 即为电平时长。接收配置参数 \ref GX_HAL_IR_RX_CFG_T,配置接口为 \ref gx_hal_ir_recv_cfg,接收接口为 \ref gx_hal_ir_recv_data_ud,不同参数接收的方式参考示例代码中的灵活模式接收实现。 ```c GX_HAL_IR_RX_CFG_T rx; uint32_t data[256] = {0}; GX_HAL_IR_UD_DATA_T *ir_ud = (GX_HAL_IR_UD_DATA_T *)data; #define GX_IR_UD_TICK 10 ///< ir clk(12M) / ud_div(120) = 100K, 10 us int ret = 0; memset(&rx, 0, sizeof(rx)); rx.rx_thr_start = 0xbff; rx.rx_thr_data = 0xbff; rx.deb_legth = 0x17; rx.demod_legth = 0x07; rx.ud_rx_tov = 15000; rx.demod_en = 1; rx.invert_en = 1; rx.deb_en = 1; rx.ud_clk_div = 120-1; //100KHz,10 us rx.ud_rxfifo_thr = 0; gx_ir_recv_cfg(&rx); gx_ir_ud_rx_flush(); ret = gx_ir_recv_data_ud(&rx, (void*)data, 256, 0); printf("ret %d,recv data:\r\n", ret); if(ret > 0) { for(int i = 0; i < ret; i++) { printf("%d:data %x, h %d us, l %d us\r\n", i, data[i], ir_ud[i].high_level_cnt*GX_IR_UD_TICK, \ (ir_ud[i].cycle_cnt-ir_ud[i].high_level_cnt)*GX_IR_UD_TICK); } } return ret; ``` ### 灵活模式发送 灵活模式发送连续的波形数据,数据格式为波形的电平和长度,参考 \ref GX_HAL_IR_UD_DATA_T 的定义。发送配置参数 \ref GX_HAL_IR_TX_CFG_T,接收接口为 \ref gx_hal_ir_send_data_ud。 以下为发送 MNEC 协议数据: ```c GX_HAL_IR_TX_CFG_T tx; uint32_t data[64] = {0x04b00320,0x00640032,0x00c80032,0x00c80032,0x00c80032, /* 0111 */ 0x00c80032,0x00640032,0x00640032,0x00c80032, /* 1001 */ 0x00c80032,0x00c80032,0x00640032,0x00640032, /* 1100 */ 0x00640032,0x00640032,0x00640032,0x00640032, /* 0000 */ 0x00c80032,0x00c80032,0x00c80032,0x00c80032, /* 1111 */ 0x00c80032,0x00c80032,0x00640032,0x00640032, /* 1100 */ 0x00c80032,0x00640032,0x00640032,0x00c80032, /* 1001 */ 0x00c80032,0x00c80032,0x00640032,0x00640032, /* 1100 */ 0x00c80032}; memset(&tx, 0, sizeof(tx)); tx.modulation_en = 1; tx.ud_clk_div = 120-1; tx.ud_txfifo_thr = 3; tx.data = (void*)data; tx.data_len = 34; gx_ir_send_data_ud(&tx); ``` ### 中断方式接收标准协议 接收完成触发中断,并获取接收状态。通过回调函数传入接收数据和状态。中断接收启动接口为 \ref gx_hal_ir_recv_std_it_start,回调函数在初始化时配置。 ```c //接收完成回调 int gx_ir_test_recv_std_cb(void* unsigned int data, unsigned char type, unsigned char error) { printf("data:%x, type:%d\r\n", data, type); if(error & GX_HAL_IR_CUSTOM_CODE_ERR) ///< custom code error { printf("custom code error!\r\n"); } if(error & GX_HAL_IR_COMMAND_CODE_ERR) ///< command code error { printf("command code error!\r\n"); } if(error & GX_HAL_IR_PORT_DET_ERR) ///< port_det_err { printf("port_det_error!\r\n"); } return 0; } GX_HAL_IR_RX_CFG_T rx; memset(&rx, 0, sizeof(rx)); rx.rx_thr_start = 0xbff; rx.rx_thr_data = 0xbff; rx.deb_legth = 0x17; rx.demod_legth = 0x07; rx.std_rx_tov = 180*1000; rx.demod_en = 1; rx.invert_en = 1; rx.deb_en = 1; rx.kdc_cmp_en = 1; rx.cc_cmp_en = 1; gx_ir_recv_std_it_start(&rx); return 0; ``` ### 中断方式接收灵活模式数据 通过中断方式接收一串红外数据,红外模块先将波形数据存入 FIFO,接收完成后产生完成中断,然后将数据读出。启动中断接收灵活模式数据接口 \ref gx_hal_ir_recv_ud_it_start,获取接收数据接口 \ref gx_hal_ir_get_ud_recv_data,回调函数在初始化时配置。回调中存入缓存 buffer,buffer 写入参考 \ref gx_ir_test_write_ud_recv_data。 ```c int gx_ir_test_recv_ud_cb(void* ir_dev) { uint32_t val = 0; uint16_t cnt = gx_ir_get_udrx_fifo_count(); while(cnt--) { val = gx_ir_get_udrx_fifo_data(); gx_ir_test_write_ud_recv_data((unsigned int*)&val, 1); } g_ud_rx_done =1; return 0; } /*灵活模式中断接收,通过中断方式接收一串红外数据,红外模块先将波形数据存入 FIFO,接收完成后产生完成中断,然后将数据读出*/ int gx_ir_test_recv_ud_it(void) { GX_HAL_IR_RX_CFG_T rx; uint32_t data[256] = {0}; GX_HAL_IR_UD_DATA_T *ir_ud = (GX_HAL_IR_UD_DATA_T *)data; #define GX_IR_UD_TICK 10 ///< ir clk(8M) / ud_div(80) = 100K, 10 us uint32_t ret =0; memset(&rx, 0, sizeof(rx)); rx.rx_thr_start = 0xbff; rx.rx_thr_data = 0xbff; rx.deb_legth = 0x17; rx.demod_legth = 0x07; rx.ud_rx_tov = 22000; rx.demod_en = 1; rx.invert_en = 1; rx.deb_en = 1; rx.ud_clk_div = 120-1; //100KHz,10 us rx.ud_rxfifo_thr = 2; gx_ir_ud_rx_flush(); gx_ir_recv_ud_it_start(&rx); while (1) { if(g_ud_rx_done == 0) continue; g_ud_rx_done = 0; printf("ud rx done.\r\n"); ret = gx_ir_test_get_ud_recv_data((void*)data, 256); if(ret) { for(int i = 0; i < ret; i++) { printf("%d:data %x, h %d us, l %d us\r\n", i, data[i], ir_ud[i].high_level_cnt*10, \ (ir_ud[i].cycle_cnt-ir_ud[i].high_level_cnt)*10); } } } } ``` ### 中断方式发送灵活模式数据 通过发送灵活模式数据,发送完成后会触发中断,调用回调函数。启动中断发送灵活模式数据接口 \ref gx_hal_ir_send_ud_it_start,停止接口 \ref gx_hal_ir_send_ud_it_stop,回调函数在初始化时配置。 ```c volatile static uint8_t g_ud_tx_done = 0; static uint32_t *g_data; /*!< 异步发送数据指针 */ static uint32_t g_len; /*!< 异步发送数据长度 */ static uint32_t g_count; /*!< 异步发数据计数 */ /*灵活模式发送FIFO到达阈值回调函数*/ int gx_ir_test_ud_tx_thr_cb(void* ir_dev) { int spare = ((GX_HAL_IR *)ir_dev)->tx_fifo_depth -gx_ir_get_udtx_fifo_count(); while((spare > 0) && (g_count < g_len)) { gx_ir_udtx_fifo_put(g_data[g_count]); g_count++; spare--; } printf("tx thr\r\n"); return 0; } /*灵活模式发送FIFO空回调函数*/ int gx_ir_test_ud_tx_empty_cb(void* ir_dev) { if(g_count == g_len) gx_ir_udtx_write_endflag(); printf("tx fifo empty\r\n"); return 0; } /*灵活模式中断发送,带调制*/ int gx_ir_test_send_ud_it(void) { GX_HAL_IR_TX_CFG_T tx; uint32_t data[] = {0x04b00320,0x00640032,0x00c80032,0x00c80032,0x00c80032, /* 0111 */ 0x00c80032,0x00640032,0x00640032,0x00c80032, /* 1001 */ 0x00c80032,0x00c80032,0x00640032,0x00640032, /* 1100 */ 0x00640032,0x00640032,0x00640032,0x00640032, /* 0000 */ 0x00c80032,0x00c80032,0x00c80032,0x00c80032, /* 1111 */ 0x00c80032,0x00c80032,0x00640032,0x00640032, /* 1100 */ 0x00c80032,0x00640032,0x00640032,0x00c80032, /* 1001 */ 0x00c80032,0x00c80032,0x00640032,0x00640032, /* 1100 */ 0x00c80032}; gx_ir_ud_tx_wait_done(); memset(&tx, 0, sizeof(tx)); tx.modulation_en = 1; tx.ud_clk_div = 120-1; tx.ud_txfifo_thr = 3; tx.data = (void*)data; tx.data_len = 34; g_ud_tx_done = 0; g_count = gx_ir_get_udtx_fifo_depth() > tx.data_len ? tx.data_len : gx_ir_get_udtx_fifo_depth(); g_len = tx.data_len; g_data = data; gx_ir_send_ud_it_start(&tx); while(g_ud_tx_done == 0); return 0; } ```