OpenEdv-开源电子网

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

读到低电平后再读到高电平就计数减一,软真调试没问题,为什么硬件就出错呢?

[复制链接]

4

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
60
金钱
60
注册时间
2016-12-28
在线时间
8 小时
发表于 2016-12-29 16:15:37 | 显示全部楼层 |阅读模式
1金钱
功能:
外部给PE4高低电平,读取PE4,读到低电平后再读到高电平就计数减一
代码:
u8 a=5;   //计数初始值为5

int main(void)
{
     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
     uart_init(115200);   
     delay_init();
     LED_Init();
     LCD_Init();
     LCD_ShowString(30,40,210,24,24,"rest:");
     LCD_ShowNum(0,80,a,24,24);   
     while(1)
        {
            if(a==0)        //当a=0时亮DS1提示,按下KEY1则灭灯
            {
                GPIO_ResetBits(GPIOE,GPIO_Pin_5);
                if(!GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3))
                {
                    GPIO_SetBits(GPIOE,GPIO_Pin_5);
                    break;
                }
            }
            else
            {
                if(!GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4))        //读取到低电平
                {
                    GPIO_ResetBits(GPIOB,GPIO_Pin_5);                  //亮灯DS0
                    if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4))    //读取到高电平
                    {
                        a=a-1;                                                      //计数减一
                        LCD_ShowNum(0,80,a,24,24);                       //LCD屏上显示此时的数值
                        GPIO_SetBits(GPIOB,GPIO_Pin_5);                 //灭灯DS0
                    }
                }
                else
                {
                    GPIO_SetBits(GPIOB,GPIO_Pin_5);
                }
            }
        }
}
问题:
烧到开发板上给PE4高低电平,LCD屏上有时候会减一,减一规律不定。
第一次:成功 LCD:4            第二次:成功 LCD:4               第三次:......
            成功 LCD:3                        失败 LCD:4
            失败 LCD:3                        成功 LCD:3
            成功 LCD:2                        成功 LCD:2
            失败 LCD:2                        失败 LCD:2
            成功 LCD:1                        成功 LCD:1
            成功 LCD:0                        成功 LCD:0

但是在软件仿真中还是准确计数的。

求助。

最佳答案

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

在我问了这个问题的第三天,我的领导给了我一个方法,在循环里每一句话加上较大的延时,然后发现可以结果正常了,接着就把那些延时一步一步的减少直到发现具体是哪需要延时以及延时多少。 原因不是很清楚,大概理解为软件和硬件上的差时。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

4

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
60
金钱
60
注册时间
2016-12-28
在线时间
8 小时
 楼主| 发表于 2016-12-29 16:15:38 | 显示全部楼层
在我问了这个问题的第三天,我的领导给了我一个方法,在循环里每一句话加上较大的延时,然后发现可以结果正常了,接着就把那些延时一步一步的减少直到发现具体是哪需要延时以及延时多少。
原因不是很清楚,大概理解为软件和硬件上的差时。
回复

使用道具 举报

17

主题

344

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1280
金钱
1280
注册时间
2013-12-14
在线时间
567 小时
发表于 2016-12-29 16:37:03 | 显示全部楼层
你外部给PE4的电平是怎么来的,是传感器给的还是自己用手模拟的?
if(!GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4))        //读取到低电平
                {
                    GPIO_ResetBits(GPIOB,GPIO_Pin_5);                  //亮灯DS0
                    if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4))    //读取到高电平
你这种写法,是一个瞬态,单片机的运行速度很高,在检测到低电平以后,必须在这个“瞬间”再次检测到高电平,a才能-1。
不清楚你的需求是什么,是要检测一个上升沿还是高脉冲?这个可以用上升沿中断来做。

另外,感觉你那个break用的有问题,为什么要跳出while(1)循环?
半导体->模拟电路->数字电路->单片机->汇编->C->操作系统->java
回复

使用道具 举报

4

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
60
金钱
60
注册时间
2016-12-28
在线时间
8 小时
 楼主| 发表于 2016-12-29 17:16:34 | 显示全部楼层
东北小辉辉 发表于 2016-12-29 16:37
你外部给PE4的电平是怎么来的,是传感器给的还是自己用手模拟的?
if(!GPIO_ReadInputDataBit(GPIOE,GPIO_ ...

外部接的是光电开关。检测到有挡光后会持续低电平,无挡光是高电平。
我是要获取到有下降沿然后又有上升沿就计数减一。
本来打算用pwm但是不要知道低电平持续时间就放弃了。
break是因为计数到0后要求断另一个设备的电,我还不会就暂时先这样模拟了。
回复

使用道具 举报

3

主题

85

帖子

0

精华

高级会员

Rank: 4

积分
586
金钱
586
注册时间
2016-5-13
在线时间
106 小时
发表于 2016-12-29 17:37:30 | 显示全部楼层
正正杨 发表于 2016-12-29 17:16
外部接的是光电开关。检测到有挡光后会持续低电平,无挡光是高电平。
我是要获取到有下降沿然后又有上升 ...

小建议,参考按键消抖的形式,按键松开才算数,尽量把这种函数放在定时器当中做,不要放在主函数,判断类的函数最好不要一直占着CPU,中断中判断成功了置位一个标志给主程序知道就行了
回复

使用道具 举报

17

主题

344

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1280
金钱
1280
注册时间
2013-12-14
在线时间
567 小时
发表于 2016-12-29 17:46:13 | 显示全部楼层
本帖最后由 东北小辉辉 于 2016-12-29 17:48 编辑
正正杨 发表于 2016-12-29 17:16
外部接的是光电开关。检测到有挡光后会持续低电平,无挡光是高电平。
我是要获取到有下降沿然后又有上升 ...

低电平时间不知道的话,能否考虑用中断来做呢?中断资源够用吗?
我刚才的理解可能有点问题,尝试使用先下降沿,再上升沿这种中断的方式来尝试一下吧。
其实我感觉直接配置成下降沿中断也行,看看其他人有什么好办法。
半导体->模拟电路->数字电路->单片机->汇编->C->操作系统->java
回复

使用道具 举报

4

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
60
金钱
60
注册时间
2016-12-28
在线时间
8 小时
 楼主| 发表于 2016-12-29 17:56:10 | 显示全部楼层
abdfgh 发表于 2016-12-29 17:37
小建议,参考按键消抖的形式,按键松开才算数,尽量把这种函数放在定时器当中做,不要放在主函数,判断类的函 ...

有这么写,只是为了方便问问题就用了原始写法。
谢谢建议。
回复

使用道具 举报

4

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
60
金钱
60
注册时间
2016-12-28
在线时间
8 小时
 楼主| 发表于 2016-12-29 18:09:53 | 显示全部楼层
东北小辉辉 发表于 2016-12-29 17:46
低电平时间不知道的话,能否考虑用中断来做呢?中断资源够用吗?
我刚才的理解可能有点问题,尝试使用先 ...

我有写这个方法,捕获下降沿有效,但是捕获不到上升沿,所以显示的低电平延续时间都是定时器的最大值。。。我就想还是按简单的方法试试能不能检测到高电平,然后又出了这个问题。

忘记说的是在检测到低电平又检测到高电平后的语句里
                                        if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4))
                                        {
                                                a=a-1;
                                                LCD_ShowNum(0,80,a,24,24);
                                                GPIO_SetBits(GPIOB,GPIO_Pin_5);
                                        }
低电平亮灯,高电平灭灯,这个灯是正确的,所以我怀疑是不是计数的问题。可是这个原因我怎么也相信不了。。。

谢谢你啊
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-1 01:58

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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