打印

用什么方法同时实现50HZ的波形和按键检测?

[复制链接]
5010|21
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
西门闩|  楼主 | 2010-6-9 14:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我打算用CCP1与TMR2实现50HZ的方波,但是算出来PR2的初值超出了8位,还有其它方法吗?
要求,我这个还要实时检测B口的按键状态,一旦B口某位为低,则会执行相应的程序,但此时50HZ的方波不能停止,也就是一上电就有50HZ的方波,任何操作不影响。

如果用中断,一旦响应中断,肯定会优先执行某一项任务,那么相应的执行程序就会暂停,我这个是不能暂停的。时时刻刻波形输出与按键检测任何一个都不能停的。

大家能指点一下么?
沙发
yewuyi| | 2010-6-9 15:58 | 只看该作者
说的很乱,不明所以。。。

似乎是说PWM的输出和KEY都接在PORTB的某个口上,但又不想让检测KEY影响了PWM输出。

鉴于50HZ的频率比较低,可以采用20MS软件定时中断来实现,20MS定时中断后首先查询读KEY值,然后再翻转IO口电平实现50HZ方波输出,需要做一定的PWM和按键输入的电平隔离处理,这通过串二极管和电阻等就可解决 ,具体电路自己思考。
缺点:处理不好的话 ,可能的中断延迟等可能导致50HZ的频率精度会不如直接利用PWM输出那么准确。

使用特权

评论回复
板凳
西门闩|  楼主 | 2010-6-9 17:23 | 只看该作者
PWM的输出不是接在B口,B口只是接按键,方波信号在C口输出。
如果直接用PWM,我输出50HZ的方波,算出来的PR2值要16位,但是PR2只有8位啊。
如果定时到后,再查询KEY的值,假如某个KEY被按下,则程序就会去执行某个KEY的相关程序,但此时就没有波形输出了。
我这个是不能暂停的。时时刻刻波形输出与按键检测任何一个都不能停的。

使用特权

评论回复
地板
XIEYUANBIN| | 2010-6-9 19:13 | 只看该作者
如果你要用CCP来产生50HZ 的 PWM,必须降低你系统的振荡频率才能有此输出,我试过400HZ的PWM只能用4M的晶振,你自己算吧。50HZ还不如用IO口模拟了。按键检测要方便得多,根本占用不了你的资源。

使用特权

评论回复
5
NE5532| | 2010-6-9 19:23 | 只看该作者
降频率,用定时器自装载就不耗费CPU,实在不行还可以输出50Hz的倍频,外面加个CD4040来分频。

使用特权

评论回复
6
yewuyi| | 2010-6-9 20:04 | 只看该作者
PWM的输出不是接在B口,B口只是接按键,方波信号在C口输出。
如果直接用PWM,我输出50HZ的方波,算出来的PR2值要16位,但是PR2只有8位啊。
如果定时到后,再查询KEY的值,假如某个KEY被按下,则程序就会去执行某个KE ...
西门闩 发表于 2010-6-9 17:23


如果不是在同一个IO口上,连IO复用的麻烦都省了,这好象已经是很简单的考题了把,实在不明白这样的考题有什么难点.

还是自己多思考思考把.

写的是50HZ,但这个世界上显然没有正好理想的东西,即使PWM计算的值是正确的,还要受系统频率的限制呢,所以这显然有一个精度的问题,至于要做到多高的精度显然只有你自己清楚,鉴于50HZ这样的频率确实很低,完全也可以用IO模拟输出来达到和PWM输出一样的精度,当然,软件如何模拟需要自己去琢磨了

使用特权

评论回复
7
yewuyi| | 2010-6-9 20:07 | 只看该作者
对于目前的多数MCU来说,从微观上讲,任意两个任务都不能做到并行,所以你所说的PWM和KEY 不能停的问题只能是宏观而言,

使用特权

评论回复
8
西门闩|  楼主 | 2010-6-10 09:25 | 只看该作者
怎么好象全部都认为波形输出与按键检测能同时进行?
大家能更进一步提示一下么?到底怎么个写法?小弟刚搞这个不久,还不是很懂,求大伙能多指点一下,只提示一个方向都行,多谢了!

使用特权

评论回复
9
tangzzbb| | 2010-6-10 14:33 | 只看该作者
哈哈,这是因为你刚学,用的按键程序采用“检测到按键按下,延时等待防抖,再次检测按键仍按下,则按键按下动作被确认”。这种方式除过在特别简单和初学的状态下用外,基本实际上用不到。
要同时检测,最好这样写程序


//此处定义与硬件相关引脚
#define Key1Press         ~(PINA|(1<<5))                //如果按键1被定义在PINA的第5引脚,低电平有效


//以下为功能性定义
#define        NOKEY_PRESS        0
#deinfe KEY1_PRESS        1


uchar KeyCount=0;                        //按键计数器       
uchar KeyConfirm=0;                        //按键按下确认       
uchar KeyLastState=0;                        //保存上一次按键值

uchar TestKey(void)
{
  if(Key1Press)//按键处于按下状态
  {
    if(KeyLastSate==0)//是首次检测到按下
    {
      KeyLastState=1;//设置按键按下标识
      KeyConfirm=0;//清空按键未发送标识
      KeyCount=100;//设置按键防抖间隔
      return (NOKEY_PRESS);//返回无按键按下       
    }
    else//并非首次按下
    {
      if(KeyCount==0)&&(KeyConfirm==0)//按键防抖延时到,且按键按下操作未被发送
      {
        KeyConfirm=1;
        return(KEY1_PRESS);//返回按键按下
      }
    }
  }
  else
  {
    KeyLastState=0;//清除按键按下标识
  }

  return (NOKEY_PRESS);//返回无按键按下

}

void main(void)
{

  init();
  while(1)
  {
    dosomthing();
    if(TestKey()==KEY1_PRESS)
    {
      doKeyPress();
    }
  }
}

在毫秒定时中断中添加以下行
if(KeyCount) KeyCount--;

使用特权

评论回复
10
西门闩|  楼主 | 2010-6-10 17:43 | 只看该作者
可惜了,我不会C语言,要不这一定是一个学习的好资料。

使用特权

评论回复
11
西门闩|  楼主 | 2010-6-11 11:40 | 只看该作者
比如我采用TMR1中断,并产生波形。在中断期间,单片机肯定会暂停扫描键盘,输出波形,当单片机的TMR1没有中断时,此时刚好有某键按下,肯定会转去执行相应的按键程序(比如驱动马达转动),在执行程序的过程中,此时产生了中断,肯定就会转去执行中断,而此时的相应按键程序就会被停止了(而马达驱动程序就会被停止)。

大家帮我指点一下,看怎来实现这个功能。

使用特权

评论回复
12
dodome521| | 2010-6-14 14:57 | 只看该作者
如果用PWM,设定好周期就可以了,不用再进中断了,无论按键如何扫描,也不会影响PWM输出的。

使用特权

评论回复
13
西门闩|  楼主 | 2010-6-15 11:08 | 只看该作者
但是50HZ怎么用PWM?好象PR2只有8位吧?怎么够赋初值呢?

使用特权

评论回复
14
Hezhiqiang| | 2010-6-18 20:04 | 只看该作者
感觉I/O口模拟比较好!
1,如果要用PWM你的系统时钟要设置为至少<819.2KHZ,PR2=255,TMR2后分频1:16,PWM Period = [(PR2) + 1] • 4 • TOSC •(TMR2 Prescale Value)
2,I/O模拟加中断,制定按键检测标志位,20MS检测一次按键。大概可如下
1:20ms一次中断,中断程序里将方波I/O口取反,置按键标志位,TMR0赋初值,中断里不要有判断,只将相应的标志置1或0,根据个人爱好。
2:主程序检测按键标志位,如果按键标志有溢出则调用按键检测子程序,如没有不调用。
   按键扫描子程序:N个按键用N个寄存器累加去抖,两次应该足已,结束将按键标志清空,以保证按键扫描不占用太多系统,只20MS检测一次。
3:其余时间判断按键程序调用相应的马达驱动。

使用特权

评论回复
15
西门闩|  楼主 | 2010-6-19 09:07 | 只看该作者
如果是50HZ,就应该是10mS,然后在中断里面将方波取反,问题:如果在方波未中断的10mS,有按键被按下,此时肯定会转去执行按键子程序,但此时又刚好产生了中断,中断优先,此时,将不会执行按键子程序了。

不知以上理解对不对?

使用特权

评论回复
16
haotz| | 2010-6-23 19:56 | 只看该作者
楼主 进入死胡同了

使用特权

评论回复
17
西门闩|  楼主 | 2010-7-2 10:47 | 只看该作者
奇怪,我在PR2中赋初值F9H,得到的波形也是50HZ,算起来不对啊。

START
BSF STATUS,RP0 ;BANK1
MOVLW B'01111011'
MOVWF TRISC ;设CCP1,RC7为输出
MOVLW 0F9H
MOVWF PR2 ;设定PWM周期为最大值FFH


BCF STATUS,RP0 ;BANK0

MOVLW 0CH ;设CCP1为PWM输出
MOVWF CCP1CON ;脉宽低2位固定为00
MOVLW 7FH
MOVWF CCPR1L ;脉宽
CLRF T2CON ;设TMR2后分频比1:1,预分频比1:1,暂不开启
BSF T2CON,1 ;重设预分频比为1:16
BSF T2CON,TMR2ON ;开启TMR2
LOOP
BSF PORTC,7
END

不过我是用的RC振荡,在10脚测得的频率为211.5KHZ(系统4分频后的输出),为什么会这样呢?是我错误造成的?还是误打误撞搞对了?

使用特权

评论回复
18
西门闩|  楼主 | 2010-7-2 13:14 | 只看该作者
不好意思,算了一下,确实是这个频率。

使用特权

评论回复
19
兰天白云| | 2010-7-2 19:10 | 只看该作者
“同时”有不同的理解,
两者相差1秒算不算同时?
两者相差1毫秒算不算同时?
两者相差1微秒算不算同时?
两者相差1纳秒算不算同时?
两者相差1皮秒算不算同时?

在单片机里,你的“同时”是什么要求?
如果相差1毫秒算“同时”,那么,要实现你的PWM和按键处理就没有问题
按键可以这样处理,当第一次检测到按键后启动一个计时器,然后去干别的事(如PWM),20毫秒后再检测按键,看看是否还是这个键,如果是则处理这个键,如果在处理这个键的时候又要求处理PWM,那么你赶紧处理PWM(请你在几个微妙处理好PWM),然后回来处理按键,这样看起来他们是同时处理的

使用特权

评论回复
20
kjzyywx| | 2010-8-6 15:36 | 只看该作者
在单片机里,你的“同时”是什么要求?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

71

主题

288

帖子

1

粉丝