无需外围38KHZ晶振,STC8H系列芯片按道理都能用,万能接受,万能发射,EEPROM存储数据,暂时只能存一个码,串口输出信息,按下遥控器按键,发送02可显示刚刚收到的信息并保存,发送10可发射刚刚保存的数据,本人新手,程序有些乱,但有注释,因为刚刚做出来所以并不完善,还请大佬多多指教!
红外发射接P11,接受接P20。
原始波形:
经过学以后发射的波形:
单片机源程序如下:
- #include "stc8H.h"
- #include "intrins.h"
- #include <stdio.h>
- #include "uart.h"
- #include "eeprom.h"
- #include "launch.h"
- extern char ch;
- int ir1 = 0x0400;
- unsigned short xdata captures[VAL] = {0},eep_captures[VAL] = {0}; //缓存数组
- static unsigned int num = 0; //一共接受了几个脉冲
- unsigned int two_num;
- static unsigned int Overflow = 0; //溢出次数
- static unsigned char val; //接收超时变量
- void Timer0_Init(void) //1毫秒@24.000MHz,定时器0
- {
- AUXR |= 0x80;
- TMOD &= 0xF0; //设置定时器模式
- // TL0 = 0x90; //设置定时初始值
- // TH0 = 0xE8; //设置定时初始值
-
- TL0 = 0x40; //设置定时初始值
- TH0 = 0xA2; //设置定时初始值
-
- TF0 = 0; //清除TF0标志
- TR0 = 1; //定时器0开始计时
- ET0 = 1;
- }
- void IR() //初始化
- {
- P1M0 = 0x00;
- P1M1 = 0x00;
- P3M0 = 0x00;
- P3M1 = 0x00;
- P5M0 = 0x00;
- P5M1 = 0x00;
- P_SW2 = 0x80;
- PWM1_PS = 0x05;
- //(CC1捕获TI1上升沿,CC2捕获TI1下降沿)
- PWMA_CCER1 = 0x00;
- PWMA_CCMR1 = 0x01; //CC1为输入模式,且映射到TI1FP1上
- PWMA_CCMR2 = 0x02; //CC2为输入模式,且映射到TI1FP2上
- PWMA_CCER1 = 0x11; //使能CC1/CC2上的捕获功能
- PWMA_CCER1 |= 0x00; //设置捕获极性为CC1的上升沿
- PWMA_CCER1 |= 0x20; //设置捕获极性为CC2的下降沿
-
- PWMA_CR1 = 0x01;
-
- PWMA_PSCR = 0x09;
-
- PWMA_IER = 0x04; //使能CC2捕获中断
- PWMA_IER |= 0x02; //使能CC1捕获中断
- EA = 1;
- }
- void PWMA_ISR() interrupt 26 //PWM沿触发中断
- {
- unsigned int cnt_l;
- unsigned int cnt_h;
-
- if (PWMA_SR1 & 0x02)
- {
- PWMA_SR1 &= ~0x02;
- cnt_l = (PWMA_CCR1 - PWMA_CCR2)/24; //差值即为低电平宽度 cnt/时钟频率 = 脉宽(us)
- captures[num++] = cnt_l;
- }
-
-
- if (PWMA_SR1 & 0x04)
- {
- PWMA_SR1 &= ~0x04;
- cnt_h = (PWMA_CCR2 - PWMA_CCR1)/24; //差值即为高电平宽度
- captures[num++] = cnt_h;
- }
- }
- void TM0_Isr() interrupt 1 //定时器0中断用来判断脉冲接受是否超时,大于30ms为超时
- {
- if(P20 == 1)
- {
- val++;
- if(val > 30)
- {
- Overflow = 1;
- val = 0;
- }
- }else {val = 0;Overflow = 0;}
- }
- void UartReceiveHandler() interrupt 4 {
- if (RI) { // 接收中断
- RI = 0; // 清除接收标志位
- ch = SBUF; // 读取接收到的数据
- //UartSend(ch); // 原样返回接收到的数据
- }
- }
-
- void TM3_Isr() interrupt 19 //定时器3中断发生38K载波
- {
- P11 = !P11; //红外1端口
- }
- //---------------------------------------------------------------------------------------------
- void main()
- {
- unsigned int i = 0,a = 0;
-
-
-
- Timer0_Init();
- Timer3_Init();
- UartInit();
- IR();
-
- UartSendString("Starting\r\n");
- lach1 = 1;
- while(1)
- {
- //lach1 = 1;
- if(Overflow == 1 && ch == 0x02)//如果超时溢出,并且接收到0x02
- {
- EraseUIntFromEEPROM(0x0400);
- EraseUIntFromEEPROM(0x0600);
- delays(5);
- EraseUIntFromEEPROM(0x0000);
- delays(5);
- for(i = 0; i <= num; i++)
- {
- SaveUIntToEEPROM(ir1+i*2, captures[i]); //写入eeprom
- //SaveUIntToEEPROM(ir1+i*2, '3'); //写入eeprom
- UartSendUint(captures[i]);//打印保存到数组里的数据
- captures[i] = 0;
- delays(1);
- }
- SaveUIntToEEPROM(0x0000, num); //将脉冲个数写入eeprom
- UartSendString("End\r\n"); /*End结束*/
- UartSendUint(num);
- ir1 = 0x0400;
- ch = 0;
- num = 0;
- Overflow = 0;
- PWMA_IER = 0; //关闭PWM中断使能
- ET0 = 0; //关闭定时器0中断
- }else if(P20 == 0 && Overflow==0){
- PWMA_IER = 0x06; //打开PWM中断使能
- ET0 = 1; //打开定时器0中断
- }
-
-
- if(ch == 0x01)
- {
- two_num = ReadUIntFromEEPROM(0x0000);
- for(a = 0;a<=two_num;a++) //读取红外接收数组
- {
- eep_captures[a] = ReadUIntFromEEPROM(ir1+a*2);
- UartSendUint(eep_captures[a]);//打印保存到数组里的数据
- delays(1);
- }
- UartSendUint(two_num);
- ir1 = 0x0400;
- two_num = 0;
- ch = 0x00;
- }
- if(ch == 0x10)
- {
- two_num = ReadUIntFromEEPROM(0x0000);
- for(a = 0;a<=two_num;a++) //读取红外接收数组
- {
- eep_captures[a] = ReadUIntFromEEPROM(ir1+a*2);
- UartSendUint(eep_captures[a]);//打印保存到数组里的数据
- delays(1);
- }
- Launch_1(eep_captures,two_num);
- ch = 0;
- }
-
- }
- }
- 单片机源程序如下:
- [code]#include "stc8H.h"
- #include "intrins.h"
- #include <stdio.h>
- #include "uart.h"
- #include "eeprom.h"
- #include "launch.h"
- extern char ch;
- int ir1 = 0x0400;
- unsigned short xdata captures[VAL] = {0},eep_captures[VAL] = {0}; //缓存数组
- static unsigned int num = 0; //一共接受了几个脉冲
- unsigned int two_num;
- static unsigned int Overflow = 0; //溢出次数
- static unsigned char val; //接收超时变量
- void Timer0_Init(void) //1毫秒@24.000MHz,定时器0
- {
- AUXR |= 0x80;
- TMOD &= 0xF0; //设置定时器模式
- // TL0 = 0x90; //设置定时初始值
- // TH0 = 0xE8; //设置定时初始值
-
- TL0 = 0x40; //设置定时初始值
- TH0 = 0xA2; //设置定时初始值
-
- TF0 = 0; //清除TF0标志
- TR0 = 1; //定时器0开始计时
- ET0 = 1;
- }
- void IR() //初始化
- {
- P1M0 = 0x00;
- P1M1 = 0x00;
- P3M0 = 0x00;
- P3M1 = 0x00;
- P5M0 = 0x00;
- P5M1 = 0x00;
- P_SW2 = 0x80;
- PWM1_PS = 0x05;
- //(CC1捕获TI1上升沿,CC2捕获TI1下降沿)
- PWMA_CCER1 = 0x00;
- PWMA_CCMR1 = 0x01; //CC1为输入模式,且映射到TI1FP1上
- PWMA_CCMR2 = 0x02; //CC2为输入模式,且映射到TI1FP2上
- PWMA_CCER1 = 0x11; //使能CC1/CC2上的捕获功能
- PWMA_CCER1 |= 0x00; //设置捕获极性为CC1的上升沿
- PWMA_CCER1 |= 0x20; //设置捕获极性为CC2的下降沿
-
- PWMA_CR1 = 0x01;
-
- PWMA_PSCR = 0x09;
-
- PWMA_IER = 0x04; //使能CC2捕获中断
- PWMA_IER |= 0x02; //使能CC1捕获中断
- EA = 1;
- }
- void PWMA_ISR() interrupt 26 //PWM沿触发中断
- {
- unsigned int cnt_l;
- unsigned int cnt_h;
-
- if (PWMA_SR1 & 0x02)
- {
- PWMA_SR1 &= ~0x02;
- cnt_l = (PWMA_CCR1 - PWMA_CCR2)/24; //差值即为低电平宽度 cnt/时钟频率 = 脉宽(us)
- captures[num++] = cnt_l;
- }
-
-
- if (PWMA_SR1 & 0x04)
- {
- PWMA_SR1 &= ~0x04;
- cnt_h = (PWMA_CCR2 - PWMA_CCR1)/24; //差值即为高电平宽度
- captures[num++] = cnt_h;
- }
- }
- void TM0_Isr() interrupt 1 //定时器0中断用来判断脉冲接受是否超时,大于30ms为超时
- {
- if(P20 == 1)
- {
- val++;
- if(val > 30)
- {
- Overflow = 1;
- val = 0;
- }
- }else {val = 0;Overflow = 0;}
- }
- void UartReceiveHandler() interrupt 4 {
- if (RI) { // 接收中断
- RI = 0; // 清除接收标志位
- ch = SBUF; // 读取接收到的数据
- //UartSend(ch); // 原样返回接收到的数据
- }
- }
-
- void TM3_Isr() interrupt 19 //定时器3中断发生38K载波
- {
- P11 = !P11; //红外1端口
- }
- //---------------------------------------------------------------------------------------------
- void main()
- {
- unsigned int i = 0,a = 0;
-
-
-
- Timer0_Init();
- Timer3_Init();
- UartInit();
- IR();
-
- UartSendString("Starting\r\n");
- lach1 = 1;
- while(1)
- {
- //lach1 = 1;
- if(Overflow == 1 && ch == 0x02)//如果超时溢出,并且接收到0x02
- {
- EraseUIntFromEEPROM(0x0400);
- EraseUIntFromEEPROM(0x0600);
- delays(5);
- EraseUIntFromEEPROM(0x0000);
- delays(5);
- for(i = 0; i <= num; i++)
- {
- SaveUIntToEEPROM(ir1+i*2, captures[i]); //写入eeprom
- //SaveUIntToEEPROM(ir1+i*2, '3'); //写入eeprom
- UartSendUint(captures[i]);//打印保存到数组里的数据
- captures[i] = 0;
- delays(1);
- }
- SaveUIntToEEPROM(0x0000, num); //将脉冲个数写入eeprom
- UartSendString("End\r\n"); /*End结束*/
- UartSendUint(num);
- ir1 = 0x0400;
- ch = 0;
- num = 0;
- Overflow = 0;
- PWMA_IER = 0; //关闭PWM中断使能
- ET0 = 0; //关闭定时器0中断
- }else if(P20 == 0 && Overflow==0){
- PWMA_IER = 0x06; //打开PWM中断使能
- ET0 = 1; //打开定时器0中断
- }
-
-
- if(ch == 0x01)
- {
- two_num = ReadUIntFromEEPROM(0x0000);
- for(a = 0;a<=two_num;a++) //读取红外接收数组
- {
- eep_captures[a] = ReadUIntFromEEPROM(ir1+a*2);
- UartSendUint(eep_captures[a]);//打印保存到数组里的数据
- delays(1);
- }
- UartSendUint(two_num);
- ir1 = 0x0400;
- two_num = 0;
- ch = 0x00;
- }
- if(ch == 0x10)
- {
- two_num = ReadUIntFromEEPROM(0x0000);
- for(a = 0;a<=two_num;a++) //读取红外接收数组
- {
- eep_captures[a] = ReadUIntFromEEPROM(ir1+a*2);
- UartSendUint(eep_captures[a]);//打印保存到数组里的数据
- delays(1);
- }
- Launch_1(eep_captures,two_num);
- ch = 0;
- }
-
- }
- }
复制代码
原理图:无
仿真:无
程序:
8路红外.zip
(125.01 KB, 下载次数: 64)
|