打印

用三星单片机S3F9454做的一个遥控开关的源代码

[复制链接]
4699|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
比尔熊|  楼主 | 2008-11-28 13:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include <ioS3C9454.h>

#define uchar unsigned char
#define uint  unsigned int

#define NOP asm("NOP")
#define DI  asm("DI")
#define EI  asm("EI")

#define SET_LED (P0 |= 0x01)
#define CLR_LED (P0 &= ~0x01)
#define COM_LED (P0 ^= 0x01)
#define SET_SCR (P0 |= 0x04)
#define CLR_SCR (P0 &= ~0x04)
#define COM_SCR (P0 ^= 0x04)
#define GET_SCR (P0 & 0x04)
#define GET_IR  (P0 & 0x02)
#define SET_BUZZER (P2 |= 0x01)
#define COM_BUZZER (P2 ^= 0x01)

#define IR_USER_CODE 0x00
#define IR_POWER     0x7C
#define IR_Vol_Add   0x16
#define IR_Vol_Dec   0x02
#define IR_RIGHT     0x0F
#define IR_LEFT      0x0E
#define IR_UP        0x5B
#define IR_DOWN      0x53

__root const uchar smartOption[4] @ 0x003C ={0x00,0x00,0xE4,0x00};

uchar remBuffer[4];
uchar irFlag;
uint timeCount;

void InitSfr(void)
{
 BTCON = 0x02;
 CLKCON = 0x18;
 P0CONH = 0xAA;
 P0CONL = 0xA6;
 P0PND = 0x00;
 P1CON = 0x0A;
 P2CONH = 0x4A;
 P2CONL = 0xAA;
 P0 = 0x00;
 P2 = 0x00;
 SET_SCR;
 SET_LED;
 SET_BUZZER;
 irFlag = 0;
 timeCount = 0;
}

void DelayMs(uchar ms)
{
    uchar i,j;
    for(i = 0; i < ms; i++)
    {
        for(j = 0; j < 250; j++)
        NOP;
    }
}

void SendDat(uchar byte)
{
  uchar i;
  for(i = 0; i < 8; i++)
  {
    CLR_LED;
    if(byte & 0x80)
    DelayMs(1);
    else
    DelayMs(3);
    SET_LED;
    byte <<= 1;
    DelayMs(1);
  }
}

void BuzzerOut(uint time)
{
  uint j;
  uchar i;
  for(j = 0; j < time; j++)
  {
    BTCON = 0x02;
    for(i = 0; i < 16; i++)
    {
      NOP;
    }
    COM_BUZZER;
  }
}

void main()
{
  DI;
  InitSfr();
  DelayMs(100);
  T0DATA = 250;//定时器初始值
  T0CON = 0xC8;//打开定时器 1/8之一分频
  P0PND = 0x08;
  BuzzerOut(3000);
  CLR_LED;
  EI;
  while(1)
  {
    BTCON = 0x02;
    P0CONL = 0xA6;
    SET_BUZZER;
    if(irFlag)
    {
      if(remBuffer[0] == IR_USER_CODE)
      {
        if(remBuffer[2] == IR_POWER)
        {
          COM_SCR;
          if(GET_SCR == 0)
          {
            BuzzerOut(1000);
            SET_LED;
          }
          else
          {
            BuzzerOut(2000);
            CLR_LED;
          }
        }
      }
      //SendDat(remBuffer[2]);
      irFlag = 0;
      P0PND = 0x08;
    }
    if(GET_SCR)
    {
      timeCount++;
      if(timeCount >= 55000)
      {
        timeCount = 0;
        SET_LED;
        DelayMs(50);
        CLR_LED;
      }
    }
  }
}
#pragma vector = 0x00
__interrupt void Interrupts(void)
{
  uchar count;
  uchar i,j;
  if(P0PND & 0x04)
  {
    P0PND = 0x00;
    for(count = 0;count < 160; count++)
    {
      T0CON = 0xC8;
      do
      NOP;
      while(T0CNT < 150);
      if(GET_IR)
      {
        P0PND = 0x08;
        return;
      }
    }
    
    while(GET_IR == 0);
    
    for(count = 0;count < 80;count++)
    {
      T0CON = 0xC8;
      do
      NOP;
      while(T0CNT < 150);
      if(GET_IR == 0)
      {
        P0PND = 0x08;
        return;
      }
    }
    
    while(GET_IR);
    
    for(j=0;j<4;j++)
    {
      for(i=0;i<8;i++)
      {
        while(GET_IR == 0);
        for(count = 0; count < 18; count++)
        {
          T0CON = 0xC8;
          do
          NOP;
          while(T0CNT < 150);
        }
        remBuffer[j] >>= 1;
        if(GET_IR)
        {
          remBuffer[j] |= 0x80;
          for(count = 0; count < 32; count++)
          {
            T0CON = 0xC8;
            do
            NOP;
            while(T0CNT < 150);
          }
          
        }
      }
    }
    irFlag = 1;
  }
}

测试100%通过,请大家放心试用!

相关帖子

沙发
程序匠人| | 2008-11-28 14:08 | 只看该作者

送裤子一条,如果有原理图,再送一条

使用特权

评论回复
板凳
古道热肠| | 2008-11-28 14:29 | 只看该作者

哈哈,这个网名有意思

Bear熊(贝尔熊),俺家小子看的<右脑开发宝典>中的主角.

使用特权

评论回复
地板
keyanfeng| | 2008-11-28 17:06 | 只看该作者

关于RF的编码

开始的时候我是用中断产生定时间隔来做的.
也是用9454.
这种方法不是很准确,
330us的高电平,有时候只有300us,
现在换成,发射编码时,先关中断,
再调用延时函数,处理产生时序.

楼主的DelayMs(1) 好像延时不是1ms,
你的晶振是多少?

void DelayMs(uchar ms)
{
    uchar i,j;
    for(i = 0; i < ms; i++)
    {
        for(j = 0; j < 250; j++)
        NOP;
    }
}

IAR的汇编如下,
代码中级优化.

DelayMs:
    0111    B0CE        CLR      R14
    0113    8B0B        JR       T, 0x0120
        NOP;
    0115    FF          NOP     
        for(j = 0; j < 250; j++)
    0116    DE          INC      R13
        for(j = 0; j < 250; j++)
    0117    56DFFC      AND      0xDF, #0xFC
    011A    A6CDFA      CP       R13, #0xFA
    011D    7BF6        JR       C, 0x0115
    for(i = 0; i < ms; i++)
    011F    EE          INC      R14
    for(i = 0; i < ms; i++)
    0120    A2EF        CP       R14, R15
    0122    FB04        JR       NC, 0x0128
        for(j = 0; j < 250; j++)
    0124    B0CD        CLR      R13
    0126    8BEF        JR       T, 0x0117
}
    0128    AF          RET     
    0129    FF          NOP     
?C_EXIT:
exit:
    012A    FF          NOP     



看我的RF 编码.
/******************************************************************/
// RF send data start
// 12ms idle time,333us start bit,(333+666)us*16 data bit,
//       __    __
//      |  |  |  |
//    __|  |__|  |__
        di();
        RF_out0();
        i = 12;                            // RF idle  12ms
        while(i>0)
        {
            delay_330us();
            delay_330us();
            delay_330us();
            i--;
        }

        RF_out1();                      // RF start bit 330us
        delay_330us();                    // RF_out1
        do
        {
            j = RF_code[RF_byte];
            for(i=0; i<8; i++)
            {
                if(j & 0x80)
                {
                    RF_out0();
                    delay_330us();                // 0
                    RF_out1();
                    delay_330us();              // 1
                    delay_330us();              // 1
                }
                else
                {
                    RF_out0();
                    delay_330us();                // 0
                    delay_330us();              // 0
                    RF_out1();
                    delay_330us();              // 1
                }
                j = j << 1;
            }
            RF_byte++;
        }while(RF_byte < 2);
        RF_out0();
        RF_flag.bit.BIT_RF_EN = 0;
        RF_frame_num++;
        ei();

/******************************************************************/

延时函数

void delay_330us(void)
{
    uchar i;
//    i = 64;
    i = 93;
    while(i > 0)
    {
        i--;
    }
}

IAR的汇编如下,
 i = 93;
delay_330us:
    0B74    FC5D        LD       R15, #0x5D
    0B76    8B02        JR       T, 0x0B7A
  i--;
    0B78    00CF        DEC      R15
 while(i > 0)
    0B7A    42FF        OR       R15, R15
    0B7C    EBFA        JR       NZ, 0x0B78
}
    0B7E    AF          RET     
    0B7F    FF          NOP  


4M晶振,延时为:
1+1.5+ 93*3.5 -1 + 2 + 3.5= 332.5us

使用特权

评论回复
5
awey| | 2008-11-28 18:08 | 只看该作者

这款单片机价格好象很便宜,性价比很高

使用特权

评论回复
6
比尔熊|  楼主 | 2008-11-29 16:29 | 只看该作者

不是很高,而是超高

不是很高,而是超高

使用特权

评论回复
7
比尔熊|  楼主 | 2008-12-1 10:58 | 只看该作者

没人顶的贴就不是好贴

使用特权

评论回复
8
keyanfeng| | 2008-12-1 19:49 | 只看该作者

仿真器贵

在这间公司呆了一年,
OPENice还只能够借别人的来用。

使用特权

评论回复
9
discussant| | 2008-12-10 08:30 | 只看该作者

可以不用仿真器,用烧写器即可

电磁炉上用得很多。

使用特权

评论回复
10
超导体88| | 2008-12-12 09:26 | 只看该作者

大虾好

小弟用9454开发了一个项目,需要用到9454的编程时序资料,不知您能否赐教

使用特权

评论回复
11
j1ason| | 2013-12-13 07:10 | 只看该作者
Mark!!!!!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

20

主题

64

帖子

0

粉丝