免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 931 | 回复: 0
打印 上一主题 下一主题

6410 io口配置为输出模式两种不同写法造成bug [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-20 09:44 |只看该作者 |倒序浏览
近期在做磁条刷卡器的驱动,需要通过两个IO口输出高低电平序列将磁条刷卡器开机初始化为新模式。
我按照Datasheet 写好后,怎么调试都无法进入新模式。给厂家打电话也无法解决。最总决定重写所有代码,很凑巧的搞定了。对比错误代码,和正确代码:

运行良好的代码1:

VOID IO_set_StrobeHigh()
{
    v_pIOPregs->GPPCON = (v_pIOPregs->GPPCON & (~(0x3 << 16))) | (0x1 << 16);
    v_pIOPregs->GPPDAT |= 0x01 << 8;
}
VOID IO_set_StrobeLow()
{
    v_pIOPregs->GPPCON = (v_pIOPregs->GPPCON & (~(0x3 << 16))) | (0x1 << 16);
    v_pIOPregs->GPPDAT &= ~(0x01 << 8);
}


无法得到结果的代码2:

VOID IO_set_StrobeHigh()
{
    v_pIOPregs->GPPCON &= (~(0x03 << 16));
    v_pIOPregs->GPPCON |= 0x01 << 16;
    v_pIOPregs->GPPDAT |= 0x01 << 8;
}

VOID IO_set_StrobeLow()
{
    v_pIOPregs->GPPCON &= (~(0x03 << 16));
    v_pIOPregs->GPPCON |= 0x01 << 16;
    v_pIOPregs->GPPDAT &= ~(0x01 << 8);
}


事后比较两处代码,在示波器上看到得波形完全一样。但是结果确不一样。

后来询问高手,意见不一,大致如下:

总结一下大家的回答:
1. 编译器问题:
  1.1 编译器将代码2作为8位来处理得。
  针对这个,我将代码修改为:
C/C++ code
VOID IO_set_strobe_H()
{
    v_pIOPregs->GPPCON &=  (~(0x00000003 << 16));
    v_pIOPregs->GPPCON |= 0x00000001 << 16;
    v_pIOPregs->GPPDAT |= 0x00000001 << 8;
}
VOID IO_set_strobe_L()
{
    v_pIOPregs->GPPCON &=  (~(0x00000003 << 16));
    v_pIOPregs->GPPCON |= 0x00000001 << 16;
    v_pIOPregs->GPPDAT &= ~(0x00000001 << 8);
}



重新测试,问题依旧。
1.2 编译器优化问题。
  这个我对vs2005 编译器不太熟悉。没有论证。

2. 寄存器配置问题
  这种说法主要是说代码2分两步设置IO为输出状态:
  第一步是现将IO口配置为输入状态,
  然后再配置为输出状态。
  这个时候第一步设为输入状态会产生隐患,输入状态下,IO口电平可能会被外部电路拉高或者拉低,产生毛刺。 如果在这一步被中断,毛刺可能会更大。



至于示波器问题, 我写得延时函数是us 级的,但S3C6410命令执行是ns 级的, 示波器没有分析出毛刺成分也是可能的。


总的来说,我比较倾向于第二种说法,将寄存器配置成输入状态会造成隐患。

这些都是写驱动中得经验问题,自己经验还是太少。
谢谢大家的热心回复。

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

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP