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

发布于 2022-09-23 13:08:35 字数 12568 浏览 27 评论 0

我的开发平台是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 编辑 ]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

可是我不能没有你 2022-09-30 13:08:35

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

有木有妳兜一样 2022-09-30 13:08:35

你是放到arm里面么

絕版丫頭 2022-09-30 13:08:35

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

扎心 2022-09-30 13:08:35

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

拥抱影子 2022-09-30 13:08:35

恩 是的
insmod sht10.ko

怀中猫帐中妖 2022-09-30 13:08:35

A:data_input(void)该函数,你在哪里调用过啊~不将io口设成输入,你怎么读数~
B:有没有对io口开漏的要求~

就是这个样子~~~

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

始终不够 2022-09-30 13:08:35

读数据的时候有设置阿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 编辑 ]

如梦初醒的夏天 2022-09-30 13:08:35

我没太明白你得pxa310和BLOB是什么关系

活泼老夫 2022-09-30 13:08:35

BLOB就是在bootloader里,相当于单片机裸奔

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文