durongze 发表于 2025-2-23 12:25:47

ercircle 发表于 2025-2-23 11:51
夸张了,慢慢来呗搞不定了工程贴上来大家一块研究研究




我增加了两个文件Library/ir_air.cLibrary/ir_air.h

其实 Library/ir_air.c 中只有void IrWave(u16 *raw, int rawNum)这个函数是我写的,其他的代码是我从官网的例子里 复制过来的。

从字面意思来看比较简单,就是 用 红外的 脉冲 和 空闲 两个函数把 main.c 中的 rawDataAirOn1 发出去。

然后在 User/Main.c 里面调用了一下。



#include "stdio.h"
#define PRINTF_HID      
//#define PRINTF_SEGLED //printf输出重定向到ISP下载软件中的7段数码管

#include "AI8051U.h"//包含此头文件后,不需要再包含"reg51.h"头文件
#include "usb.h"   //USB调试及复位所需头文件
#include "vk.h"
#include "pic.h"
#include "string.h"
#include "ir_air.h"

#define MAIN_Fosc       24000000L   //定义主时钟

BYTE xdata cod;

char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";                      //设置自动复位到ISP区的用户接口命令

u16 rawDataAirOn1 = {6122, 7424,514, 1674,514, 1674,514, 1676,514, 1674,514, 1674,514, 1676,512, 1676,514, 1674,514, 580,514, 580,514, 580,514, 580,514, 578,514, 580,514, 580,514, 578,514, 1676,514, 1674,514, 1674,514, 1674,514, 1676,512, 1674,514, 1674,514, 1676,514, 578,514, 580,514, 582,512, 582,512, 580,514, 580,514, 580,514, 580,514, 1676,514, 1674,514, 1674,514, 1674,514, 1676,514, 1672,514, 1674,514, 1674,514, 580,512, 580,514, 578,514, 580,512, 582,514, 580,514, 580,514, 580,514, 1674,514, 580,514, 1674,514, 580,514, 580,514, 580,512, 582,514, 1676,512, 580,514, 1674,514, 580,514, 1676,512, 1676,512, 1674,512, 1676,512, 582,514, 580,512, 1676,512, 1676,536, 558,534, 1654,512, 582,536, 1654,534, 1652,534, 1654,536, 558,534, 558,534, 1654,536, 558,534, 1654,534, 558,534, 560,534, 560,536, 1652,534, 562,534, 1652,514, 582,512, 1676,512, 582,512, 582,512, 1674,536, 560,512, 1674,536, 560,512, 1674,512, 584,512, 1676,512, 1678,512, 7408,512};


u16 rawDataAirOn2 = {3410, 1670,408, 1258,410, 1260,408, 424,408, 426,408, 424,410, 1258,408, 426,408, 424,408, 1258,432, 1236,408, 424,430, 1236,408, 426,408, 424,408, 1258,408, 1258,432, 402,408, 1260,408, 1258,408, 426,408, 424,408, 1260,408, 424,408, 424,408, 1258,408, 424,408, 426,430, 404,430, 402,408, 424,408, 426,408, 426,430, 402,408, 426,408, 426,430, 402,430, 402,408, 426,408, 426,408, 426,408, 426,408, 426,430, 1236,430, 404,408, 424,408, 1260,430, 404,408, 424,408, 1260,408, 1260,430, 404,430, 404,430, 402,430, 404,430, 402,430, 402,430, 402,430, 1236,408, 1260,430, 404,430, 402,430, 402,430, 404,430, 404,430, 402,430, 1236,430, 402,430, 1238,430, 1236,430, 1236,430, 404,430, 404,430, 404,430, 402,430, 404,430, 404,430, 404,430, 404,430, 404,430, 404,430, 402,430, 404,430, 402,430, 404,430, 404,430, 404,430, 402,430, 402,430, 404,430, 404,430, 404,406, 426,430, 404,430, 402,428, 404,428, 404,430, 404,430, 404,430, 404,430, 404,428, 404,428, 404,430, 404,430, 404,430, 404,406, 426,430, 1236,430, 1238,430, 1238,430, 1236,408, 1260,430, 404,406};


u16 rawDataAirOn3 = {3492, 1746,458, 1310,462, 372,460, 374,460, 372,460, 1312,460, 396,436, 398,434, 400,436, 1310,460, 398,436, 374,460, 398,434, 1312,460, 398,434, 398,434, 398,434, 1314,458, 398,436, 398,436, 398,436, 1312,460, 372,460, 374,460, 400,434, 1310,460, 400,434, 398,434, 374,460, 1310,460, 398,434, 374,460, 372,460, 1312,460, 372,460, 374,460, 372,460, 1310,462, 370,460, 374,460, 374,460, 374,460, 374,460, 1310,460, 374,460, 374,460, 1312,460, 374,460, 372,460, 1310,460, 1312,460, 372,460, 372,460, 374,460, 372,460, 374,460, 374,460, 374,458, 1312,460, 1310,460, 372,460, 374,460, 372,460, 374,460, 372,460, 374,460, 1312,482, 350,482, 1290,482, 352,482, 350,484, 350,490, 370,462, 372,458, 376,456, 376,458, 376,456, 374,456, 376,458, 376,456, 376,456, 376,456, 376,456, 376,456, 376,456, 376,456, 378,456, 378,456, 378,456, 378,454, 402,430, 402,408, 426,430, 404,408, 426,408, 426,408, 426,408, 426,408, 424,408, 426,430, 378,454, 378,456, 378,456, 376,456, 376,456, 374,458, 376,458, 1314,458, 1314,458, 374,456, 376,458, 376,458, 1314,456};

//P3.2口按键复位所需变量
bit Key_Flag;
u16 Key_cnt;

void sys_init();
void delay_ms(u8 ms);
void KeyResetScan(void);
// PUTCHAR_FUN(){
//         USB_SendData((BYTE*)&c,1);
//         return c;
// }
void main()
{
    sys_init();
    usb_init();
    PWM_config();

    EA = 1;
   
    while (1)
    {
      delay_ms(1);
      KeyResetScan();   //长按P3.2口按键触发软件复位,进入USB下载模式,不需要此功能可删除本行代码

      if(DeviceState != DEVSTATE_CONFIGURED)//判断USB设备是否配置完成
            continue;

      if (bUsbOutReady)
      {
            if ((UsbOutBuffer == 'K') &&
                (UsbOutBuffer == 'E') &&
                (UsbOutBuffer == 'Y') &&
                (UsbOutBuffer == 'P'))
            {
                switch (UsbOutBuffer)
                {
                case VK_DIGIT_0:
                  // printf("00000000");      //在数码管上显示字符串
                  IrWave(rawDataAirOn1, sizeof(rawDataAirOn1) / sizeof(rawDataAirOn1));
                  break;
                case VK_DIGIT_1:
                  // printf("%08lx", 0x1234abcdL);      //在数码管上显示字符串
                  IrWave(rawDataAirOn2, sizeof(rawDataAirOn2) / sizeof(rawDataAirOn2));
                  break;
                case VK_DIGIT_2:
                  // SEG7_ShowLong(0x98765432, 16);   //在数码管上显示4字节长整型数
                  IrWave(rawDataAirOn3, sizeof(rawDataAirOn3) / sizeof(rawDataAirOn3));
                  break;

---------------------------------------------------------------------------------------------------------



durongze 发表于 2025-2-23 12:32:15


void IrWave(u16 *raw, int rawNum)
{
    int i;
    for(i = 0; i < rawNum; i++)
    {
      if (i % 2 == 0) {
            IR_TxPulse(raw/1000*38);    //我简单解释一下为啥要除以1000,这个是把us转成ms,成以38是我发现官网的例子里似乎是把毫秒乘以38才往出发。
      } else {
            IR_TxSpace(raw/1000*38);
      }
    }
}

----------------------------------------------------
下面这段代码是官网给的例子里的,我分析了官网的代码,发现这个接口传的值应该是ms值*38
      if (KeyCode != 0)       //检测到键码
      {
            KeyCode=255;
            TxTime = 0;
            //一帧数据最小长度 = 9 + 4.5 + 0.5625 + 24 * 1.125 + 8 * 2.25 = 59.0625 ms
            //一帧数据最大长度 = 9 + 4.5 + 0.5625 + 8 * 1.125 + 24 * 2.25 = 77.0625 ms
            IR_TxPulse(342);    //对应9ms,同步头       9ms       这里的342 应该就是9 *38 得来的
            IR_TxSpace(171);    //对应4.5ms,同步头间隔 4.5ms这里的171 应该就是4.5*38 得来的
            IR_TxPulse(21);   //开始发送数据          0.5625ms   这里的21 应该就是0.5625*38 得来的

            IR_TxByte(User_code%256);   //发用户码低字节
            IR_TxByte(User_code/256);   //发用户码高字节
            IR_TxByte(KeyCode);         //发数据
            IR_TxByte(~KeyCode);      //发数据反码

            if (TxTime < 56)    //一帧按最大77ms发送, 不够的话,补偿时间   108ms
            {
                TxTime = 56 - TxTime;
                TxTime = TxTime + TxTime / 8;
                delay_ms(TxTime);
            }

            delay_ms(31);

            while (IO_KeyState != 0) //键未释放
            {
                IR_TxPulse(342);    //对应9ms,   同步头      9ms
                IR_TxSpace(86);   //对应2.25ms,同步头间隔    2.25ms
                IR_TxPulse(21);   //开始发送数据            0.5625ms
                delay_ms(96);
                IO_KeyScan();
            }

            printf("User_code=0x%04X,KeyCode=%u\r\n", User_code, KeyCode);
            KeyCode = 0;
      }

ercircle 发表于 2025-2-23 12:58:08

sdcc要在main函数所在文件声明中断中断才生效。和keil的差异点可以参考我这个帖子

【四合一】分享一个可同时编译Keil C251\Keil C51\SDCC\IAR工程模板 - SDCC, IAR C++ for 51, GCC, VSCode,Linux, MacOS 国芯技术交流网站 - AI32位8051交流社区
建议:
业务代码放在sdcc工程,不要放在lib工程,否则每次修改后要重新编译两个工程。
编译前clean缓存:
make clean
make

另外修改了几处可能是bug,你试下




这两行验证不阻塞了:




durongze 发表于 2025-2-23 13:28:40

ercircle 发表于 2025-2-23 12:58
sdcc要在main函数所在文件声明中断中断才生效。和keil的差异点可以参考我这个帖子

【四合一】分享一个可同 ...

官网的例子里有个bug,我也往里面加了两个bug 。{:yinxian:}

1.extern void PWMA_ISR() __interrupt(PWMA_VECTOR);   //这个是我改出来的。
2.tx_cnt--; // 等于0的时候继续--,这个bug是官网原来的。
3.IR_TxPulse(raw/1000.0*38); // 这个除法的大bug 也是我搞出来的。{:hanxiao:}

给我你的心好吗 发表于 2025-3-21 14:04:41

佬们,用 SDCC 编译的话是不是只能编写 8 位指令模式?8 位和 32 位会有什么性能上的优劣嘛?

ercircle 发表于 2025-3-21 14:08:24

给我你的心好吗 发表于 2025-3-21 14:04
佬们,用 SDCC 编译的话是不是只能编写 8 位指令模式?8 位和 32 位会有什么性能上的优劣嘛? ...

是的,32位用keil,当然32位更快

ercircle 发表于 2025-3-22 22:58:38

更新记录:
V20250322:
1.修改hid库发送逻辑bug
2.cdc和hid库代码对齐,usb头文件添加PRINTF_USB宏。

Istar_MCU 发表于 2025-4-18 08:57:36

学习到了,准备实践
页: 1 2 3 4 [5]
查看完整版本: 分享USB_CDC库, USB_HID库, SDCC版, IAR版, @Ai8051U-8Bit