免费注册 查看新帖 |

Chinaunix

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

请教嵌入式Linux下调试温湿度传感器(SHT10)驱动程序碰到问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-12-15 10:34 |只看该作者 |倒序浏览
我的开发平台是pxa310,通过在驱动程序中模拟GPIO来读取SHT10的温湿度数据,Linux内核2.6.在驱动程序中没有读到SHT10的应答信号,发送命令以后SHT10 DATA引脚没有被拉低.示波器上面看到在SCK第8个下降沿跳低,在第9个SCK下降沿跳高,但是电平就跳低到2.3V,没有跳低到0.8V以下,后面的数据也没有读出来.但是我将这段程序移植到BLOB下面,不改变时序,只换用BLOB下对GPIO控制的接口函数,倒可以把数据读出来,而且数据正常, 不知道是什么问题想请教一下.中间重新编译过内核,和这个会有关吗?下面是我的驱动程序

  1. #include <linux/module.h>
  2. #include <linux/kernel.h>
  3. #include <linux/miscdevice.h>
  4. #include <linux/delay.h>
  5. #include <linux/spinlock.h>
  6. #include <linux/fs.h>
  7. #include <linux/ioctl.h>
  8. #include <linux/completion.h>
  9. #include <linux/interrupt.h>
  10. #include <linux/delay.h>
  11. #include <asm/arch/pxa3xx_gpio.h>
  12. #include <asm/arch/pxa-regs.h>
  13. #include <asm/arch/mfp.h>
  14. #include <asm/uaccess.h>

  15. #define DEVICE_NAME "sht10"

  16. #define noACK    0
  17. #define ACK    1
  18. #define MEASURE_TEMP        0x03
  19. #define MEASURE_HUMI        0x05
  20. #define MEASURE_REGI        0x07
  21. #define MEASURE_RESET    0x1e
  22. #define ARRAY_SIZE(x)    (sizeof(x) / sizeof((x)[0]))
  23. #define OSCC_REG            0x41350000
  24. /*static sht10_do_tasklet(void);
  25. DECLARE_TASKLET(sht10_tasklet,sht10_do_tasklet,0);

  26. DECLARE_COMPLETION(comp);
  27. */
  28. enum {TEMP,HUMI,REGI};
  29. unsigned char buf[4]={0};

  30. static void delay(void)
  31. {
  32.     unsigned int i;
  33.     for(i=0;i<2000;i++);
  34. //    mdelay(10);
  35. }

  36. static void port_init(void)
  37. {
  38.     pxa3xx_gpio_set_direction(79,1);
  39.     pxa3xx_gpio_set_direction(78,1);
  40. }

  41. static void data_output(void)
  42. {
  43.     pxa3xx_gpio_set_direction(78,1);
  44. }

  45. static void data_input(void)
  46. {
  47.     pxa3xx_gpio_set_direction(78,0);
  48. }

  49. static void set_sck(void)
  50. {
  51.     pxa3xx_gpio_set_level(79,1);
  52. }

  53. static void clear_sck(void)
  54. {
  55.     pxa3xx_gpio_set_level(79,0);
  56. }

  57. static void set_data(void)
  58. {
  59.     pxa3xx_gpio_set_level(78,1);
  60. }

  61. static void clear_data(void)
  62. {
  63.     pxa3xx_gpio_set_level(78,0);
  64. }

  65. static int read_data(void)
  66. {
  67.     int level=0;
  68.    
  69.     pxa3xx_gpio_set_direction(78,0);
  70.     level=pxa3xx_gpio_get_level(78);
  71.     pxa3xx_gpio_set_direction(78,1);
  72.     return level;
  73. }

  74. static void start_trans(void)
  75. {
  76.     set_data();clear_sck();
  77.     delay();
  78.     set_sck();
  79.     delay();
  80.     clear_data();
  81.     delay();
  82.     clear_sck();
  83.     clear_sck();
  84.     clear_sck();
  85.     delay();delay();
  86.     delay();delay();
  87.     set_sck();
  88.     delay();
  89.     set_data();
  90.     delay();
  91.     clear_sck();
  92. }

  93. static void reset_sht10(void)
  94. {
  95.     unsigned char i;
  96.     set_data();
  97.     clear_sck();
  98.     for(i=0;i<9;i++)
  99.     {
  100.         set_sck();
  101.         delay();   
  102.         clear_sck();
  103.         delay();   
  104.     }   
  105.     start_trans();
  106. }

  107. static char write_byte(unsigned char value)
  108. {
  109.     unsigned char i,error=0;
  110.     for(i=0x80;i>0;i>>=1)
  111.     {
  112.         if(i & value)
  113.         {   
  114.             set_data();
  115.         }
  116.         else
  117.         {
  118.             clear_data();
  119.         }
  120.         set_sck();
  121.         delay();//delay();
  122.         clear_sck();   
  123. //        delay();
  124.     }   
  125.     //delay();
  126.     set_data();
  127.     set_sck();
  128.     error=read_data();
  129.     //printk("write byte read error=0x%x\n",error);
  130.     delay();delay();delay();
  131.     clear_sck();
  132.     return error;
  133. }

  134. static char read_byte(unsigned char ack)
  135. {
  136. unsigned char i,val=0;
  137.     set_data();
  138.     for(i=0x80;i>0;i/=2)
  139.     {
  140.         set_sck();
  141.         delay();
  142.         if(read_data()){
  143.             val=(val|i);
  144.         }
  145.     //    delay();//delay();delay();
  146.         clear_sck();
  147.         delay();
  148.     }
  149.     //data_output();
  150.     delay();
  151.     if(ack==1){
  152.         clear_data();
  153.     }else{
  154.         set_data();
  155.     }
  156.     delay();//delay();delay();
  157.     set_sck();
  158.     delay();delay();delay();
  159.     clear_sck();
  160.     delay();//delay();delay();
  161.     set_data();
  162.     return val;
  163. }

  164. static int measure_sht10(unsigned char checksum,unsigned char mode)
  165. {
  166.     unsigned char error=0;
  167.     unsigned int i=0;
  168.     start_trans();
  169.     switch(mode)
  170.     {
  171.         case TEMP:error+=write_byte(MEASURE_TEMP);i=1;break;
  172.         case HUMI:error+=write_byte(MEASURE_HUMI);break;
  173.         default:break;
  174.     }
  175.     while(1)
  176.     {
  177.           if(read_data()==0) break;
  178.     }
  179.     if(read_data())
  180.     {
  181.         error+=1;
  182.         printk("time out high level error+1\n");
  183.     }
  184.     //printk("after receive ack\n");
  185.     if(i){
  186.         buf[0]=read_byte(ACK);
  187.         buf[1]=read_byte(ACK);
  188.         printk("buf[0]=0x%x\n",buf[0]);
  189.         printk("buf[1]=0x%x\n",buf[1]);
  190.     }
  191.     else{
  192.         buf[2]=read_byte(ACK);
  193.         buf[3]=read_byte(ACK);
  194.         printk("buf[2]=0x%x\n",buf[2]);
  195.         printk("buf[3]=0x%x\n",buf[3]);

  196.     }
  197.     checksum=read_byte(noACK);
  198.     //printk("ready to return\n");
  199.     return error;
  200. }

  201. /*static int sht10_do_tasklet(void)
  202. {
  203.     unsigned int error=0;
  204.     unsigned char checksum=0;
  205.     error+=measure_sht10(checksum,TEMP);    //measure the temperature
  206.     error+=measure_sht10(checksum,HUMI);    //measure the humidity
  207.     //error+=measure_sht10(checksum,REGI);    //measure the humidity
  208.     complete(&comp);
  209.     if(error!=0)
  210.     {
  211.         printk("wrong in measure error==>%d\n",error);
  212.     }
  213.     else
  214.     {
  215.         printk("data correct!\n");   
  216.     }
  217.     return error;
  218. }*/

  219. static ssize_t sht10_read(struct file *file,char *buffer,size_t count,loff_t *offp)
  220. {
  221.     unsigned int error=0;
  222.     unsigned char checksum=0;
  223.     port_init();
  224.     reset_sht10();
  225.     error+=measure_sht10(checksum,TEMP);    //measure the temperature
  226.     error+=measure_sht10(checksum,HUMI);    //measure the humidity
  227. //    tasklet_schedule(&sht10_tasklet);
  228. //    wait_for_completion(&comp);
  229.     copy_to_user(buffer,(char *)&buf,sizeof(buf));
  230. //    return 0;
  231.     //printk("after copy to user\n");
  232.     if(error!=0)
  233.     {
  234.         printk("wrong in measure error==>%d\n",error);
  235.     }
  236.     else
  237.     {
  238.         printk("data correct!\n");   
  239.     }
  240.     return error;
  241. }

  242. static struct file_operations sht10_fops = {
  243.     owner:    THIS_MODULE,
  244.     read:    sht10_read,
  245. };

  246. static struct miscdevice my_sht10 ={
  247.     .minor=4,
  248.     .name="sht10",
  249.     .fops=&sht10_fops,
  250. };

  251. struct pxa3xx_pin_config littleton_sensor_pins[] = {
  252. PXA3xx_MFP_CFG("SENSOR_DATA", MFP_PIN_GPIO78, MFP_AF0, MFP_DS10X, 0, MFP_LPM_PULL_NEITHER,MFP_EDGE_NONE),   
  253. PXA3xx_MFP_CFG("SENSOR_SCK",  MFP_PIN_GPIO79, MFP_AF0, MFP_DS10X, 0, MFP_LPM_PULL_NEITHER,MFP_EDGE_NONE),   
  254. };

  255. void pxa3xx_enable_sensor_pins(void)
  256. {
  257.     pxa3xx_mfp_set_configs(littleton_sensor_pins,ARRAY_SIZE(littleton_sensor_pins));
  258. }

  259. static int __init sht10_init(void)
  260. {
  261.     misc_register(&my_sht10);
  262.     pxa3xx_enable_sensor_pins();
  263.     printk(DEVICE_NAME " initialized\n");
  264.     return 0;
  265. }

  266. static void __exit sht10_exit(void)
  267. {
  268.     misc_deregister(&my_sht10);
  269. }

  270. module_init(sht10_init);
  271. module_exit(sht10_exit);
复制代码

[ 本帖最后由 dreamice 于 2008-12-15 11:13 编辑 ]

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
2 [报告]
发表于 2008-12-15 11:14 |只看该作者

回复 #1 chenbo35 的帖子

你确定你得硬件设计是没有问题的吧?

论坛徽章:
0
3 [报告]
发表于 2008-12-15 12:50 |只看该作者

回复 #1 chenbo35 的帖子

你是放到arm里面么

论坛徽章:
0
4 [报告]
发表于 2008-12-15 13:18 |只看该作者

回复 #2 dreamice 的帖子

是的,我的这个程序在BLOB下面可以跑的,数据也可以读出来,而且之前在linux下面也测试成功了,但是不知道怎么回事,现在再用这个驱动的时候就不行了....是我写的时候有什么地方没有注意还是怎么的?有点郁闷.请您指点一下,谢谢!

论坛徽章:
0
5 [报告]
发表于 2008-12-15 13:19 |只看该作者

回复 #2 dreamice 的帖子

数据读进来的一直是高阻0xff,好像是SHT10没有响应似的

论坛徽章:
0
6 [报告]
发表于 2008-12-15 13:20 |只看该作者

回复 #3 kns1024wh 的帖子

恩 是的
insmod sht10.ko

论坛徽章:
0
7 [报告]
发表于 2008-12-15 13:22 |只看该作者
A:data_input(void)该函数,你在哪里调用过啊~不将io口设成输入,你怎么读数~
B:有没有对io口开漏的要求~

就是这个样子~~~

[ 本帖最后由 .kaka 于 2008-12-15 13:27 编辑 ]

论坛徽章:
0
8 [报告]
发表于 2008-12-15 16:40 |只看该作者

回复 #7 .kaka 的帖子

读数据的时候有设置阿pxa3xx_gpio_set_direction(78,0); 0表示输入,调用
#include <asm/arch/pxa3xx_gpio.h>里的接口函数
static int read_data(void)
{
    int level=0;
   
    pxa3xx_gpio_set_direction(78,0);
    level=pxa3xx_gpio_get_level(78);
    pxa3xx_gpio_set_direction(78,1);
    return level;
}

[ 本帖最后由 dreamice 于 2008-12-15 16:56 编辑 ]

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
9 [报告]
发表于 2008-12-15 16:57 |只看该作者
我没太明白你得pxa310和BLOB是什么关系

论坛徽章:
0
10 [报告]
发表于 2008-12-15 20:06 |只看该作者

回复 #9 dreamice 的帖子

BLOB就是在bootloader里,相当于单片机裸奔
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP