PWM硬件移相测试卡教程(一)按键点灯测试
=== STC8H2K08U, STC8H2K12U, STC8H2K17U
=== 有一个硬件PWM移相功能的PWM, 做逆变,做变频什么的就舒服多了 === 串口超时中断,这个超时检测可以轻松的实现类似 ModBus RTU 协议里的3.5个字符周期的超时等待
前言: 本章节系列最终的测试板卡如上所示(需要这个板卡的小伙伴可以到文末找到某宝的下单链接自行下载),用的最新的STC8H2K17U单片机,至于为什么选择这个单片机,可以看到宣传页!
新功能1:他有一个硬件移相功能的PWM,做逆变,做变频什么的就舒服多了 新功能2:和以往的规格相比,还多了个T11的低功耗定时器。 毕竟定时器这玩意儿可以不用,但是不能没有~ 新功能3:以及还有串口超时中断,这个超时检测可以让我们很轻松的实现类似于 ModBus RTU 协议里的3.5个字符周期的超时等待 新功能4:P10/P11引脚的数字功能可以对调(模拟功能不行)! P54可以映射P12的数字功能 (用过STC的小伙伴会发现带USB的单片机好多没有P12引脚)
一、引脚排布分析 欲练神功,必先拥有武功秘籍,先附上原理图,这一张主要讲解按键的点灯测试,也是为了测试硬件,毕竟要是硬件有问题的话,后面PWM写的天花乱坠灯一直不亮就尴尬了。
这里就可以很轻松的看到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输出引脚初始化(推挽输出)
再给他写个函数名称,这个初始化函数就可以配置为这样
- void LED_Init(void)
- {
- P1M0 = 0xff;
- P1M1 = 0x00;
- }
复制代码
2.按键输入初始化(准双向口)
再给他写个函数名称,这个初始化函数就可以配置为这样 - void KEY_Init(void)
- {
- P3M0 &= ~0xf0;
- P3M1 &= ~0xf0;
- }
复制代码
3.1ms系统时间函数(这里用定时器0实现,毕竟定时器0有不可屏蔽中断)还是用工具直接在线配置即可
这里直接可以用软件生成如下函数,该说不说,非常的好用 - void Timer0_Isr(void) interrupt 1
- {
- }
-
- void Timer0_Init(void) //1毫秒@22.1184MHz
- {
- AUXR |= 0x80; //定时器时钟1T模式
- TMOD &= 0xF0; //设置定时器模式
- TL0 = 0x9A; //设置定时初始值
- TH0 = 0xA9; //设置定时初始值
- TF0 = 0; //清除TF0标志
- TR0 = 1; //定时器0开始计时
- ET0 = 1; //使能定时器0中断
- }
复制代码
三、用户程序编写 1.按键检测函数 总有好多小伙伴问这个按键消抖怎么写,这里就简单的提供一种思路 这里所谓的抖动就是如上图那样,没按下的时候是高电平,按下之后马上变低电平,当然这是理想状态,实际因为机械按键会存在抖动的现象, 他会高低电平有一段变化的区间,常规的消抖就是检测到低电平了延时10ms在判断,当然这种相对来说并不可靠,我常用的思路就是,间隔1ms,连续10次检测到低电平即为触发了。即可通过如下代码实现: - u8 KEY_Read(u8 no)
- {
- if( no == 0 )
- return KEY1;
- if( no == 1 )
- return KEY2;
- if( no == 2 )
- return KEY3;
- if( no == 3 )
- return KEY4;
- return 0;
- }
- void KEY_Deal(void) //检查所有的按键状态 10ms执行一次
- {
- u8 i = 0;
- for(i=0;i<KEY_NUM;i++) //循环8次 i的取值范围是0-7 代表了P30-P37的状态查询
- {
- if( KEY_Read(i)==0 ) //持续按下,变量+1
- {
- if( Count[i]<60000 )
- Count[i] ++; //按键按下,这个计数变量+1
- }
- else //按键松开了,变量清0
- {
- if( Count[i]>0 ) //如果这个变量是按下过的
- {
- LastState |= (1<<i); //这个变量相应的标志位置位
- }
- else
- {
- LastState &= ~(1<<i); //这个变量相应的标志位清0
- }
- Count[i] = 0; //按键按下,这个计数变量清0
- }
- }
- }
- u8 KEY_ReadState(u8 no) //读取指定的按键的状态 10ms执行一次
- {
- if( Count[no]>0 ) //按键是按下的各种状态返回
- {
- if( Count[no]<10 ) //按下<30ms 返回消抖状态
- {
- return KEY_FILCKER;
- }
- else if( Count[no]==10 ) //按下正好30ms 返回单击
- {
- return KEY_PRESS;
- }
- else if( Count[no]<3000 ) //按下不到3000ms 返回单击结束
- {
- return KEY_PRESSOVER;
- }
- else if( Count[no]==3000 ) //按下正好3000ms 返回长按状态
- {
- return KEY_LONGPRESS;
- }
- else //长按结束
- {
- return KEY_LONGOVER;
- }
-
- }
- else //按键已经松开了,返回各种状态
- {
- if( LastState &( 1<<no ) ) //按键之前按下过
- {
- return KEY_RELAX;
- }
- else //按键之前没有按下
- {
- return KEY_NOPRESS;
- }
- }
- }
复制代码
上面的代码看起来好像很长,其实总结下来就很多,如果按钮按下了,数值按1ms自加一次,如果按钮松开了计数清0,计数等于10的时候表示单击,计数等于3000,也就是三秒的时候表示长按,这样是不是就很好理解了,这里第一个函数读取当前状态就是你为了让他可以变成一个数组类型方便参与循环,按钮多的时候一行行写就写死人了,这样一个循环就搞定了。
2.主函数编写 - void main()
- {
- LED_Init();
- KEY_Init();
- Timer0_Init();
-
- EA = 1;
-
- while (1)
- {
- if( flag_1ms )
- {
- flag_1ms = 0;
- KEY_Deal();
-
- if( KEY_ReadState(KEY_BACK_No)==KEY_PRESS )
- OUT_1P = !OUT_1P;
- if( KEY_ReadState(KEY_BACK_No)==KEY_RELAX )
- OUT_1N = !OUT_1N;
-
- if( KEY_ReadState(KEY_SUB_No)==KEY_PRESS )
- OUT_2P = !OUT_2P;
- if( KEY_ReadState(KEY_SUB_No)==KEY_RELAX )
- OUT_2N = !OUT_2N;
-
- if( KEY_ReadState(KEY_ADD_No)==KEY_PRESS )
- OUT_3P = !OUT_3P;
- if( KEY_ReadState(KEY_ADD_No)==KEY_RELAX )
- OUT_3N = !OUT_3N;
-
- if( KEY_ReadState(KEY_DETE_No)==KEY_PRESS )
- OUT_4P = !OUT_4P;
- if( KEY_ReadState(KEY_DETE_No)==KEY_RELAX )
- OUT_4N = !OUT_4N;
-
- }
- }
- }
复制代码
上面的驱动函数都写好了, 这里主函数就非常简单了。第一个按键按下,1P的灯取反,按键松开,1N的灯取反。第二个按键按下,2P的灯取反,按键松开,2N的灯取反。以此类推,这个程序也可以用来检测外设是不是正常。
四、下载测试 1.首先ISP软件的下载参数进行如下的配置!
2.使用LINK1D连接设备
3.下载测试,点击下载按钮直到看到他下载完成。
最后分别按下四个按钮,看到测试可以正常,满足我们的预期效果了。
1.按键点灯测试.rar
(137.43 KB, 下载次数: 236)
|