说明:mini2440平台,wince6.0系统,vs2005
经过几个月的学学停停,终于在wince下加入了GPIO模拟的IIC总线,实现了IIC的移植,IIC的芯片是SHT21温湿度芯片。
之所以搞了这么久没搞定IIC,是在ADS下很早实现了,可就是添加到系统就总不对!示波器抓取发现时序在芯片复位后就不对了,找来找去都不知道怎么回事!这下就陷入了
纠结中,还是那种死循环的纠结,怎么都绕不出来!
网上发帖,网友们也支了很多招,感谢你们!jonsenwu网友的话提示了我!驱动程序加到系统里面,系统的调度需要时间,驱动程序使用的延时会出现延长的情况!根据他的提示,也进一步向他请教,这里特别感谢他!对驱动程序的优先级进行调整,使其在运行过程中始终保持住CPU的使用权。在ADS下测试的延时函数在系统下是不会相同的!
经过这个移植学到的东西:
1、wince下优先级相关知识
以下是代码:用于实现优先级抢占
//dwThreadID = GetCurrentThread(); //获取线程的ID
//dwThreadPri = CeGetThreadPriority(dwThreadID); //获取线程ID的优先级
//dwThreadQuantum = CeGetThreadQuantum(dwThreadID); // 获取线程的时间论片参数
//CeSetThreadPriority(dwThreadID, 0);// 设置当前线程的优先级为最高
//CeSetThreadQuantum(dwThreadID, 0); //设置当前线程的时间论片为0,保持CPU的占有权
//
//.......... (操作i2c的函数)
//
//CeSetThreadQuantum(dwThreadID, dwThreadQuantum); // 恢复正常时间论片
//CeSetThreadPriority(dwThreadID, dwThreadPri); //恢复正常优先级
说明:设置优先级有两个函数,一个函数可以设置0~255的个优先级(CeSetThreadPriority()),一个函数可以只能设置应用程序的优先级248~255(SetThreadPriority())!!
IIC调试成功后,把数据传给应用程序又出现个问题,先是在XXX_IOControl实现传递,怎么试都没数据出来,最后放到XXX_Read里面来实现就OK了。这里还要说明个关于memcpy的问题。如下:
2、对于memcpy函数的理解
先看一下出问题的写法:
unsigned short SHT_Data[2];//
memcpy( pBuffer , SHT_Data , 2 );//output
我应用程序读到的数据只有温度是对的,湿度就很大的数!肯定高手一眼就看出来问题所在了!
是因为:memcpy函数的拷贝是基于字节的,上面我拷贝的个数是2,所以只有温度能正常,湿度根本就没拷贝过去。
正确的方法是4个字节:memcpy( pBuffer , SHT_Data , 4);//output
3、GPIO的说明
这里得再次鄙视下友善之臂的技服!GPIO我原来使用的是2440默认两个引脚(默认的接了EEPROM和Camera!!,能对才怪!),最后查找到SPI0的空余引脚才搞定。
代码可以参照:http://www.linuxidc.com/Linux/2012-11/74419p2.htm
在mini2440下用IIC的IO口的模拟IIC时序,驱动一个外设芯片,ADS调试正确,添加到系统就不行,对驱动的优先级也提升了,还是不正确。
volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;
//volatile INTreg *s2440INT = (INTreg *)INT_BASE;
float SHT_Data[2];///tmp
HANDLE hDevSHT21;
DWORD SHT2x_Option_ThreadFuc(LPVOID Context);
void Virtual_Alloc(); // Virtual allocation
///////////////////////////////////////////////////////////////////////////
////////////////////////////////I2C.c source///////////////////////////////////////
#define noACK 0
#define aCk 1
#define SCL_OutEnable s2440IOP->rGPECON =( s2440IOP->rGPECON | 0x30000000 ) & 0xDFFFFFFF //28 config SCL as output
#define SDA_OutEnable s2440IOP->rGPECON =( s2440IOP->rGPECON | 0xC0000000 ) & 0x7FFFFFFF //30config SDA as output
#define SDA_OutDisable s2440IOP->rGPECON =( s2440IOP->rGPECON & 0x3fffffff)//config SDA as input
#define SCL_Set s2440IOP->rGPEDAT |= (1 << 14) //SCL output '1'
#define SCL_Clear s2440IOP->rGPEDAT &= ~(1 << 14) //SCL output '0'
#define SDA_Set s2440IOP->rGPEDAT |= (1 << 15) //SDA output '1'
#define SDA_Clear s2440IOP->rGPEDAT &= ~(1 << 15)
void Delay_us(U32 uS)
{
volatile DWORD dwCounter;
dwCounter = 100 * uS;
while(dwCounter--);
}
void I2c_Initialize ()
{ // put setup code here
SCL_OutEnable; // set gpio6->SCL as output
SCL_Set; // set SCL = '1'
SDA_OutDisable; // set gpio7->SDA as input
SDA_Set;
Delay_us(100); // let I2C device ready
}
//==============================================================================
void I2c_StartCondition ()
//==============================================================================
{
SDA_OutEnable; // set SDA as output
//SCL_OutEnable; //!!
SDA_Set;
SCL_Set;
Delay_us(1);
SDA_Clear;
Delay_us(5);
SCL_Clear;
Delay_us(5);
}
//==============================================================================
void I2c_StopCondition ()
//==============================================================================
{
SDA_OutEnable; // set SDA as output
//SCL_OutEnable; //!!
SDA_Clear;
SCL_Clear;
Delay_us(1);
SCL_Set;
Delay_us(5);
SDA_Set;
Delay_us(5);
}
//----------------------------------------------------------------------------------
unsigned char I2c_WriteByte(unsigned char value)
// writes a byte on the Sensibus and checks the acknowledge
//----------------------------------------------------------------------------------
{
// dwThreadID = GetCurrentThread();
//dwThreadPri = CeGetThreadPriority(dwThreadID);
//dwThreadQuantum = CeGetThreadQuantum(dwThreadID);
//CeSetThreadPriority(dwThreadID, 0);/
//CeSetThreadQuantum(dwThreadID, 0);
//
//。。。。。。。 (此部分是操作i2c的函数)
//
//CeSetThreadQuantum(dwThreadID, dwThreadQuantum);
//CeSetThreadPriority(dwThreadID, dwThreadPri);
HANDLE dwThreadID = GetCurrentThread();
DWORD dwThreadPri = CeGetThreadPriority(dwThreadID);
DWORD dwThreadQuantum = CeGetThreadQuantum(dwThreadID);
CeSetThreadPriority(dwThreadID, 0);
CeSetThreadQuantum(dwThreadID, 0);
int error=0, i1=0, i2=0;
for(i2 = 0; i2 < 8; i2++ )
{ // setup data onto SDA
if(value & 0x80){
SDA_Set; //SetSDA( 1 );
}
else{
SDA_Clear; //SetSDA( 0 );
}
Delay_us(1); //I2C timing: data setup time > 200ns
// issue a clock
SCL_Set; //SetSCL( 1 );
Delay_us(1); //I2C timing: SCL high time > 0.6us
SCL_Clear; //SetSCL( 0 );
Delay_us(2); //I2C timing: SCL low time > 1.3us
value= value<< 1;
}
//check ACK(Low state) from I2C device
SDA_OutDisable; //set SDA as input
Delay_us(1); //I2C timing: data(from I2C device) setup time > 200ns
SCL_Set; //SetSCL( 1 ); // issue a clock
Delay_us(1); //I2C timing: SCL high time > 0.6us
if(s2440IOP->rGPEDAT>>15) //read ACK_BIT issued from I2C device
{
// NO ACK, so setup STOP condition
SCL_Set; //SetSCL( 1 );
Delay_us(1); //I2C timing: stop setup timing > 0.6us
SDA_Set; //SetSDA( 1 ); SDA is in input status!
return -(i1+1); // no acknowledgement -> failed
}
SCL_Clear; //SetSCL( 0 );
Delay_us(2); //I2C timing: SCL low time > 1.3us
//check ACK passed, config SDA as output for further outputing
SDA_OutEnable;
// backup the thread priority;
CeSetThreadQuantum(dwThreadID, dwThreadQuantum);
CeSetThreadPriority(dwThreadID, dwThreadPri);
return 0;
}
//----------------------------------------------------------------------------------
unsigned char I2c_ReadByte(unsigned char ack)
//----------------------------------------------------------------------------------
// reads a byte form the Sensibus and gives an acknowledge in case of 'ack=1'
{
HANDLE dwThreadID = GetCurrentThread();
DWORD dwThreadPri = CeGetThreadPriority(dwThreadID);
DWORD dwThreadQuantum = CeGetThreadQuantum(dwThreadID);
CeSetThreadPriority(dwThreadID, 0);
CeSetThreadQuantum(dwThreadID, 0);
unsigned char i,val=0;
int i2=0,ub[1];
SDA_OutDisable; //SetSDADir( 0 ); // set SDA as input
// then read a abyte
for(i2 = 0; i2 < 8; i2++)
{
ub[0] = ub[0] << 1;
// issue a clock
SCL_Set; //SetSCL( 1 );
//DelayInuSec(1); //I2C timing: SCL high time > 0.6us
if(s2440IOP->rGPEDAT>>15) // read SDA
{
ub[0] = ub[0] | 0x01;
}
SCL_Clear; //SetSCL( 0 );
Delay_us(5); //I2C timing: SCL low time > 1.3us
}
//issue ACK condition properly
SDA_OutEnable;
if (ack)
{ SDA_Clear; }
else
{ SDA_Set; }
Delay_us(1); //I2C timing: data setup time > 200ns
SCL_Set; //SetSCL( 1 );
Delay_us(1); //I2C timing: SCL high time > 0.6us
SCL_Clear;
Delay_us(2); //I2C timing: SCL low time > 1.3us
// backup the thread priority;
CeSetThreadQuantum(dwThreadID, dwThreadQuantum);
CeSetThreadPriority(dwThreadID, dwThreadPri);
return ub[0];
}
///////////////////////////// SHT2x.c source //////////////////////////////////////
//===========================================================================
unsigned char SHT2x_MeasureHM(etSHT2xMeasureType eSHT2xMeasureType, unsigned int *pMeasurand)
//===========================================================================
{
unsigned char checksum; //checksum
unsigned char data[2]; //data array for checksum verification
unsigned char error=0; //error variable
unsigned int i; //counting variable
//-- write I2C sensor address and command --
I2c_StartCondition();
error |= I2c_WriteByte (I2C_ADR_W); // I2C Adr 0x80
RETAILMSG(1,(TEXT(' ...I2c_WriteByte (I2C_ADR_W ) error=%d rn'),error));
error = 0;
switch(eSHT2xMeasureType)
{
case HUMIDITY:
error |= I2c_WriteByte (TRIG_RH_MEASUREMENT_HM); break; //0xe5
case TEMP :
error |= I2c_WriteByte (TRIG_T_MEASUREMENT_HM); break; //0xe3
default:
break;
}
//-- wait until hold master is released --
RETAILMSG(1,(TEXT(' ...The MEASUREMENT error=%d rn'),error));
error = 0;
I2c_StartCondition();
error |= I2c_WriteByte (I2C_ADR_R);//0x81
RETAILMSG(1,(TEXT(' ...I2c_WriteByte (I2C_ADR_R) error =%d rn'),error));
error = 0;
Delay_us(2400);//covert time 90ms
//-- read two data bytes and one checksum byte --
data[0] = I2c_ReadByte(ACK);
data[1] = I2c_ReadByte(ACK);
checksum=I2c_ReadByte(NO_ACK);
RETAILMSG(1,(TEXT(' ...the MSB is 0x%xrn'), data[0]));
RETAILMSG(1,(TEXT(' ...the LSB is 0x%xrn'), data[1]));
*pMeasurand=data[0];
*pMeasurand<<=8;
*pMeasurand+=data[1];
//-- verify checksum --
//error |= SHT2x_CheckCrc (data,2,checksum);
I2c_StopCondition();
return error;
}
//===========================================================================
u8 SHT2x_SoftReset()
//===========================================================================
{
u8 error=0; //error variable
I2c_StartCondition();
error |= I2c_WriteByte (I2C_ADR_W); // I2C Adr 0x80
error |= I2c_WriteByte (SOFT_RESET); //0xfe // Command
I2c_StopCondition();
//Delay_us(400); // wait till sensor has restarted
Sleep(15);
return error;
}
//void SHT2x_Option(unsigned int pValue[] )
DWORD SHT2x_Option_ThreadFuc(LPVOID Context)
{
int error=0;
unsigned int sRH,sT;
float fHumiValue,fTempeValue;
LPCRITICAL_SECTION RegCS; // Register CS
while(1)
{
// EnterCriticalSection(RegCS);
上一篇:2440GPIO口在Linux中的定义
下一篇:mini2440 ADC可调电阻驱动程序开发源代码(杂项设备驱动框架)
推荐阅读最新更新时间:2026-03-20 20:03
- ADR435B 5 Vout 超低噪声 XFET 电压基准的典型应用,具有灌电流和拉电流能力
- 使用 Analog Devices 的 ADP8140 的参考设计
- NCP699SN30T1G 150mA、3 路输出电压 CMOS 低 Iq LDO 的典型应用,在 TSOP-5 中启用
- ZTL431过压/欠压保护电路典型应用
- 使用 Microchip Technology 的 DVR2802B3 的参考设计
- 开源的浮游生物监测分析设备PlanktoScope
- STK503,旨在评估 AT90USB AVR MCU 的入门套件,通过 AVR Studio 支持 JTAGICE mkII 和 AVRISP mkII
- 使用 BittWare 的 XCVU190 的参考设计
- 远程声控参考设计
- NCP4354AADAPGEVB,用于 NCP4354、65W 适配器关闭模式控制器的评估板



ZIGBEE网络原理与应用开发__吕治安编著
现代雷达系统的信号设计
BFR340T






京公网安备 11010802033920号