请教嵌入式Linux下调试温湿度传感器(SHT10)驱动程序碰到问题
我的开发平台是pxa310,通过在驱动程序中模拟GPIO来读取SHT10的温湿度数据,Linux内核2.6.在驱动程序中没有读到SHT10的应答信号,发送命令以后SHT10 DATA引脚没有被拉低.示波器上面看到在SCK第8个下降沿跳低,在第9个SCK下降沿跳高,但是电平就跳低到2.3V,没有跳低到0.8V以下,后面的数据也没有读出来.但是我将这段程序移植到BLOB下面,不改变时序,只换用BLOB下对GPIO控制的接口函数,倒可以把数据读出来,而且数据正常, 不知道是什么问题想请教一下.中间重新编译过内核,和这个会有关吗?下面是我的驱动程序
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/miscdevice.h>
- #include <linux/delay.h>
- #include <linux/spinlock.h>
- #include <linux/fs.h>
- #include <linux/ioctl.h>
- #include <linux/completion.h>
- #include <linux/interrupt.h>
- #include <linux/delay.h>
- #include <asm/arch/pxa3xx_gpio.h>
- #include <asm/arch/pxa-regs.h>
- #include <asm/arch/mfp.h>
- #include <asm/uaccess.h>
- #define DEVICE_NAME "sht10"
- #define noACK 0
- #define ACK 1
- #define MEASURE_TEMP 0x03
- #define MEASURE_HUMI 0x05
- #define MEASURE_REGI 0x07
- #define MEASURE_RESET 0x1e
- #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
- #define OSCC_REG 0x41350000
- /*static sht10_do_tasklet(void);
- DECLARE_TASKLET(sht10_tasklet,sht10_do_tasklet,0);
- DECLARE_COMPLETION(comp);
- */
- enum {TEMP,HUMI,REGI};
- unsigned char buf[4]={0};
- static void delay(void)
- {
- unsigned int i;
- for(i=0;i<2000;i++);
- // mdelay(10);
- }
- static void port_init(void)
- {
- pxa3xx_gpio_set_direction(79,1);
- pxa3xx_gpio_set_direction(78,1);
- }
- static void data_output(void)
- {
- pxa3xx_gpio_set_direction(78,1);
- }
- static void data_input(void)
- {
- pxa3xx_gpio_set_direction(78,0);
- }
- static void set_sck(void)
- {
- pxa3xx_gpio_set_level(79,1);
- }
- static void clear_sck(void)
- {
- pxa3xx_gpio_set_level(79,0);
- }
- static void set_data(void)
- {
- pxa3xx_gpio_set_level(78,1);
- }
- static void clear_data(void)
- {
- pxa3xx_gpio_set_level(78,0);
- }
- 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;
- }
- static void start_trans(void)
- {
- set_data();clear_sck();
- delay();
- set_sck();
- delay();
- clear_data();
- delay();
- clear_sck();
- clear_sck();
- clear_sck();
- delay();delay();
- delay();delay();
- set_sck();
- delay();
- set_data();
- delay();
- clear_sck();
- }
- static void reset_sht10(void)
- {
- unsigned char i;
- set_data();
- clear_sck();
- for(i=0;i<9;i++)
- {
- set_sck();
- delay();
- clear_sck();
- delay();
- }
- start_trans();
- }
- static char write_byte(unsigned char value)
- {
- unsigned char i,error=0;
- for(i=0x80;i>0;i>>=1)
- {
- if(i & value)
- {
- set_data();
- }
- else
- {
- clear_data();
- }
- set_sck();
- delay();//delay();
- clear_sck();
- // delay();
- }
- //delay();
- set_data();
- set_sck();
- error=read_data();
- //printk("write byte read error=0x%x\n",error);
- delay();delay();delay();
- clear_sck();
- return error;
- }
- static char read_byte(unsigned char ack)
- {
- unsigned char i,val=0;
- set_data();
- for(i=0x80;i>0;i/=2)
- {
- set_sck();
- delay();
- if(read_data()){
- val=(val|i);
- }
- // delay();//delay();delay();
- clear_sck();
- delay();
- }
- //data_output();
- delay();
- if(ack==1){
- clear_data();
- }else{
- set_data();
- }
- delay();//delay();delay();
- set_sck();
- delay();delay();delay();
- clear_sck();
- delay();//delay();delay();
- set_data();
- return val;
- }
- static int measure_sht10(unsigned char checksum,unsigned char mode)
- {
- unsigned char error=0;
- unsigned int i=0;
- start_trans();
- switch(mode)
- {
- case TEMP:error+=write_byte(MEASURE_TEMP);i=1;break;
- case HUMI:error+=write_byte(MEASURE_HUMI);break;
- default:break;
- }
- while(1)
- {
- if(read_data()==0) break;
- }
- if(read_data())
- {
- error+=1;
- printk("time out high level error+1\n");
- }
- //printk("after receive ack\n");
- if(i){
- buf[0]=read_byte(ACK);
- buf[1]=read_byte(ACK);
- printk("buf[0]=0x%x\n",buf[0]);
- printk("buf[1]=0x%x\n",buf[1]);
- }
- else{
- buf[2]=read_byte(ACK);
- buf[3]=read_byte(ACK);
- printk("buf[2]=0x%x\n",buf[2]);
- printk("buf[3]=0x%x\n",buf[3]);
- }
- checksum=read_byte(noACK);
- //printk("ready to return\n");
- return error;
- }
- /*static int sht10_do_tasklet(void)
- {
- unsigned int error=0;
- unsigned char checksum=0;
- error+=measure_sht10(checksum,TEMP); //measure the temperature
- error+=measure_sht10(checksum,HUMI); //measure the humidity
- //error+=measure_sht10(checksum,REGI); //measure the humidity
- complete(&comp);
- if(error!=0)
- {
- printk("wrong in measure error==>%d\n",error);
- }
- else
- {
- printk("data correct!\n");
- }
- return error;
- }*/
- static ssize_t sht10_read(struct file *file,char *buffer,size_t count,loff_t *offp)
- {
- unsigned int error=0;
- unsigned char checksum=0;
- port_init();
- reset_sht10();
- error+=measure_sht10(checksum,TEMP); //measure the temperature
- error+=measure_sht10(checksum,HUMI); //measure the humidity
- // tasklet_schedule(&sht10_tasklet);
- // wait_for_completion(&comp);
- copy_to_user(buffer,(char *)&buf,sizeof(buf));
- // return 0;
- //printk("after copy to user\n");
- if(error!=0)
- {
- printk("wrong in measure error==>%d\n",error);
- }
- else
- {
- printk("data correct!\n");
- }
- return error;
- }
- static struct file_operations sht10_fops = {
- owner: THIS_MODULE,
- read: sht10_read,
- };
- static struct miscdevice my_sht10 ={
- .minor=4,
- .name="sht10",
- .fops=&sht10_fops,
- };
- struct pxa3xx_pin_config littleton_sensor_pins[] = {
- PXA3xx_MFP_CFG("SENSOR_DATA", MFP_PIN_GPIO78, MFP_AF0, MFP_DS10X, 0, MFP_LPM_PULL_NEITHER,MFP_EDGE_NONE),
- PXA3xx_MFP_CFG("SENSOR_SCK", MFP_PIN_GPIO79, MFP_AF0, MFP_DS10X, 0, MFP_LPM_PULL_NEITHER,MFP_EDGE_NONE),
- };
- void pxa3xx_enable_sensor_pins(void)
- {
- pxa3xx_mfp_set_configs(littleton_sensor_pins,ARRAY_SIZE(littleton_sensor_pins));
- }
- static int __init sht10_init(void)
- {
- misc_register(&my_sht10);
- pxa3xx_enable_sensor_pins();
- printk(DEVICE_NAME " initialized\n");
- return 0;
- }
- static void __exit sht10_exit(void)
- {
- misc_deregister(&my_sht10);
- }
- module_init(sht10_init);
- module_exit(sht10_exit);
复制代码
[ 本帖最后由 dreamice 于 2008-12-15 11:13 编辑 ]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
你确定你得硬件设计是没有问题的吧?
你是放到arm里面么
是的,我的这个程序在BLOB下面可以跑的,数据也可以读出来,而且之前在linux下面也测试成功了,但是不知道怎么回事,现在再用这个驱动的时候就不行了....是我写的时候有什么地方没有注意还是怎么的?有点郁闷.请您指点一下,谢谢!
数据读进来的一直是高阻0xff,好像是SHT10没有响应似的
恩 是的
insmod sht10.ko
A:data_input(void)该函数,你在哪里调用过啊~不将io口设成输入,你怎么读数~
B:有没有对io口开漏的要求~
就是这个样子~~~
[ 本帖最后由 .kaka 于 2008-12-15 13:27 编辑 ]
读数据的时候有设置阿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 编辑 ]
我没太明白你得pxa310和BLOB是什么关系
BLOB就是在bootloader里,相当于单片机裸奔