呵呵哥 发表于 2024-6-30 20:04:08

红外发射求助

#ifndef STC8_H
#define STC8_H
#include <STC8G.H>
#endif
#include<intrins.h>

#include "Timer0.h"
//以12MHZ烧录
void Delay3000ms(void)        //@11.0592MHz
{
        unsigned char data i, j, k;

        _nop_();
        i = 169;
        j = 80;
        k = 87;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}





void main()
{
          P5M0 |= 0x10; P5M1 &= ~0x10;
                        Timer0_Init();
                        P54 = 0;
                        while(1)
                        {
                       
                                SendCode(0xfc,0xAf);//1111 1100 0110 1001
                                Delay3000ms();
                        }
}#ifndef STC8_H
#define STC8_H
#include <STC8G.H>
#endif

bit OP=0;                                   //红外发射管的亮灭控制位
unsigned int count =0;                //载波发射时间
unsigned int Lcount =0;        //发射载波后,等待的时间

void Timer0_Init(void)                //26微秒@12.000MHz
{
        AUXR &= 0x7F;                        //定时器时钟12T模式
        TMOD &= 0xF0;                        //设置定时器模式
        TL0 = 0xE6;                                //设置定时初始值
        TH0 = 0xFF;                                //设置定时初始值
        TF0 = 0;                                //清除TF0标志
        TR0 = 1;                                //定时器0开始计时
        ET0 = 1;
        EA = 1;
}
void SendSingleCode(unsigned char _code)
{
        while (Lcount>0);//直到当前不在发射数据
        switch (_code)
        {
        case 0://560/26=21.6,560/26=21.6
                count = 22;
                Lcount = 22;
                break;
       
        case 1://560/26=21.6,1690/26=65
                count = 22;
                Lcount = 65;
                break;

        case 2://引导码9000/26=346,4500/26=173
                count = 346;
                Lcount = 173;
                break;
        case 3://重复码 9000/26=346,2250/26=86.5
                count = 346;
                Lcount = 87;       
                break;
        case 4://最后一位时,需要给个短暂的高电平,让接收端识别出最后一位的时间
                count = 10;
                break;
        case 5://最后保持一定时间的低电平,用于重复码过短的问题
                Lcount = 3800;
                break;
        }
}
void SendStart()
{
        SendSingleCode(2);
}

void SendRepeat()
{
        SendSingleCode(3);
        SendSingleCode(4);//短暂的高电平
        SendSingleCode(5);//长时间的低电平
}

<font color="#ff8c00">void test()
{
        SendStart();
        SendSingleCode(0);
        SendSingleCode(0);
        SendSingleCode(0);
        SendSingleCode(0);
        SendSingleCode(1);
        SendSingleCode(1);
        SendSingleCode(1);
        SendSingleCode(1);
       
        SendSingleCode(1);
        SendSingleCode(1);
        SendSingleCode(1);
        SendSingleCode(1);
        SendSingleCode(0);
        SendSingleCode(0);
        SendSingleCode(0);
        SendSingleCode(0);
       
        SendSingleCode(0);
        SendSingleCode(0);
        SendSingleCode(0);
        SendSingleCode(0);
        SendSingleCode(1);
        SendSingleCode(1);
        SendSingleCode(1);
        SendSingleCode(1);
       
        SendSingleCode(1);
        SendSingleCode(1);
        SendSingleCode(1);
        SendSingleCode(1);
        SendSingleCode(0);
        SendSingleCode(0);
        SendSingleCode(0);
        SendSingleCode(0);
       
        SendSingleCode(4);//短暂的高电平
        SendSingleCode(5);//长时间的低电平
}</font>

<font color="#ff0000">void SendCode(unsigned char _address,unsigned char _command)//地址码,命令码
{
        unsigned char temp ,i;
        SendStart();
       
        for (i = 0; i < 8; i++)
        {
                temp = _address>>i;
                temp &= 0x01;
                SendSingleCode(temp);
        }

                for (i = 0; i < 8; i++)
        {

                temp = _address>>i;
                temp &= 0x01;
                temp = ~temp;
                SendSingleCode(temp);
        }

                for (i = 0; i < 8; i++)
        {

                temp = _command>>i;
                temp &= 0x01;
                SendSingleCode(temp);
        }

                for (i = 0; i < 8; i++)
        {

                temp = _command>>i;
                temp &= 0x01;
                temp = ~temp;
                SendSingleCode(temp);
        }
       
        SendSingleCode(4);//短暂的高电平
        SendSingleCode(5);//长时间的低电平

       
}</font>



void timeint(void) interrupt 1
{
       
       
        if (count>0)         //如果是待发送的有效数据flag=1,就在此产生载波(亮灭交变)
        {
                OP=~OP;
                count--;                                                
        }
        else
        {
                OP = 0;               //发送低电平
                if (Lcount>0)
                {
                        Lcount--;
                }
               
        }
       
       P54 = OP;           //往发射模块的 IO口发送出去
}
问题挺奇怪的,看我代码标红的部分,我用了4个for循环分别发送地址码,地址反码,命令码,命令反码

发送的地址码和命令码分别是0xfc,0xAf
但是接收端只能收到16位数据,正常应该是32位啊,而且正好是反码没有
我又写了个test(),一位一位的发,不用for循环,又正常了
所以我想知道是不是什么导致for循环出问题了

呵呵哥 发表于 2024-6-30 20:46:11

试了下把SendCode里的四个for循环换成了:
i=0;
temp = _address>>i;
temp &= 0x01;
SendSingleCode(temp);
i++;
...
这样一行一行写,就又是正常了{:sweat:}

呵呵哥 发表于 2024-6-30 21:04:53

最终把代码改成这个了,虽然正常收发了,但是还是不知道原因是什么,难道是不能在for循环里取反?{:sweat:}
void SendCode(unsigned char _address,unsigned char _command)//地址码,命令码
{
        unsigned char temp ,i;
        SendStart();
       
        for (i = 0; i < 8; i++)
        {
                temp = _address>>i;
                temp &= 0x01;
                if(temp)
                {
                        SendSingleCode(1);
                }
                else
                {
                        SendSingleCode(0);
                }
        }

                for (i = 0; i < 8; i++)
        {

                temp = _address>>i;
                temp &= 0x01;
                if(!temp)
                {
                        SendSingleCode(1);
                }
                else
                {
                        SendSingleCode(0);
                }
        }

                for (i = 0; i < 8; i++)
        {

                temp = _command>>i;
                temp &= 0x01;
                if(temp)
                {
                        SendSingleCode(1);
                }
                else
                {
                        SendSingleCode(0);
                }
        }

                for (i = 0; i < 8; i++)
        {

                temp = _command>>i;
                temp &= 0x01;
                if(!temp)
                {
                        SendSingleCode(1);
                }
                else
                {
                        SendSingleCode(0);
                }
        }
       
        SendSingleCode(4);//短暂的高电平
        SendSingleCode(5);//长时间的低电平

       
}

呵呵哥 发表于 2024-6-30 21:23:09

wnagming 发表于 2024-6-30 21:13
你用11.0592M,程序执行时间与定时器中断时间刚好契合,也就是程序中要发送下一位了,定时器刚好把上一位的 ...

你这应该涉及底层机器语言执行了吧,我对这不怎么熟
你的意思是定时器把for给打断了之后,当前的for被放弃了,然后执行下一个for?
页: [1]
查看完整版本: 红外发射求助