数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

搜索
查看: 4374|回复: 9

[C51] 请教stc15w408as PWM分压实现方控功能问题。

[复制链接]
发表于 2020-3-21 23:18:43 | 显示全部楼层 |阅读模式

爱科技、爱创意、爱折腾、爱极致,我们都是技术控

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x
digger63兄用单片机实现方控功能非常好,帖子在老站:http://bbs.mydigit.cn/read.php?tid=1698430

这是我见过改红外遥控的最简洁的方法!奇怪的是,我用stc15w408as,看针脚和201s基本一样,但是isp录入后,红外码都是乱码,测试方控两脚,电流好像没有变化,似乎红外并没有起作用。

我的车机是斯巴鲁力狮6碟,只需要方控正负,测试方控电压为3.20v。取电点为3.40v,接电阻测试电流数据如下:

3.40v下功能电压                 pwm比例
静音 0.04v                           3:255
音量加 0.48-0.45v               36:255
音量减1.04v                        78:255
下一曲 1.85v                       139:255
上一区 2.34-2.32v               1755:2550
模式切换 1.50v                   1125:2550

没有看明白帖子中电阻和电压的关系[s:15] ,我理解只要给方控加上适当的电压就可以实现方控功能,所以在开机状态下量取加功能电阻后的静态电压,不知道这样合适否?pwm比例和取电点有关,还是和方控电压有关?欢迎有研究的大侠指教。
@digger63 @yuanhs
[attachment=21091458][attachment=21091459]

  1. /********************************************************
  2. *  版权所有,仿冒不究
  3. *  卡罗拉松下版遥控程序,适用于STC15W系单片机
  4. *  STC15W201S   IRC频率设定为10MHz
  5. *  15Jun2016 by digger63
  6. *********************************************************/
  7. #define uchar unsigned char
  8. #define uint unsigned int

  9. #define        User_code                0x4CB3                //定义红外接收用户码
  10. #define        power_code                0xDC                //定义开关机红外接收码
  11. #define        LED_code                0x82                //定义按键灯红外接收码
  12. #define        volup_code                0xFF                //定义音量加红外接收码
  13. #define        voldown_code        0x81                //定义音量减红外接收码
  14. #define        up_code                        0x8D                //定义上红外接收码
  15. #define        down_code                0xC1                //定义下红外接收码
  16. #define        mode_code                0xD9                //定义模式红外接收码
  17. #define        mute_code                 0x80                //定义静音红外接收码
  18. #define        seek_code                0x99                //定义前进红外接收码
  19. #define        track_code                0xC1                //定义后退红外接收码

  20. #include <STC15F2K60S2.H>
  21. #include<intrins.h>
  22. #include "IR.H"
  23. sbit sw0=P1^5;        //开关按钮
  24. sbit sw1=P3^3;        //方控1
  25. sbit sw2=P3^2;        //方控2
  26. sbit mcu=P5^5;        //MCU
  27. sbit ACCC=P1^4;        //ACC
  28. sbit LED=P3^6;        //按键灯

  29. void delay(uint t)        //10us()@10MHz
  30. {
  31.         uchar i;
  32.         i = 246;
  33.         do
  34.         {
  35.                 while (--i);
  36.         } while (--t);
  37. }

  38. void PWM(uint m,n)           //m:占空比。n:持续时间,决定短按或长按
  39. {
  40.         uchar l;
  41.         for(;n;n--)
  42.         {
  43.         for(l=0;l<255;l++)         //PWM 周期
  44.         if (l < m){sw1 = 0;}
  45.         else{sw1 = 1;}
  46.         }
  47. }

  48. void main()
  49. {
  50.         P1M0 = 0x10;
  51.         ACCC = 1;
  52.         delay(20000);
  53.         mcu = 0;                        //模拟短按面板 POWER 按钮
  54.         delay(900);
  55.         mcu = 1;               
  56.         LED = 0;
  57.         InitTimer();                //初始化Timer
  58.         PrintString("****** 我的车机红外接收程序 ******\r\n");        //上电后串口发送一条提示信息
  59.     while(1)
  60.           {
  61.                                 if (sw0 == 0){
  62.                                 ACCC = !ACCC;
  63.                                 delay(10000);
  64.                                 mcu = 0;                        //模拟短按面板 POWER 按钮
  65.                                 delay(500);
  66.                                 mcu = 1;               
  67.                                 }
  68.                                 if(B_IR_Press)                //有IR键按下
  69.                                 {
  70.                                         PrintString("红外码: 0x");                        //提示红外键码
  71.                                         Tx1Send(HEX2ASCII(IR_code >> 4));        //键码高半字节
  72.                                         Tx1Send(HEX2ASCII(IR_code));                //键码低半字节
  73.                                         if(B_IrUserErr)                                                //用户码错误,则发送用户码
  74.                                                 {
  75.                                                         Tx1Send(' ');                                        //发空格
  76.                                                         Tx1Send(' ');                                        //发空格
  77.                                                         PrintString("用户码: 0x");                //提示用户码
  78.                                                         Tx1Send(HEX2ASCII(IR_UserH >> 4));        //用户码高字节的高半字节
  79.                                                         Tx1Send(HEX2ASCII(IR_UserH));                //用户码高字节的低半字节
  80.                                                         Tx1Send(HEX2ASCII(IR_UserL >> 4));        //用户码低字节的高半字节
  81.                                                         Tx1Send(HEX2ASCII(IR_UserL));                //用户码低字节的低半字节
  82.                                                 }
  83.                                                 else
  84.                                                 {
  85.                                                 EA  = 0;
  86.                                                 if(IR_code == power_code)
  87.                                                         {
  88.                                                         ACCC = !ACCC;                        
  89.                                                         mcu = 0;                        //模拟短按面板 POWER 按钮
  90.                                                         delay(900);
  91.                                                         mcu = 1;
  92.                                                         }
  93.                                                 if(IR_code == LED_code)                {LED = !LED;}                                       
  94.                                                 if(IR_code == volup_code)        {PWM(3,255);}
  95.                                                 if(IR_code == voldown_code)        {PWM(38,255);}
  96.                                                 if(IR_code == up_code)                {PWM(108,255);}
  97.                                                 if(IR_code == down_code)        {PWM(150,255);}
  98.                                                 if(IR_code == seek_code)        {PWM(220,255);}
  99.                                                 if(IR_code == track_code)        {PWM(180,2550);}
  100.                                                 if(IR_code == mode_code)        {PWM(1760,2550);}        //MODE
  101.                                                 if(IR_code == mute_code)        {PWM(78,255);}        //静音
  102.                                                 EA  = 1;
  103.                                                 }
  104.                                         Tx1Send(0x0d);                //发回车
  105.                                         Tx1Send(0x0a);                //发回车
  106.                                         B_IR_Press = 0;
  107.                                 }
  108.         }
  109. }


  110. /*
  111. Program Size: data=16.5 xdata=0 code=633
  112. creating hex file from "kll"...
  113. "kll" - 0 Error(s), 0 Warning(s).
  114. */
复制代码


发表于 2020-3-23 09:05:42 来自手机浏览器 | 显示全部楼层
没看到初始化串口,红外乱码是串口全部乱码还是只有红外数据乱?全部乱看单片机频率和串口波特率是否正确,遥控数据乱?单个按键每次不同?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-30 21:13:41 | 显示全部楼层
ploestar 发表于 2020-3-23 09:05
没看到初始化串口,红外乱码是串口全部乱码还是只有红外数据乱?全部乱看单片机频率和串口波特率是否正确, ...

谢谢您的回复。现在功能正常了,但是isp串口里还是出现乱码,是全部都有乱码,车机程序上电,自动发一个提示消息,消息本身个别字符有乱码。单片机频率为10mhz,我用内部振晶,偏差0.1%不到,应该没有问题吧。波特率是9600都是固定的呢。

我主要是搞不清楚pwm比例取电压,所取得是不是单片机供电电压?方控1的电压已经是3.20了,串联电压应该等于电压之和,靠pwm如何让方控1取得比如1.04v电压呢?
回复 支持 反对

使用道具 举报

发表于 2020-3-30 23:16:20 来自手机浏览器 | 显示全部楼层
单片机用到串口的时候,最好是11.0592m的频率或翻倍,这样计算出来没有偏差。单片机模拟电压跟方控供电没什么关系了,跟单片机供电(io输出电压)有关,输出的是对地电压,话说pwm模拟dac不用滤波的么?
回复 支持 反对

使用道具 举报

发表于 2020-3-31 00:01:31 来自手机浏览器 | 显示全部楼层
其实把那个周期255改成单片机供电电压的100倍更好,比如3.4v就用340,需要多大电压直接100倍数字,需要1.04就用104输出应该就是1.04v了。其实应该滤波处理,比如占空比50,一个周期内就是一半时间高一半低,(理想)滤波之后拉平,就是电压的一半了。

打赏

参与人数 1家元 +20 收起 理由
家睦 + 20

查看全部打赏

回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-31 15:01:46 | 显示全部楼层
受教了:handshake:。主要是pwm取值问题搞不清楚。我的记忆电压是3.4,例如我的静音功能在接10欧电阻可以实现,在接10欧电阻时测试方控线电压是0.04v,是不是写3:255就可以了?原电路接了270欧电阻,我接了10欧、30欧从1开始测试,都找出来相应功能的pwm值,但是不稳定,晚上正常,早上又不灵了。pwm是如何取值?谢谢您的回复,祝春安。
回复 支持 反对

使用道具 举报

发表于 2020-4-11 22:47:43 | 显示全部楼层
兄弟,电阻和电压的关系请看下图:
因为我的车机方控点已有1200欧姆上拉电阻R1,所以我首先在方控点对地用不同阻值的电阻尝试,找到对应各种功能的阻值及电压,如上图。
下一步确认单片机IO口到方控点的电阻阻值,原则上要比上图中的最小的阻值还要小一点,如图我的是330欧姆,所以我取值270欧姆。
程序中PWW参数的调整我是用的笨办法不断地修改数值,写入再修改再写入,分别找到各个功能的上下限然后取中。
至于你ISP里看串口数据乱码问题,估计要修改程序里的串口参数了。祝你成功。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x

打赏

参与人数 1家元 +20 收起 理由
家睦 + 20

查看全部打赏

回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-4-15 22:18:24 | 显示全部楼层
几天没登录,没想到digger63光临指导,非常感谢。串口乱码始终出现,不过不影响程序使用,车机遥控基本成功,谢谢您的程序。
pwm参数我也是用笨办法,从1开始测试的,好在电视遥控器有几十个按键可用,找到若干功能对应的数值,除了上一曲需要双击(单击是本曲从头开始),其他基本稳定,只是白天稳定的数值,到晚上就稍有变化,估计是灯光等光线影响。所以想是不是有定压能够取得更准确的数值。例如上一曲需要电压1.85v,单片机供电3.4v,pwm值是否应该是1.85/3.40*255=138.7,就写成138:255这样?
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2020-4-16 01:04:14 | 显示全部楼层
digger63 发表于 2020-4-11 22:47
兄弟,电阻和电压的关系请看下图:
因为我的车机方控点已有1200欧姆上拉电阻R1,所以我首先在方控点对地用 ...

终于找到isp输出乱码原因了!
我将主时钟定义为12m,下载设置为11.0592就完美了,可能我的是408as。:biggrin::biggrin::biggrin:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x

打赏

参与人数 1家元 +20 收起 理由
家睦 + 20 認真發帖

查看全部打赏

回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-4-16 01:09:34 | 显示全部楼层
ploestar 发表于 2020-3-23 09:05
没看到初始化串口,红外乱码是串口全部乱码还是只有红外数据乱?全部乱看单片机频率和串口波特率是否正确, ...

红外乱码搞定了,digger63兄写的主时钟是10m,我改为12m,设置为11.0592就可以了,谢谢。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 微信登录

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-7-21 20:14 , Processed in 0.171601 second(s), 11 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

快速回复 返回顶部 返回列表