[DemoCode下载] 使用pwm及capture作紅外學習及發送的功能

[复制链接]
 楼主| a_ziliu 发表于 2017-4-6 11:54 | 显示全部楼层 |阅读模式
使用nuc240 nuedu, 作38khz紅外線發射及學習。
NUC230_240 IR LEARN.zip (487.41 KB, 下载次数: 37)
天灵灵地灵灵 发表于 2017-4-6 18:35 | 显示全部楼层
  1. /**************************************************************************//**
  2. * [url=home.php?mod=space&uid=288409]@file[/url]     main.c
  3. * [url=home.php?mod=space&uid=895143]@version[/url]  V1.00
  4. * $Revision: 6 $
  5. * $Date: 15/09/02 11:55a $
  6. * [url=home.php?mod=space&uid=247401]@brief[/url]    NUC200 Series I2S Controller Sample Code
  7. *
  8. * @note
  9. * Copyright (C) 2011 Nuvoton Technology Corp. All rights reserved.
  10. *
  11. ******************************************************************************/
  12. #include <stdio.h>
  13. #include "NUC230_240.h"
  14. #include "NuEdu-Basic01.h"

  15. extern unsigned int cap_buffer[256];
  16. extern unsigned int cap_edge[256];
  17. extern unsigned int cap_count;
  18. unsigned int i,temp;


  19. #define DATA_FLAHSH_OFFSET  0x0001F000

  20. uint32_t SIM_EEPROM_READ(uint32_t address)
  21. {
  22.     uint32_t temp_data;
  23.     temp_data=*((uint32_t*)(address+DATA_FLAHSH_OFFSET));
  24.         return temp_data;
  25. }

  26. void SIM_EEPROM_WRITE(uint32_t address,uint32_t data)
  27. {

  28.            uint32_t i,j;
  29.     uint32_t buffer[512];               
  30.         if((SIM_EEPROM_READ(address)==0xffffffff)|((SIM_EEPROM_READ(address)&data)==data))
  31.         {       
  32.                 FMC_Write(address+DATA_FLAHSH_OFFSET, data);
  33.         }
  34.         else
  35.     {   
  36.          //backup date
  37.          j=0;         
  38.         // printf("0x%x\n\r",DATA_FLAHSH_OFFSET+(address/512)+(512));
  39.          for(i=DATA_FLAHSH_OFFSET+((address/512)*512);i<DATA_FLAHSH_OFFSET+((address/512)*512)+512;i=i+4)
  40.          {
  41.                 //printf("0x%x\n\r",i);
  42.                 //printf("0x%x\n\r",FMC_Read(i));
  43.              buffer[j]=FMC_Read(i);               
  44.              j++;
  45.          }                                 
  46.         //erase page
  47.         FMC_Erase(DATA_FLAHSH_OFFSET+((address/512)*512));              
  48.         buffer[(address%512)/4]=data;
  49.         j=0;
  50.         for(i=DATA_FLAHSH_OFFSET+((address/512)*512);i<DATA_FLAHSH_OFFSET+((address/512)*512)+512;i=i+4)
  51.         {
  52.             FMC_Write(i,buffer[j]);
  53.             j++;
  54.         }
  55.    }
  56. }

  57. /*---------------------------------------------------------------------------------------------------------*/
  58. /*  MAIN function                                                                                          */
  59. /*---------------------------------------------------------------------------------------------------------*/
  60. int main(void)
  61. {
  62. SYS_Init();
  63.         Open_Seven_Segment();
  64.             SYS_UnlockReg();
  65.         FMC_Open();
  66. while(1)
  67. {
  68. if(PC13==0)
  69. {
  70.         Show_Seven_Segment(1,1);
  71.         //clear buffer
  72.         cap_count=0;
  73.         for(i=0;i<256;i++)
  74.         {
  75.         cap_buffer[i]=0;
  76.         cap_edge[i]=1;
  77.         }
  78.         IrDA_NEC_Rx_Init();
  79.   while(PB14==1);       
  80.         Show_Seven_Segment(2,1);
  81.         NVIC_DisableIRQ(PWMB_IRQn);
  82. }
  83.    
  84. if(PE8==0)
  85. {
  86.          Show_Seven_Segment(3,1);
  87.          IrDA_NEC_Tx_Init();
  88.           for(i=0;i<256;i++)
  89.           {
  90.                  if(cap_buffer[i]==0)
  91.                                 goto END;
  92.             if(cap_edge[i]==1)
  93.                         {
  94.                                 CLK_SysTickDelay(cap_buffer[i]);                       
  95.                         }
  96.             else
  97.                         {                       
  98.                   PWM_EnableOutput(PWMB, 0X04);
  99.                         CLK_SysTickDelay(cap_buffer[i]);
  100.                         PWM_DisableOutput(PWMB, 0X04);
  101.                         }

  102.                 }
  103. END:               
  104. Show_Seven_Segment(4,1);
  105.         }
  106.   
  107. if(PC14==0)//write learn data data eeprom
  108. {
  109.          Show_Seven_Segment(5,1);
  110. for(i=0;i<256;i++)
  111.         {

  112.                 SIM_EEPROM_WRITE((i*4),cap_buffer[i]);
  113.                 SIM_EEPROM_WRITE((256*4)+(i*4),cap_edge[i]);
  114.         }
  115.         Show_Seven_Segment(6,1);
  116.        
  117. }

  118. if(PC15==0)  //read learn data data eeprom
  119. {
  120.          Show_Seven_Segment(7,1);
  121. //clear ram buffer
  122.   cap_count=0;
  123.         for(i=0;i<256;i++)
  124.         {
  125.         cap_buffer[i]=0;
  126.         cap_edge[i]=1;
  127.         }
  128.         for(i=0;i<256;i++)
  129.         {
  130.         cap_buffer[i]=SIM_EEPROM_READ((i*4));
  131.         cap_edge[i]=SIM_EEPROM_READ((256*4)+(i*4));
  132.         }
  133.         Show_Seven_Segment(8,1);
  134. }
  135. }
  136. }
天灵灵地灵灵 发表于 2017-4-6 18:39 | 显示全部楼层
7段数码管很好用的。
yiyigirl2014 发表于 2017-4-6 21:39 | 显示全部楼层
38Khz是需要单片机来生成还是那个红外直接就是38Khz
zhuomuniao110 发表于 2017-4-6 22:29 | 显示全部楼层
  1. # include <reg52.h>
  2. # include <intrins.h>
  3. typedef unsigned char uchar;// # define uchar unsinged char
  4. typedef unsigned int  uint; // # define uint  unsinged int

  5. sbit key1 = P3^3;
  6. sbit key2 = P3^4;
  7. sbit key3 = P3^5;
  8. sbit out  = P3^7;
  9. sbit led  = P1^0;

  10. uchar i;//产生38KHZ时用到
  11. //======初始化================================================
  12. void init()
  13. {
  14.         EX0 = 1;//外中断0使能
  15.         IE0 = 0//触发方式 电平
  16.         PX0 = 1;//中断优先级 高
  17.         EA  = 1;//总中断 开
  18.         
  19.         key1 = 1;
  20.         key2 = 1;
  21.         key3 = 1;
  22. }
  23. //======延时==================================================
  24. void delay(uchar a)
  25. {
  26.         uchar b,c;
  27.         for(b = 0; b < a; b++)
  28.                 for(c = 0; c < 200; c++);
  29.                
  30. }
  31. void delayms(uchar a)//延时程序
  32. {
  33.         uchar b;
  34.         for(b = 0; b < a; b++)
  35.         {
  36.                 _nop_(); _nop_(); _nop_(); _nop_();
  37.                 _nop_(); _nop_(); _nop_(); _nop_();
  38.         }
  39. }

  40. //======发送38KHZ程序====频率:38KHZ  周期:26us =================
  41. void _38KHZ(uchar a)//调制脉冲发送时间
  42. {
  43.         //时间自己测试 周期 26us  高低电平各占 13us
  44.         uchar j;
  45.         for(j = 0; j < a; j++)
  46.         {
  47.                 out = !out;
  48.                 i = 7;
  49.                 while( i > 0) i--; //26us  38KHZ
  50.         }
  51.         out = 1;
  52.         
  53. }
  54. /*        延时时间测试值在括号内
  55.         //khz(??);                  //   精确的时间
  56.         //khz(??);                //
  57.         //khz(??);                 //
  58.         //delayms(??);        //   这里是一些时间的介绍
  59.         //delayms(??);        //
  60.         //delayms(??);        //

  61. */
  62. //====================编码数据发送===本程序的关键==============================
  63. void send_data(uchar temp)
  64. {
  65.         uchar num
  66.         _38KHZ(116) //3ms 38khz  这里是发送引导码 开始码
  67.         delayms(125); //2ms
  68.         for(num = 0; num < 8; num++)
  69.         {
  70.                 _38KHZ(40);// 1ms
  71.                 //out = 1;
  72.                 if(temp & 0x01)
  73.                         delay(93)// 1.5ms  上面的1ms+这里的1.5ms 即发送的“1”
  74.                 else
  75.                         delay(65)// 1ms                上面的1ms+这里的1ms 即发送的“0”
  76.                 temp = temp >> 1;//从最低位先发送
  77.         }

  78.         _38KHZ(20); //一字节的数据发送完成后的结束码
  79. }

  80. //====================发送成功状态指示灯=================================
  81. void _38khz_led(void)
  82. {
  83.         uchar k;
  84.         for(k = 0; k < 4; k++)
  85.         {
  86.                 LED0 = !LED0;
  87.                 delay(50);
  88.         }
  89.         LED0 = 1;
  90. }
  91. //====================按键扫描功能程序=================================
  92. void keyscan(void)
  93. {
  94.         if(0 == key1)//按键1
  95.         {
  96.                 _nop_(); _nop_(); _nop_(); _nop_();//延时10us消除按键抖动
  97.                 _nop_(); _nop_(); _nop_(); _nop_();
  98.                 if(0 == key1)
  99.                 {
  100.                         while(!key1);//按下按键后 收放开后开始红外线发射程序
  101.                         send_data(0xf3);//发送数据
  102.                         _38khz_led();        //状态指示

  103.                 }
  104.         }
  105.         
  106.         if(0 == key2)//按键1
  107.         {
  108.                 _nop_(); _nop_(); _nop_(); _nop_();//延时10us消除按键抖动
  109.                 _nop_(); _nop_(); _nop_(); _nop_();
  110.                 if(0 == key2)
  111.                 {
  112.                         while(!key2);//按下按键后 收放开后开始红外线发射程序
  113.                         send_data(0x3f);//发送数据
  114.                         _38khz_led();        //状态指示

  115.                 }
  116.         }
  117.         
  118.         if(0 == key3)//按键1
  119.         {
  120.                 _nop_(); _nop_(); _nop_(); _nop_();//延时10us消除按键抖动
  121.                 _nop_(); _nop_(); _nop_(); _nop_();
  122.                 if(0 == key3)
  123.                 {
  124.                         while(!key3);//按下按键后 收放开后开始红外线发射程序
  125.                         send_data(0xf5);//发送数据
  126.                         _38khz_led();        //状态指示

  127.                 }
  128.         }
  129. }

  130. //====================主程序=================================
  131. void main(void)
  132. {
  133.         init();//初始化
  134.         key1 = 0;
  135.         while(1)
  136.         {
  137.                 keyscan();
  138.         }
  139. }
yiyigirl2014 发表于 2017-4-7 12:32 | 显示全部楼层
不知道跟那个单片机串口的Ir模式是不是一回事。
dongnanxibei 发表于 2017-4-8 12:13 | 显示全部楼层
好像有的单片机带一个红外专用的接口吧?
xixi2017 发表于 2017-4-9 15:32 | 显示全部楼层
红外发射接收原理
遥控器部分:
遥控器部分的工作原理较为简单,主要就是编码IC通过三极管进行放大调变,然后将此电信号(脉冲波)经有红外发射管(940nm波长)转变为光信号发射出去。
现在国产遥控器的电路主要有:455K晶振,编码IC,放大三极管,发射管等主要几个电子原件组成,2节3V电池驱动;但目前一些国际大厂所用的遥控器,其编码IC内已包括了晶振和放大三极管,电路设计更加方便,且只需要1节电池驱动,更加环保。
红外接收部分:
红外接收头内部结构如上图,其主要由光电二极管+红外接收IC组成,工作原理为:光电二极管(俗称接收管)其接收到红外发射管发射出的光信号后转换为电信号(为微安级的电流),此电信号输入到接收IC内部经过放大--增益--滤波--解调变--整形还原后,还原遥控器给出的原始编码,通过接收头信号输出脚输入到后面的代码识别电路
xixi2017 发表于 2017-4-9 15:54 | 显示全部楼层
至于为什么用38KHZ,是因为这样可以提高红外线的抗干扰能力,避免大气中的红外线干扰。原理如下
调制载波频率一般在30khz到60khz之间,大多数使用的是38kHz,占空比1/3的方波,如图2所示,这是由发射端所使用的
455kHz晶振决定的。在发射端要对晶振进行整数分频,分频系数一般取12,所以455kHz÷12≈37.9
kHz≈38kHz。
稳稳の幸福 发表于 2017-4-9 19:20 | 显示全部楼层
for(i=DATA_FLAHSH_OFFSET+((address/512)*512);i<DATA_FLAHSH_OFFSET+((address/512)*512)+512;i=i+4)
这个用的给力。
yiy 发表于 2017-4-10 23:51 | 显示全部楼层
38K 是由单片机产生的吗
xiaohhys8 发表于 2021-4-22 15:10 | 显示全部楼层
好好学习学习!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

100

主题

310

帖子

6

粉丝
快速回复 在线客服 返回列表 返回顶部