优享家 发表于 2014-7-20 21:41:11

51单片机串口转红外接收数据异常

本帖最后由 优享家 于 2014-7-20 21:47 编辑

芯片采用的是STC15
1、串口转红外发射程序:管脚为P3.1

//波特率为1200bps 22.184MHz 用于红外
        PCON &= 0x7F;                //波特率不倍速
        SCON = 0x50;                //8位数据,可变波特率
        AUXR |= 0x40;                //定时器1时钟为Fosc,即1T
        AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
        TMOD &= 0x0F;                //设定定时器1为16位自动重装方式
        TL1 = 0x00;                //设定定时初值
        TH1 = 0xEE;                //设定定时初值
        ET1 = 0;                //禁止定时器1中断
        TR1 = 1;                //启动定时器1

//串口发送数据
void SendChar(uchar n)
{
                ES = 0;       //发送时关中断
                CR = 1;       // 38K调制中断       
                     SBUF = ~n;      //采用的NPN型,此处要取反操作
              while (!TI);//发送数据
              TI=0;
                while(P36 == 0);
                CR = 0;       // 38K调制中断
                ES = 1;

}

//38K调制管脚为P3.6
#define        T38KHZ                                                (uint)(FOSC/(4 * 38000) + 0.5)//四舍五入
void IR_Modulate_Init(void)
{
        CMOD = 0x02;       //设置PCA时钟源为SYSclk / 2
        CCON = 0;                        //初始化PCA寄存器,PCA寄存器停止、清除CF标记、清除模块中断标志
        CL = 0;                                //复位PCA寄存器
        CH = 0;                                //复位PCA寄存器
        IR_Modulate_Value = T38KHZ;       
        CCAP1L =IR_Modulate_Value;          //低8位
        CCAP1H =IR_Modulate_Value >> 8; //高8位
        IR_Modulate_Value += T38KHZ;
        IP=0X80;                //设置为最高优先级
        AUXR1 = 0x10;        //        CCP调整为管脚P3.6,发送38K脉冲
        CCAPM1 = 0X4D;//
        CR = 0;                               
}

voidPCA_isr() interrupt 7 using 2
{
        CCF1 = 0;
        CCAP1L =IR_Modulate_Value;          //低8位
        CCAP1H =IR_Modulate_Value >> 8; //高8位
        IR_Modulate_Value += T38KHZ;
//                SendChar('0');       
}

//串口调制发送的数据:
                SendStr("12345");
                Delay(60000);
                SendChar('1');
2、用红外发送,接收头接收,接收头接收数据用串口转TTL工具直接接收至电脑,采集到如下数据
发送的数据为ASCII 123451,但是接收的数据存在多种 且看起来没有规律
发送31 32 33 34 35 31
         1   23   4   5   1
接收(波特率一致)
        21 19 86 63 F3 CC
        31 19 06 1A CD CC
        21 19 86 63 F3 CC
        0C 19 46 63 C3 CC
        21 19 46 63 E3 21
        21 19 86 63 E3 63
        8C C6 46 63 F3 CC
        21 19 46 63 F3 8C
        63 19 46 C3 F3 0C
转成二进制
发送001100010011001000110011001101000011010100110001
接收001000010001100110000110011000111111001111001100
        001100010001100100000110000110101100110111001100
        001000010001100110000110011000111111001111001100
        000011000001100101000110011000111100001111001100
        001000010001100101000110011000111110001100100001
        001000010001100110000110011000111110001101100011
        100011001100011001000110011000111111001111001100
        001000010001100101000110011000111111001110001100
        011000110001100101000110110000111111001100001100


3、已经排查的问题:
1)、38K调制波形,用示波器测量P3.6调制管脚的波形为26.2us波形是正确的
2)、单片机的串口信息直接用串口转TTL工具接电脑,接收的串口信息是正确的
3)、已经可以正常收发,那硬件电路应该是没有问题的

4、问题是:
1)为何会出现一样的发送信息,为何波特率一致情况下会存在多种接收
2)接收头是否有特殊的频率,我更改了下频率比如38k改为38.4K效果类似
3)是否还有其他问题没有被我考虑到


注:搭建的硬件电路暂时只有一个红外发送二极管

孤独飞行 发表于 2014-7-21 08:37:11

串口直接红外发送,错码肯定很高~

zxd08 发表于 2014-7-21 09:07:32

串口的码,不合适用来做红外的码

优享家 发表于 2014-7-21 10:27:16

孤独飞行 发表于 2014-7-21 08:37
串口直接红外发送,错码肯定很高~

为什么不行呢?在软件上有无一些可以优化的地方
链接是现有的方案
http://item.taobao.com/item.htm?spm=a230r.1.14.23.aN4CZH&id=21298903771&ns=1&_u=l51n4g92222#detail

优享家 发表于 2014-7-21 10:44:37

zxd08 发表于 2014-7-21 09:07
串口的码,不合适用来做红外的码

为什么不行呢?在软件上有无一些可以优化的地方
链接是现有的方案
http://item.taobao.com/item.htm?spm=a230r.1.14.23.aN4CZH&id=21298903771&ns=1&_u=l51n4g92222#detail

lcw_swust 发表于 2014-7-21 11:03:24

楼主的发射电路是高电平有效,但是TXD在空闲时为高电平,所以不对。
建议Q4Q5换作8550,与R4交换位置。

孤独飞行 发表于 2014-7-21 11:17:00

给你上个NEC的红外编码做参考

优享家 发表于 2014-7-21 15:30:00

本帖最后由 优享家 于 2014-7-21 15:33 编辑

lcw_swust 发表于 2014-7-21 11:03
楼主的发射电路是高电平有效,但是TXD在空闲时为高电平,所以不对。
建议Q4Q5换作8550,与R4交换位置。 ...

void SendChar(uchar n)
{
                ES = 0;         //发送时关中断
                CR = 1;         // 38K调制中断      
                     SBUF = ~n;      //采用的NPN型,此处要取反操作
                while (!TI);//发送数据
                TI=0;
                while(P36 == 0);
                CR = 0;         // 38K调制中断
                ES = 1;

}

这个已经取反而且发送完成后也关了调制

优享家 发表于 2014-7-21 15:31:29

孤独飞行 发表于 2014-7-21 11:17
给你上个NEC的红外编码做参考

也就是说用串口通信本身来说存在很多不稳定情况,所以NEC采用时间间隔来区分

优享家 发表于 2014-7-21 15:46:34

孤独飞行 发表于 2014-7-21 11:17
给你上个NEC的红外编码做参考

但这样就不能使用串口来发送数据,串口的bps是定的,无法调整,不然接收和发送就不一致了

lcw_swust 发表于 2014-7-21 16:10:32

优享家 发表于 2014-7-21 15:30
void SendChar(uchar n)
{
                ES = 0;         //发送时关中断


这里取反没用,串口启始位为0,停止位是1,不受SBUF控制。

优享家 发表于 2014-7-21 16:35:19

lcw_swust 发表于 2014-7-21 16:10
这里取反没用,串口启始位为0,停止位是1,不受SBUF控制。

但是我关掉了P3638K调制
                while(P36 == 0);
                CR = 0;         // 38K调制中断

lcw_swust 发表于 2014-7-21 16:59:04

优享家 发表于 2014-7-21 16:35
但是我关掉了P3638K调制
                while(P36 == 0);
                CR = 0;         // 38K调 ...

在关调制前,1位起始位+8位数据位+0.5位停止位已经发出去了。
由于起始位是低电平,红外LED不发光,接收端为高电平,接收端不认为这是起始位,
可能后面的数据成了起始位,所以无法保证数据的正确性.

优享家 发表于 2014-7-21 21:24:33

lcw_swust 发表于 2014-7-21 16:59
在关调制前,1位起始位+8位数据位+0.5位停止位已经发出去了。
由于起始位是低电平,红外LED不发光,接收端 ...

非常感谢,按你说的确实解决了问题

zxd08 发表于 2014-7-22 09:37:46

优享家 发表于 2014-7-21 10:44
为什么不行呢?在软件上有无一些可以优化的地方
链接是现有的方案
http://item.taobao.com/item.htm?spm= ...

可能是有中转的,把串口码转成红外码发出去,再把红外码转成串口码

优享家 发表于 2014-7-22 20:25:38

zxd08 发表于 2014-7-22 09:37
可能是有中转的,把串口码转成红外码发出去,再把红外码转成串口码

已经解决,见楼上,谢谢各位
页: [1]
查看完整版本: 51单片机串口转红外接收数据异常