OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2564|回复: 32

程序消抖求解决哪位大神帮忙看下啊,急急,谢谢

[复制链接]

11

主题

67

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2019-5-23
在线时间
26 小时
发表于 2019-5-28 20:35:46 | 显示全部楼层 |阅读模式
1金钱
用拨码开关调频,下载好后可以用,不过几天后就有异常,高手能帮我看下吗?急急,异常是我没做拨码开关的消抖吗
#include "stm32f10x.h"
#include "key.h"
#include "sys.h"
#include "delay.h"
#include "timer.h"
#include "led.h"
#include "24cxx.h"
extern u16 f,w;               

void TIM3_IRQHandler(void)   //TIM3中断
{
        if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
                {
                        t++;       
                        if(t<w)
                        {
                                LED3=0;
                                LED4=0;
                        }       
                        else
                        {
                                LED3=1;
                                LED4=1;
                        }
                        if(t>=f)t=0;
                }
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update);  //清除TIMx更新中断标志        
}

//按键初始化函数
void KEY_Init(void) //IO初始化
{
        GPIO_InitTypeDef GPIO_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE,ENABLE);

        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_9;//PB9
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
        GPIO_Init(GPIOB, &GPIO_InitStructure);//
       
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6;//KEY0-KEY6
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
        GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE0,1,2,3
}

////////////
void KEY_Scan1()//拨码开关调频
{
        if(KEY0==1&&KEY1==1&&KEY2==1&&KEY3==1)//0
        {
                RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
                f=200;w=100;       
        }
        else if(KEY0==0&&KEY1==1&&KEY2==1&&KEY3==1)//1
        {
                RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
                f=140;w=70;
        }
        else if(KEY0==1&&KEY1==0&&KEY2==1&&KEY3==1)//2
        {
                RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
                f=100;w=50;
        }
        else if(KEY0==0&&KEY1==0&&KEY2==1&&KEY3==1)//3
        {
                RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
                f=70;w=35;
        }
        else if(KEY0==1&&KEY1==1&&KEY2==0&&KEY3==1)//4
        {
                RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
                f=50;w=25;
        }
        else if(KEY0==0&&KEY1==1&&KEY2==0&&KEY3==1)//5
        {
                RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
                f=40;w=20;
        }
        else if(KEY0==1&&KEY1==0&&KEY2==0&&KEY3==1)//6
        {
                RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
                f=30;w=15;
        }
        else if(KEY0==0&&KEY1==0&&KEY2==0&&KEY3==1)//7
        {
                RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
                f=16;w=8;
        }
        //
        else if(KEY0==1&&KEY1==1&&KEY2==1&&KEY3==0)//8
        {
                RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
                f=10;w=5;
        }
        else if(KEY0==0&&KEY1==1&&KEY2==1&&KEY3==0)//9
        {
                RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
                f=8;w=4;
        }
       
        else
        {
                  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, DISABLE); //时钟使能
                        LED3=0;LED4=1;
        }
       
}


最佳答案

查看完整内容[请看2#楼]

int tem = GPIOE->IDR&0x7F; //这是把 PE0~PE6 抄至 tem.0~6, 同时把tem.7清零 if (GPIOB->IDR & (1
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2019-5-28 20:35:47 | 显示全部楼层
本帖最后由 edmund1234 于 2019-5-29 21:23 编辑
hlphzy123456 发表于 2019-5-29 20:43
int tem =  GPIOE->IDR&0x7F;//PE0到PE7
if (GPIOB->IDR & (1    if ((DipSwR ^ tem)
  .....

int tem =  GPIOE->IDR&0x7F;    //这是把 PE0~PE6 抄至 tem.0~6, 同时把tem.7清零
if (GPIOB->IDR & (1<<9)            //这两句是把 PB9 抄至 tem.7, 是tem.7所以是+0x80
  tem+=0x80;

tem 只会在0~255这一范围内, 因为tem.0~7都是有效数据, 无需再屏蔽, 所以直接
if ((DipSwR ^ tem)就可以了

也许把 int tem 改为 u8 tem你就容易些理解吧
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2019-5-28 20:59:12 | 显示全部楼层
        u8        DipSwR;                // 全局
        u8        DebC;                // 全局       
       
        //---------> 把下面这段东东放SysTick中断
        if ((DipSwR ^ GPIOE->IDR)&0x0F) {
                if (DebC){
                        if (!--DebC) {
                                DipSwR = GPIOE->IDR;
                                DipSwitchChange();              // ---> Dip Switch 消抖后的输出点
                        }
                }
                else {
                        DebC=100;                // 100ms
                }               
        }
        else
                DebC=0;
回复

使用道具 举报

11

主题

67

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2019-5-23
在线时间
26 小时
 楼主| 发表于 2019-5-29 12:56:50 | 显示全部楼层
非常谢谢啊,这个DebC=100;                // 100ms延时函数,不是定时器函数吧,
还有能帮我看看我的中断函数有问题吗,我现在存在的问题是拨码开关拨到一个频率,波形上面会有很多小波形如下图
00.png
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2019-5-29 15:04:40 | 显示全部楼层
hlphzy123456 发表于 2019-5-29 12:56
非常谢谢啊,这个DebC=100;                // 100ms延时函数,不是定时器函数吧,
还有能帮我看看我的中 ...

DecC 是个全局变量, 因为是放在SysTick里, 100就等于100ms
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2019-5-29 15:30:37 | 显示全部楼层
hlphzy123456 发表于 2019-5-29 12:56
非常谢谢啊,这个DebC=100;                // 100ms延时函数,不是定时器函数吧,
还有能帮我看看我的中 ...

不知道你的TIM3配置是怎样的, 假如你的TIM3->ARR是赋值100;

#define  Tim3_Arr  100

const u16 FreqTab[]={
    0,                    
    0,
    0,                    
    0,
    0,                    
    0,
    0,                    
    0,
    4 * Tim3_Arr,
    5 * Tim3_Arr,
    8 * Tim3_Arr,
    15 * Tim3_Arr,
    20 * Tim3_Arr,
    25 * Tim3_Arr,
    35 * Tim3_Arr,
    50 * Tim3_Arr,
    70 * Tim3_Arr,
    100 * Tim3_Arr,
};


u8        DipSwR;                // 全局
u8        DebC;                // 全局      

void SysTick_Handler(void){

    if ((DipSwR ^ GPIOE->IDR)&0x0F) {
        if (DebC){
            if (!--DebC) {
                DipSwR = GPIOE->IDR & 0x0F;
                //DipSwitchChange();              // ---> Dip Switch 消抖后的输出点
                if (FreqTab[DipSwR]>=0) {
                    TIM3->ARR = FreqTab[DipSwR];
                    TIM3->CR1 |= TIM_CR1_CEN;
                }
                else
                    TIM3->CR1 &= ~(u32)TIM_CR1_CEN;
            }
        }
        else {
            DebC=100;                // 100ms
        }               
    }
    else
            DebC=0;
}


void TIM3_IRQHandler(void)   //TIM3中断
{
    if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
    {
        LED_GPIO->ODR ^= (LED3_Pos|LED4_Pos);    // LED3 & 4 取反
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update);  //清除TIMx更新中断标志        
    }
}



回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2019-5-29 15:35:09 | 显示全部楼层
下一次再有类似的应用, 就应该用TIM3_CHx 的toggle模式, 这就连TIM3的中断函数都不用写了
回复

使用道具 举报

11

主题

67

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2019-5-23
在线时间
26 小时
 楼主| 发表于 2019-5-29 16:30:52 | 显示全部楼层
4 * Tim3_Arr,是4*100=400吗
回复

使用道具 举报

11

主题

67

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2019-5-23
在线时间
26 小时
 楼主| 发表于 2019-5-29 16:37:24 | 显示全部楼层
TIM3->ARR = FreqTab[DipSwR];
                    TIM3->CR1 |= TIM_CR1_CEN;还有这2句是什么意思啊,我完全看不懂,我想要stm32的单片机IO像51的IO口直接对IO口赋值,比如我这样可以吗
u16 rst(void)
{
        u16 cn;
        //DATAOUT(0xff);
        cn=GPIOE->IDR&0xf0;
        return(cn);
}
回复

使用道具 举报

11

主题

67

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2019-5-23
在线时间
26 小时
 楼主| 发表于 2019-5-29 16:58:02 | 显示全部楼层
uchar KeyScan()       
{
        uchar cord ;
        cord = P2 & 0x0f;                 
        return (cord);       
}void KeyPro()
{
        switch( KeyScan() )
        {
                case 0x0f:要执行的                break;          //0
                case 0x0e:要执行的;                break;//1
                case 0x0d:要执行的;                break;//2
                case 0x0c:要执行的;                break; //4
               
        }        这个是51的程序,如何改到STM32中啊
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2019-5-29 17:02:49 | 显示全部楼层
本帖最后由 edmund1234 于 2019-5-29 17:06 编辑
hlphzy123456 发表于 2019-5-29 16:37
TIM3->ARR = FreqTab[DipSwR];
                    TIM3->CR1 |= TIM_CR1_CEN;还有这2句是什么意思啊,我 ...

TIM3->ARR = FreqTab[DipSwR];     // FreqTab是个表, 根据你拨码开关的值查表, 取出相应的值, 这个值是TIM计时器周期时间, 简单而言TIM3->ARR赋的值是决定TIM3多久产生一次中断
TIM3->CR1 |= TIM_CR1_CEN; 是使能TIM3 == TIM_Cmd(TIM3, ENABLE);
TIM3->CR1 &= ~(u32)TIM_CR1_CEN;  == TIM_Cmd(TIM3, DISABLE);
不能用RCC_APB1PeriphClockCmd来使能TIM3的, 因为一旦DISABLE后, 之前你对TIM3的设置全都会清零


IDR 是读IO的输入状态
ODR 是写IO的状态
为了方便对IO同时写 0及1, 是可以通过BSRR直接写, 不需要读回IO状态再与再或再写回去
比如 PE3 要设为1, PE4 要清零
GPIOE->BSRR = ((1<<4)<<16)+(1<<3);  这样一条就可以做到了

比如 PE6 要设为1, PE9 要清零
GPIOE->BSRR = ((1<<9)<<16)+(1<<6);  这样一条就可以做到了

BSSR只能写信, 读回来是没意思的零售, 要知道IO的输出状态就读ODR

回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2019-5-29 17:09:37 | 显示全部楼层
hlphzy123456 发表于 2019-5-29 16:30
4 * Tim3_Arr,是4*100=400吗

我不知道你现在给TIM3->ARR赋的是什么值, 就假定你是给TIM3->ARR赋的值是100, 你把100改为你对TIM3->ARR赋的值就行了
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2019-5-29 17:12:05 | 显示全部楼层
hlphzy123456 发表于 2019-5-29 16:58
uchar KeyScan()       
{
        uchar cord ;

P2  --〉 GPIOx->IDR               // x 自己填充

其它不用改
回复

使用道具 举报

11

主题

67

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2019-5-23
在线时间
26 小时
 楼主| 发表于 2019-5-29 18:33:15 | 显示全部楼层
本帖最后由 hlphzy123456 于 2020-7-1 08:29 编辑

非常感谢你啊,十分感谢
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2019-5-29 19:24:46 | 显示全部楼层
TIM3_IRQHandler(void)
先不考虑TIM3的时间会变, TIM3是时开时关的, 怎样用来去抖?
放在SysTick中断里做消抖是最合适的
回复

使用道具 举报

11

主题

67

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2019-5-23
在线时间
26 小时
 楼主| 发表于 2019-5-29 19:36:24 | 显示全部楼层
本帖最后由 hlphzy123456 于 2019-5-29 19:44 编辑

那我修改成如下void KEY_Scan1()//拨码开关调频
{
        if(KEY0==1&&KEY1==1&&KEY2==1&&KEY3==1)//0
        {
               TIM3->CR1 |= TIM_CR1_CEN;//开定时器
                f=200;w=100;        
        }
        else if(KEY0==0&&KEY1==1&&KEY2==1&&KEY3==1)//1
        {
               TIM3->CR1 |= TIM_CR1_CEN;//开定时器
                f=140;w=70;
        }
        else if(KEY0==1&&KEY1==0&&KEY2==1&&KEY3==1)//2
        {
                TIM3->CR1 |= TIM_CR1_CEN;//开定时器
                f=100;w=50;
        }
        ......
      else
    {
              TIM3->CR1 &= ~(u32)TIM_CR1_CEN;//关定时器
              LED3=0;LED4=1;
    }
        
}
u8        DipSwR;                // 全局
u8        DebC;                // 全局
void SysTick_Handler(void){

    if ((DipSwR ^ GPIOE->IDR)&0x0F)
{
        if (DebC)
         {
            if (!--DebC)
            {
                DipSwR = GPIOE->IDR & 0x0F;
                    KEY_Scan1();//执行这个函数
                    TIM3->CR1 |= TIM_CR1_CEN;
                }
                else
                    TIM3->CR1 &= ~(u32)TIM_CR1_CEN;
            }
        }
        else {
            DebC=20;                // 100ms
        }               
    }
    else
            DebC=0;
}

这样可以吗?我是刚学STM32的很多都不懂,还麻烦帮我看下啊,还有SysTick()用到的话还需要初始化一下对吗

回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2019-5-29 20:05:11 | 显示全部楼层
hlphzy123456 发表于 2019-5-29 19:36
那我修改成如下void KEY_Scan1()//拨码开关调频
{
        if(KEY0==1&&KEY1==1&&KEY2==1&&KEY3==1)//0

  //---------------- 1ms 定时中断
  SysTick->CTRL=0;
  SysTick->VAL=0;
  SysTick->LOAD = 72000-1;
  SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk|SysTick_CTRL_TICKINT_Msk|
                  SysTick_CTRL_ENABLE_Msk;
回复

使用道具 举报

11

主题

67

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2019-5-23
在线时间
26 小时
 楼主| 发表于 2019-5-29 20:19:14 | 显示全部楼层
非常谢谢啊,我是两个拨码开关,一个拨码开关接是PB9,PE0到PE2,一个拨码开关接的是PE3到PE6
DipSwR = GPIOE->IDR & 0x0F;这个我修改成DipSwR =GPIOB|GPIOE->IDR & 0xFF;对吗?
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2019-5-29 20:34:26 | 显示全部楼层
hlphzy123456 发表于 2019-5-29 20:19
非常谢谢啊,我是两个拨码开关,一个拨码开关接是PB9,PE0到PE2,一个拨码开关接的是PE3到PE6
DipSwR = GPIO ...


int tem =  GPIOE->IDR&0x7F;
if (GPIOE->IDR & (1<<9)
  tem+=0x80;

if ((DipSwR ^ GPIOE->IDR)&0x0F)    -->    if ((DipSwR ^ tem)
  .....
  ....
DipSwR = GPIOE->IDR & 0x0F; -->  DipSwR = tem;
回复

使用道具 举报

11

主题

67

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2019-5-23
在线时间
26 小时
 楼主| 发表于 2019-5-29 20:43:01 | 显示全部楼层
int tem =  GPIOE->IDR&0x7F;//PE0到PE7
if (GPIOB->IDR & (1<<9) //这里的E是B也就是PB9对吗
  tem+=0x80;//这句是0x7f+1的结果吗?

if ((DipSwR ^ GPIOE->IDR)&0x0F)  //这里为什么不是 &0xFF -->    if ((DipSwR ^ tem)
  .....
  ....
DipSwR = GPIOE->IDR & 0x0F; -->  DipSwR = tem;
回复

使用道具 举报

11

主题

67

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2019-5-23
在线时间
26 小时
 楼主| 发表于 2019-5-29 21:39:26 | 显示全部楼层
非常感谢你的解答啊,真的很感谢
回复

使用道具 举报

11

主题

67

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2019-5-23
在线时间
26 小时
 楼主| 发表于 2019-5-30 11:10:07 | 显示全部楼层
还要麻烦一下啊,现在我碰到一个问题,用void systick_int()//1ms&#182;¨ê±
{
        SysTick->CTRL=0;
  SysTick->VAL=0;
  SysTick->LOAD = 72000-1;
  SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk|SysTick_CTRL_TICKINT_Msk|
                  SysTick_CTRL_ENABLE_Msk;
}用这个systick时钟和正点原子的delay.c冲突了,只要另外写一个systick时钟整个系统就不工作了
回复

使用道具 举报

11

主题

67

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2019-5-23
在线时间
26 小时
 楼主| 发表于 2019-5-30 11:11:05 | 显示全部楼层
我的delay,库文件直接用的正点原子的delay.c
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2019-5-30 12:11:07 | 显示全部楼层
hlphzy123456 发表于 2019-5-30 11:10
还要麻烦一下啊,现在我碰到一个问题,用void systick_int()//1ms&#182;¨ê±
{
        SysTick->CTRL=0;

那就随便找个计时器做呗, TIM6 或 7 都可以

        RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM6 , ENABLE);  

        TIM_DeInit(TIM6);            
        TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1 ;   
        TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up ;
        TIM_TimeBaseInitStruct.TIM_Period = 72000-1;           
        TIM_TimeBaseInitStruct.TIM_Prescaler = 0;   
        TIM_TimeBaseInit(TIM6, &TIM_TimeBaseInitStruct ) ;         

        NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn;   
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;         
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         
        NVIC_Init(&NVIC_InitStructure);


void TIM6_IRQHandler(void){

  if (TIM6->SR & 1){
    TIM6->SR &= ~(u32)1;

     ....... 去抖的东东放这里
  }
   

}
回复

使用道具 举报

11

主题

67

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2019-5-23
在线时间
26 小时
 楼主| 发表于 2019-5-30 12:45:43 | 显示全部楼层
我开了定时器3做调频,再开定时器6做消抖,不会有互相的影响对吗?总感觉会打架
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2019-5-30 12:53:14 | 显示全部楼层
hlphzy123456 发表于 2019-5-30 12:45
我开了定时器3做调频,再开定时器6做消抖,不会有互相的影响对吗?总感觉会打架

只要你别在中断里做很多事情, 再开几个计时器都不会有问题
回复

使用道具 举报

11

主题

67

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2019-5-23
在线时间
26 小时
 楼主| 发表于 2019-5-30 12:55:48 | 显示全部楼层
好的谢谢,
回复

使用道具 举报

11

主题

67

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2019-5-23
在线时间
26 小时
 楼主| 发表于 2019-5-30 13:53:26 | 显示全部楼层
本帖最后由 hlphzy123456 于 2020-7-1 08:32 编辑

大侠棒我最后看一下啊,示波器看下来还好,void TIM6_Int_Init(u16 arr,u16 psc)
{
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); //ê±&#214;óê1&#196;ü
        
        //&#182;¨ê±&#198;÷TIM33&#245;ê&#188;&#187;ˉ
        TIM_TimeBaseStructure.TIM_Period = arr; //éè&#214;&#195;&#212;ú&#207;&#194;ò&#187;&#184;&#246;&#184;üD&#194;ê&#194;&#188;t×°è&#235;&#187;&#238;&#182;ˉμ&#196;×&#212;&#182;ˉ&#214;&#216;×°&#212;&#216;&#188;&#196;′&#230;&#198;÷&#214;ü&#198;úμ&#196;&#214;μ        
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //éè&#214;&#195;ó&#195;à′×÷&#206;aTIMxê±&#214;ó&#198;μ&#194;ê3yêyμ&#196;&#212;¤·&#214;&#198;μ&#214;μ
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //éè&#214;&#195;ê±&#214;ó·&#214;&#184;&#238;:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM&#207;òé&#207;&#188;&#198;êy&#196;£ê&#189;
        TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure); //&#184;ù&#190;Y&#214;&#184;&#182;¨μ&#196;2&#206;êy3&#245;ê&#188;&#187;ˉTIMxμ&#196;ê±&#188;&#228;&#187;ùêyμ¥&#206;&#187;

        TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE ); //ê1&#196;ü&#214;&#184;&#182;¨μ&#196;TIM6&#214;D&#182;&#207;,&#212;êDí&#184;üD&#194;&#214;D&#182;&#207;

        //&#214;D&#182;&#207;ó&#197;&#207;è&#188;&#182;NVICéè&#214;&#195;
        NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn;  //TIM6&#214;D&#182;&#207;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  //&#207;è&#213;&#188;ó&#197;&#207;è&#188;&#182;0&#188;&#182;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //′óó&#197;&#207;è&#188;&#182;3&#188;&#182;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQí¨μà±&#187;ê1&#196;ü
        NVIC_Init(&NVIC_InitStructure);  //3&#245;ê&#188;&#187;ˉNVIC&#188;&#196;′&#230;&#198;÷

        TIM_Cmd(TIM6, ENABLE);  //ê1&#196;üTIMx                                
}        
        



回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2019-5-30 14:22:14 | 显示全部楼层
本帖最后由 edmund1234 于 2019-5-30 14:23 编辑
hlphzy123456 发表于 2019-5-30 13:53
大侠棒我最后看一下啊,示波器看下来还好,void TIM6_Int_Init(u16 arr,u16 psc)
{
        TIM_TimeBaseInitTyp ...

void TIM6_IRQHandler(void)
{
  static u8 flag;
  u8 tem;
        if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET)  //&#188;ì2éTIM6&#184;üD&#194;&#214;D&#182;&#207;·¢éúó&#235;·&#241;
        {
                        tem =GPIOE->IDR&0x7F;
                        if (GPIOB->IDR & 1<<9)
                                tem +=0x80;
               
            flag++;                                                                // 看不懂你这一块怎样能消抖
            if(flag==4)                                                               //               
            {                                                                               //        
                                if ((DipSwR ^ tem))//消抖                //  <<--- 没什么机会跳到这儿来的
                {                                                                       //        
                                        DipSwR= tem; //消抖                //
                                }                                                                //
                        }                                                                        //
                        else                                                                //
                        {                                                                        //
                                flag=0;                                                // <<--- 每一次都会执行这一句
            }                              
        }
        TIM_ClearITPendingBit(TIM6, TIM_IT_Update);  //&#199;&#229;3yTIMx&#184;üD&#194;&#214;D&#182;&#207;±ê&#214;&#190;        
}                        

另外, 其实不需要disp(),
switch(DipSwR) 就可以了, 因为DipSwR就是去抖后拨码开关的状态
回复

使用道具 举报

11

主题

67

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2019-5-23
在线时间
26 小时
 楼主| 发表于 2019-5-30 15:38:17 | 显示全部楼层
为什么没有机会到这里来啊  if ((DipSwR ^ tem))//消抖
我开的是5ms一次中断TIM6_Int_Init(999,359);就是这个函数,在中断中设置一个flag,加一次就是5ms,加4次就是20ms,想20ms扫描一次,是根据51的思路写的,是不是我写错了啊
回复

使用道具 举报

0

主题

20

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
409
金钱
409
注册时间
2018-8-21
在线时间
85 小时
发表于 2019-5-30 17:34:14 | 显示全部楼层
flag=0;放到if(flag==4)里面
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2019-5-30 17:46:05 | 显示全部楼层
hlphzy123456 发表于 2019-5-30 15:38
为什么没有机会到这里来啊  if ((DipSwR ^ tem))//消抖
我开的是5ms一次中断TIM6_Int_Init(999,359);就是 ...

Flag=0 的时候

flag++   // flag=1
if (Flag==4){     // 条件不成立
  。。。。。
}
else
   flag=0;           // 所以只会跑到这里来, 再次把flag清零, 然后下一个循环也一样
回复

使用道具 举报

11

主题

67

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2019-5-23
在线时间
26 小时
 楼主| 发表于 2019-5-30 19:36:37 | 显示全部楼层
  flag++;                                                               
            if(flag==4)                                                               //               
            {                                                                               //        
                flag=0;
                if ((DipSwR ^ tem))//消抖               
                {                                                                              
                             DipSwR= tem; //消抖               
                 }   
                                                                            //
              }        这样就  成立了,二楼说的对,非常谢谢啊,
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-17 11:53

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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