找回密码
 立即注册
查看: 4508|回复: 36

PWM硬件移相测试卡教程(一)按键点灯测试@STC8H2K12U系列

[复制链接]
  • 打卡等级:常住居民III
  • 打卡总天数:135
  • 最近打卡:2024-12-25 10:15:05

47

主题

1350

回帖

8058

积分

荣誉版主

冲哥视频教程和各种开源资料QQ交流群884047237,可群

积分
8058
QQ
发表于 2024-3-6 11:36:40 | 显示全部楼层 |阅读模式

PWM硬件移相测试卡教程(一)按键点灯测试
=== STC8H2K08U, STC8H2K12U, STC8H2K17U
=== 有一个硬件PWM移相功能的PWM,
         做逆变,做变频什么的就舒服多了
=== 串口超时中断,这个超时检测可以轻松的实现类似
          ModBus RTU 协议里的3.5个字符周期的超时等待

截图202403060838422576.jpg
前言:
本章节系列最终的测试板卡如上所示(需要这个板卡的小伙伴可以到文末找到某宝的下单链接自行下载),用的最新的STC8H2K17U单片机,至于为什么选择这个单片机,可以看到宣传页!

截图202403060842595409.jpg
新功能1:他有一个硬件移相功能的PWM,做逆变,做变频什么的就舒服多了
新功能2:和以往的规格相比,还多了个T11的低功耗定时器。
                毕竟定时器这玩意儿可以不用,但是不能没有~
新功能3:以及还有串口超时中断,这个超时检测可以让我们很轻松的实现类似于
                ModBus RTU 协议里的3.5个字符周期的超时等待
新功能4:P10/P11引脚的数字功能可以对调(模拟功能不行)!
                P54可以映射P12的数字功能
              (用过STC的小伙伴会发现带USB的单片机好多没有P12引脚)

一、引脚排布分析
    欲练神功,必先拥有武功秘籍,先附上原理图,这一张主要讲解按键的点灯测试,也是为了测试硬件,毕竟要是硬件有问题的话,后面PWM写的天花乱坠灯一直不亮就尴尬了。


截图202403060852183325.jpg


    这里就可以很轻松的看到P10,P11,P13.P14.P15.P16.P17,P54这八个引脚外接了8个LED。当然我们还可以将P54映射到P12上去(只需要初始化P12,不需要初始化P54引脚),也就是P1整个端口上外接了8个LED。P34-P37上外接了4个按键开关。

    切记,STC新款的初始化之后IO均为高阻输入,必须手动修改为我们需要的模式!!(某宝上很多模块提供的历程都是89c52的,要改成新的单片机的话,绝大多数程序基本就是修改下引脚模式和延时时间即可正常使用)


二、驱动函数编写
这时候我们就可以使用我们的ISP软件来配置IO了(切记一定要使用最新的ISP软件!!一定要使用最新的ISP软件!!一定要使用最新的ISP软件!!
1.LED输出引脚初始化(推挽输出)


截图202403060935342651.jpg

再给他写个函数名称,这个初始化函数就可以配置为这样
  1. void LED_Init(void)
  2. {
  3.     P1M0 = 0xff;
  4.     P1M1 = 0x00;
  5. }
复制代码

2.按键输入初始化(准双向口)
截图202403061102039798.jpg
再给他写个函数名称,这个初始化函数就可以配置为这样
  1. void KEY_Init(void)
  2. {
  3.     P3M0 &= ~0xf0;
  4.     P3M1 &= ~0xf0;
  5. }
复制代码


3.1ms系统时间函数(这里用定时器0实现,毕竟定时器0有不可屏蔽中断)还是用工具直接在线配置即可
截图202403061032467726.jpg
这里直接可以用软件生成如下函数,该说不说,非常的好用
  1. void Timer0_Isr(void) interrupt 1
  2. {
  3. }
  4. void Timer0_Init(void)                //1毫秒@22.1184MHz
  5. {
  6.         AUXR |= 0x80;                        //定时器时钟1T模式
  7.         TMOD &= 0xF0;                        //设置定时器模式
  8.         TL0 = 0x9A;                                //设置定时初始值
  9.         TH0 = 0xA9;                                //设置定时初始值
  10.         TF0 = 0;                                //清除TF0标志
  11.         TR0 = 1;                                //定时器0开始计时
  12.         ET0 = 1;                                //使能定时器0中断
  13. }
复制代码


三、用户程序编写
1.按键检测函数
    总有好多小伙伴问这个按键消抖怎么写,这里就简单的提供一种思路
截图202403061038319674.jpg
    这里所谓的抖动就是如上图那样,没按下的时候是高电平,按下之后马上变低电平,当然这是理想状态,实际因为机械按键会存在抖动的现象, 他会高低电平有一段变化的区间,常规的消抖就是检测到低电平了延时10ms在判断,当然这种相对来说并不可靠,我常用的思路就是,间隔1ms,连续10次检测到低电平即为触发了。即可通过如下代码实现:
  1. u8 KEY_Read(u8 no)
  2. {
  3.     if( no == 0 )
  4.         return KEY1;
  5.     if( no == 1 )
  6.         return KEY2;
  7.     if( no == 2 )
  8.         return KEY3;
  9.     if( no == 3 )
  10.         return KEY4;  
  11.     return 0;   
  12. }
  13. void KEY_Deal(void)                        //检查所有的按键状态 10ms执行一次
  14. {
  15.         u8 i = 0;
  16.         for(i=0;i<KEY_NUM;i++)                                        //循环8次 i的取值范围是0-7  代表了P30-P37的状态查询
  17.         {
  18.                 if( KEY_Read(i)==0 )                        //持续按下,变量+1  
  19.                 {
  20.                         if( Count[i]<60000 )
  21.                                 Count[i] ++;                        //按键按下,这个计数变量+1
  22.                 }
  23.                 else                                                        //按键松开了,变量清0
  24.                 {
  25.                         if( Count[i]>0 )                        //如果这个变量是按下过的
  26.                         {
  27.                                 LastState |= (1<<i);        //这个变量相应的标志位置位
  28.                         }
  29.                         else
  30.                         {
  31.                                 LastState &= ~(1<<i);        //这个变量相应的标志位清0
  32.                         }
  33.                         Count[i] = 0;                                //按键按下,这个计数变量清0
  34.                 }
  35.         }
  36. }
  37. u8 KEY_ReadState(u8 no)        //读取指定的按键的状态 10ms执行一次
  38. {
  39.         if( Count[no]>0 )                                        //按键是按下的各种状态返回
  40.         {
  41.                 if( Count[no]<10 )                                //按下<30ms 返回消抖状态
  42.                 {
  43.                         return KEY_FILCKER;
  44.                 }
  45.                 else if( Count[no]==10 )                        //按下正好30ms 返回单击
  46.                 {
  47.                         return KEY_PRESS;
  48.                 }
  49.                 else if( Count[no]<3000 )                //按下不到3000ms 返回单击结束
  50.                 {
  51.                         return KEY_PRESSOVER;
  52.                 }               
  53.                 else if( Count[no]==3000 )                //按下正好3000ms 返回长按状态
  54.                 {
  55.                         return KEY_LONGPRESS;
  56.                 }
  57.                 else                                                                //长按结束
  58.                 {
  59.                         return KEY_LONGOVER;
  60.                 }                        
  61.                
  62.         }
  63.         else                                                                        //按键已经松开了,返回各种状态
  64.         {
  65.                 if( LastState &( 1<<no ) )                //按键之前按下过
  66.                 {
  67.                         return KEY_RELAX;               
  68.                 }
  69.                 else                                                                //按键之前没有按下
  70.                 {
  71.                         return KEY_NOPRESS;
  72.                 }
  73.         }
  74. }
复制代码

上面的代码看起来好像很长,其实总结下来就很多,如果按钮按下了,数值按1ms自加一次,如果按钮松开了计数清0,计数等于10的时候表示单击,计数等于3000,也就是三秒的时候表示长按,这样是不是就很好理解了,这里第一个函数读取当前状态就是你为了让他可以变成一个数组类型方便参与循环,按钮多的时候一行行写就写死人了,这样一个循环就搞定了。

2.主函数编写
  1. void main()
  2. {
  3.     LED_Init();
  4.     KEY_Init();
  5.     Timer0_Init();
  6.     EA = 1;
  7.    
  8.     while (1)
  9.     {
  10.         if( flag_1ms )
  11.         {
  12.             flag_1ms = 0;
  13.             KEY_Deal();
  14.             
  15.             if( KEY_ReadState(KEY_BACK_No)==KEY_PRESS )
  16.                 OUT_1P = !OUT_1P;      
  17.             if( KEY_ReadState(KEY_BACK_No)==KEY_RELAX )
  18.                 OUT_1N = !OUT_1N;   
  19.             
  20.             if( KEY_ReadState(KEY_SUB_No)==KEY_PRESS )
  21.                 OUT_2P = !OUT_2P;
  22.             if( KEY_ReadState(KEY_SUB_No)==KEY_RELAX )
  23.                 OUT_2N = !OUT_2N;   
  24.             
  25.             if( KEY_ReadState(KEY_ADD_No)==KEY_PRESS )
  26.                 OUT_3P = !OUT_3P;
  27.             if( KEY_ReadState(KEY_ADD_No)==KEY_RELAX )
  28.                 OUT_3N = !OUT_3N;   
  29.             
  30.             if( KEY_ReadState(KEY_DETE_No)==KEY_PRESS )
  31.                 OUT_4P = !OUT_4P;
  32.             if( KEY_ReadState(KEY_DETE_No)==KEY_RELAX )
  33.                 OUT_4N = !OUT_4N;               
  34.         
  35.         }
  36.     }
  37. }
复制代码
上面的驱动函数都写好了, 这里主函数就非常简单了。第一个按键按下,1P的灯取反,按键松开,1N的灯取反。第二个按键按下,2P的灯取反,按键松开,2N的灯取反。以此类推,这个程序也可以用来检测外设是不是正常。

四、下载测试
1.首先ISP软件的下载参数进行如下的配置!

截图202403061132563120.jpg        截图202403061134584713.jpg

2.使用LINK1D连接设备

截图202403061134267636.jpg

3.下载测试,点击下载按钮直到看到他下载完成。

截图202403061135305964.jpg

最后分别按下四个按钮,看到测试可以正常,满足我们的预期效果了。



最后附上这个测试版的下单链接,有需要可以自提:https://item.taobao.com/item.htm ... .0.0.4fee645ezPAFlh

1.按键点灯测试.rar (137.43 KB, 下载次数: 236)

回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:488
  • 最近打卡:2025-05-01 11:54:45
已绑定手机

20

主题

293

回帖

4436

积分

论坛元老

积分
4436
发表于 2024-3-6 13:33:57 | 显示全部楼层
截图202403132140051805.jpg
PWM新增硬件移相@STC8H2K08U, 含全套开源程序 !
测试版的淘宝链接:
https://item.taobao.com/item.htm ... .0.0.4fee645ezPAFlh





回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:488
  • 最近打卡:2025-05-01 11:54:45
已绑定手机

20

主题

293

回帖

4436

积分

论坛元老

积分
4436
发表于 2024-3-6 14:09:49 | 显示全部楼层

点评

已重新上传,感谢反馈  详情 回复 发表于 2024-3-7 08:06
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:83
  • 最近打卡:2024-09-30 23:22:51

0

主题

118

回帖

248

积分

中级会员

积分
248
发表于 2024-3-6 16:02:21 | 显示全部楼层
实用
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:54
  • 最近打卡:2024-05-20 05:47:02

13

主题

45

回帖

345

积分

中级会员

积分
345
发表于 2024-3-6 19:24:00 | 显示全部楼层
大爱大爱
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:54
  • 最近打卡:2024-05-20 05:47:02

13

主题

45

回帖

345

积分

中级会员

积分
345
发表于 2024-3-6 19:41:04 | 显示全部楼层
什么是PWM移相,不太懂。

点评

关注这个系列的帖子。后面会一点点剖析的哈~  详情 回复 发表于 2024-3-7 08:10
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:269
  • 最近打卡:2025-03-06 08:32:57

19

主题

59

回帖

790

积分

高级会员

积分
790
发表于 2024-3-7 08:05:08 | 显示全部楼层
是的,PWW硬件移相有什么用,不是很懂。不知道有没有什么视频可以展示一下硬件移相的效果

点评

[attachimg]37261[/attachimg] 类似这样波形整体移位了的  详情 回复 发表于 2024-3-7 08:09
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:135
  • 最近打卡:2024-12-25 10:15:05

47

主题

1350

回帖

8058

积分

荣誉版主

冲哥视频教程和各种开源资料QQ交流群884047237,可群

积分
8058
QQ
发表于 2024-3-7 08:06:10 | 显示全部楼层
马*** 发表于 2024-3-6 14:09
冲哥,文件中忘记加COM文件夹了吧,我这新手编译通过不了啊。冲哥的这例子都是实用干货啊。 ...

已重新上传,感谢反馈
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:135
  • 最近打卡:2024-12-25 10:15:05

47

主题

1350

回帖

8058

积分

荣誉版主

冲哥视频教程和各种开源资料QQ交流群884047237,可群

积分
8058
QQ
发表于 2024-3-7 08:09:29 | 显示全部楼层
ydc*** 发表于 2024-3-7 08:05
是的,PWW硬件移相有什么用,不是很懂。不知道有没有什么视频可以展示一下硬件移相的效果 ...

截图202403070809058338.jpg

类似这样波形整体移位了的
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:135
  • 最近打卡:2024-12-25 10:15:05

47

主题

1350

回帖

8058

积分

荣誉版主

冲哥视频教程和各种开源资料QQ交流群884047237,可群

积分
8058
QQ
发表于 2024-3-7 08:10:12 | 显示全部楼层
天源*** 发表于 2024-3-6 19:41
什么是PWM移相,不太懂。

关注这个系列的帖子。后面会一点点剖析的哈~
回复 支持 1 反对 0

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-1 19:38 , Processed in 0.189214 second(s), 120 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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