完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
使用 arduino 代码无法解码 psoc 4200 中的 RC5 协议
// RC5 协议解码器 Arduino 代码 // 定义定时/计数器 1 的刻度数(预分频器为 1/8) #define short_time 1400 // 用作短脉冲或短空间的最短时间 ( ==> 700 us) #define med_time 2400 // 用作短脉冲或短空间的最长时间 ( ==> 1200 us) #define long_time 4000 // 用作长脉冲或长空间的最长时间 ( ==> 2000 us) // 包括 LCD 库代码 #include // LCD 模块连接(RS、E、D4、D5、D6、D7) 液晶 液晶(3, 4, 5, 6, 7, 8); 字符 文本[3]; 布尔型 rc5_ok = 0, 切换位; 字节 rc5_state = 0, j, 地址, 命令; 无符号 无符号 rc5_code; 无效 设置() { // 设置 LCD 的列数和行数 液晶.开始(16, 2); 液晶.设置光标(0, 0); 液晶.打印("ADS:0x00 TGL: 0"); 液晶.设置光标(0, 1); 液晶.打印("CMD:0x00"); // 定时器 1 模块配置 TCCR1A = 0; TCCR1B = 0; // 禁用定时器 1 模块 TCNT1 = 0; // 将定时/计数器 1 的预加载值设置为 0(复位) TIMSK1 = 1; // 启用定时/计数器 1 溢出中断 attachInterrupt(0, RC5_read, 更改); // 启用外部中断 (INT0) } 无效 RC5_read() { 无符号 int timer_value; 如果(rc5_state != 0){ timer_value = TCNT1; // 存储定时器 1 的值 TCNT1 = 0; // 重置定时器 1 } 开关(rc5_state){ 案例 0 : // 开始接收红外数据(最初处于 mid1 的起始位置) TCNT1 = 0; // 重置定时器 1 TCCR1B = 2; // 使用 1/8 预分频器启用定时/计数器 1 模块(每 1 us 2 ticks) rc5_state = 1; // 下一状态:mid1 结束 j = 0; 返回; 案例 1 : // mid1 的结束 ==> 检查我们是否处于 start1 或 mid0 的开始位置 如果((timer_value > long_time) || (timer_value < 短时间)){ // 无效时间间隔 ==> 停止解码并重置 rc5_state = 0; // 重置解码进程 TCCR1B = 0; // 禁用定时器 1 模块 返回; } 位集(rc5_code, 13 - j); j++; 如果(j > 13){ // 如果收到所有比特 rc5_ok = 1; // 解码过程正常 detachInterrupt(0); // 禁用外部中断 (INT0) 返回; } 如果(timer_value > med_time){ // 我们正处于 0 中期的开始阶段 rc5_state = 2; // 下一状态:Mid0 结束 如果(j == 13){ // 如果我们处于 LSB 位 rc5_ok = 1; // 解码过程正常 比特清除(rc5_code, 0); // 清除 LSB 位 detachInterrupt(0); // 禁用外部中断 (INT0) 返回; } } 否则 // 我们处于 start1 的起始位置 rc5_state = 3; // 下一状态:start1 结束 返回; 案例 2 : // mid0 的结束 ==> 检查我们是否处于 start0 或 mid1 的开始位置 如果((timer_value > long_time) || (timer_value < 短时间)){ rc5_state = 0; // 重置解码进程 TCCR1B = 0; // 禁用定时器 1 模块 返回; } 比特清除(rc5_code, 13 - j); j++; 如果(timer_value > med_time) // 我们在 mid1 开始时 rc5_state = 1; // 下一状态:mid1 结束 否则 // 我们处于起点 0 的起始位置 rc5_state = 4; // 下一状态:start0 结束 返回; 案例 3 : // start1 的结束 ==> 检查我们是否处于 mid1 的开始位置 如果((timer_value > med_time) || (timer_value < 短时间)){ // 时间间隔无效 ==> 停止解码 TCCR1B = 0; // 禁用定时器 1 模块 rc5_state = 0; // 重置解码进程 返回; } 其他 // 我们在 mid1 的开头 rc5_state = 1; // 下一状态:mid1 结束 返回; 案例 4 : // start0 的结束 ==> 检查我们是否处于 mid0 的开始位置 如果((timer_value > med_time) || (timer_value < 短时间)){ // 时间间隔无效 ==> 停止解码 TCCR1B = 0; // 禁用定时器 1 模块 rc5_state = 0; // 重置解码进程 返回; } 其他 // 我们在 0 中段的起点 rc5_state = 2; // 下一状态:Mid0 结束 如果(j == 13){ // 如果我们处于 LSB 位 rc5_ok = 1; // 解码过程正常 比特清除(rc5_code, 0); // 清除 LSB 位 detachInterrupt(0); // 禁用外部中断 (INT0) } } } ISR(TIMER1_OVF_vect) { // 定时/计数器 1 中断服务例程 (ISR) rc5_state = 0; // 重置解码进程 TCCR1B = 0; // 禁用定时器 1 模块 } 无效 loop() { 如果(rc5_ok){ // 如果 mcu 成功接收到 RC5 信息 rc5_ok = 0; // 重置解码过程 rc5_state = 0; TCCR1B = 0; // 禁用定时器 1 模块 切换位 = 比特读取(rc5_code, 11); // 触发位为第 11 位 地址 = (rc5_code >> 6) 0x1F; // 接下来的 5 位是地址 命令 = rc5_code 0x3F; // 6 个 LSB 位为命令位 液晶.设置光标(15, 0); 液晶.打印(toggle_bit); // 显示切换位 sprintf(文本, "%02X", 地址); 液晶.设置光标(6, 0); 液晶.打印(文本); // 以十六进制格式显示地址 sprintf(文本, "%02X", 命令); 液晶.设置光标(6, 1); 液晶.打印(文本); // 以十六进制格式显示命令 attachInterrupt(0, RC5_read, 更改); // 启用外部中断 (INT0) } } |
|
相关推荐
1个回答
|
|
首先,我们需要确保Arduino代码能够正确地接收和解码RC5协议。RC5协议是一种红外遥控协议,它使用不同的脉冲和空间长度来表示数据。在这种情况下,我们已经有了一些基本的定义,如short_time、med_time和long_time,这些定义将用于识别不同的脉冲和空间长度。
接下来,我们将按照以下步骤来处理这个问题: 1. 初始化Arduino和所需的库。 2. 设置输入引脚以接收红外信号。 3. 定义一个函数来检测脉冲和空间长度。 4. 定义一个函数来解析RC5协议的数据。 5. 在主循环中调用这些函数,并在LCD上显示结果。 以下是修改后的Arduino代码: ```cpp #include // 定义定时/计数器 1 的刻度数(预分频器为 1/8) #define short_time 1400 // 用作短脉冲或短空间的最短时间 ( ==> 700 us) #define med_time 2400 // 用作短脉冲或短空间的最长时间 ( ==> 1200 us) #define long_time 4000 // 用作长脉冲或长空间的最长时间 ( ==> 2000 us) // 包括 LCD 库代码 #include // LCD 模块连接(RS、E、D4、D5、D6、D7) LiquidCrystal lcd(3, 4, 5, 6, 7, 8); // 定义IR接收器引脚 int irReceiverPin = 2; // 初始化IRremote库 IRrecv irrecv(irReceiverPin); decode_results results; void setup() { // 初始化LCD lcd.begin(16, 2); // 初始化串行通信 Serial.begin(9600); // 启用IR接收器 irrecv.enableIRIn(); } void loop() { // 检查是否有新的IR信号 if (irrecv.decode(&results)) { // 显示解码结果 displayResults(results); // 重置IR接收器 irrecv.resume(); } } void displayResults(decode_results results) { // 检查协议是否为RC5 if (results.decode_type == RC5) { lcd.clear(); lcd.print("RC5 Code: "); lcd.print(results.value, HEX); } } ``` 在这个代码中,我们使用了IRremote库来接收和解码IR信号。首先,我们初始化了Arduino、LCD和IRremote库。然后,在主循环中,我们检查是否有新的IR信号,如果有,我们调用displayResults函数来解析和显示RC5协议的数据。 注意:确保你已经安装了IRremote库。如果没有,请通过Arduino IDE的库管理器安装它。 |
|
|
|
只有小组成员才能发言,加入小组>>
TLE9879_BLDC电机启动需要用手拨一下才能转动,怎么解决?
5473 浏览 2 评论
4077 浏览 9 评论
请问TLE5012B_E1000 启动后为什么位置不能正确获取
3594 浏览 9 评论
1206 浏览 8 评论
3497 浏览 7 评论
416浏览 2评论
248浏览 2评论
357浏览 2评论
TLE9879_BLDC电机启动需要用手拨一下才能转动,怎么解决?
5494浏览 2评论
如果是打开已有的dave工程,怎么查看这个工程选择的mcu型号?
421浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-26 03:16 , Processed in 1.082023 second(s), Total 80, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号