您的位置:首页 > 其它

CC2530_温湿度_串口通信

2015-06-29 00:00 211 查看
流程:

传感器读取温度、湿度、光照强度 ,通过串口间歇发送给PC。

使用CC2530 读取温湿度传感器SHT10 的温度和湿度数据,并通过CC2530 内部的ADC 得到光照传感器的数据。其中对温湿度的读取是利用CC2530 的I/O(P1.0 和P1.1)

模拟一个类IIC 的过程。对光照的采集使用内部的AIN0 通道。

#include "hal.h"
#include "LCD.h"
#include "stdio.h"

#define noACK 0
#define ACK   1

#define STATUS_REG_W 0x06
#define STATUS_REG_R 0x07
#define MEASURE_TEMP 0x03
#define MEASURE_HUMI 0x05
#define RESET        0x1e

#define SCL          P1_0     //SHT10时钟
#define SDA          P1_1     //SHT10数据线

unsigned char d1,d2,d3,d4,d5,d6,d7;

void Wait(unsigned int ms);
void QWait(void)  ;
char s_write_byte(unsigned char value);
char s_read_byte(unsigned char ack);
void s_transstart(void);
void s_connectionreset(void);
char s_measure( unsigned char *p_checksum, unsigned char mode);
void initIO(void);

/**************************************************************************************************
* 函数名称:Wait
*
* 功能描述:延时函数(不精确延时)
*
* 参    数:ms -- 延时时间
*
* 返 回 值:无
**************************************************************************************************/
void Wait(unsigned int ms)
{

unsigned char g,k;
while(ms)
{

for(g=0;g<=167;g++)
{
for(k=0;k<=48;k++);
}
ms--;
}
}

/**************************************************************************************************
* 函数名称:QWait
*
* 功能描述:延时函数(大约1us的延时)
*
* 参    数:无
*
* 返 回 值:无
**************************************************************************************************/
void QWait()
{
asm("NOP");asm("NOP");
asm("NOP");asm("NOP");
asm("NOP");asm("NOP");
asm("NOP");asm("NOP");
asm("NOP");asm("NOP");
asm("NOP");

}

/**************************************************************************************************
* 函数名称:initIO
*
* 功能描述:SHT10串行通信IO初始化
*
* 参    数:无
*
* 返 回 值:无
**************************************************************************************************/
void initIO(void)
{
IO_DIR_PORT_PIN(1, 0, IO_OUT);
IO_DIR_PORT_PIN(1, 1, IO_OUT);
P1INP |= 0x03;
SDA = 1; SCL = 0;
}

/**************************************************************************************************
* 函数名称:s_write_byte
*
* 功能描述:从SHT10写一个字节
*
* 参    数:value -- 需写入的字节值
*
* 返 回 值:error -- 操作是否成功
**************************************************************************************************/
char s_write_byte(unsigned char value)
{
unsigned char i,error=0;
IO_DIR_PORT_PIN(1, 0, IO_OUT);      //时钟和数据IO设置为输出
IO_DIR_PORT_PIN(1, 1, IO_OUT);
for (i=0x80;i>0;i/=2)               //将一个字节的8位逐一输出
{
if (i & value)
SDA=1;
else
SDA=0;
SCL = 1;
QWait();QWait();QWait();QWait();QWait();
SCL = 0;
asm("NOP"); asm("NOP");
}
SDA = 1;
IO_DIR_PORT_PIN(1, 1, IO_IN);      //将数据线设置为输入,以准备接收SHT10的ACK
SCL = 1;  asm("NOP");
error = SDA;
QWait();QWait();QWait();
IO_DIR_PORT_PIN(1, 1, IO_OUT);     //将数据线恢复为输出状态
SDA = 1;
SCL = 0;

return error;
}

/**************************************************************************************************
* 函数名称:s_read_byte
*
* 功能描述:从SHT10读取一个字节
*
* 参    数:ack -- 读取数据后,向SHT10发送ACK
*
* 返 回 值:val -- 读取的字节值
**************************************************************************************************/
char s_read_byte(unsigned char ack)
{
IO_DIR_PORT_PIN(1, 0, IO_OUT);     //时钟和数据IO设置为输出
IO_DIR_PORT_PIN(1, 1, IO_OUT);
unsigned char i,val=0;
SDA= 1;
IO_DIR_PORT_PIN(1, 1, IO_IN);      //将数据线设置为输入,以准备接收SHT10的数据
for (i=0x80;i>0;i/=2)
{
SCL = 1;
if (SDA)
val = (val | i);
else
val = (val | 0x00);
SCL = 0;
QWait();QWait();QWait();QWait();QWait();
}
IO_DIR_PORT_PIN(1, 1, IO_OUT);     //将数据线恢复为输出状态
SDA = !ack;
SCL = 1;
QWait();QWait();QWait();QWait();QWait();
SCL = 0;
SDA = 1;

return val;                       //返回读取的值
}

/**************************************************************************************************
* 函数名称:s_transstart
*
* 功能描述:启动SHT10,开始与SHT10通信
*
* 参    数:无
*
* 返 回 值:无
**************************************************************************************************/
void s_transstart(void)
{
IO_DIR_PORT_PIN(1, 0, IO_OUT);
IO_DIR_PORT_PIN(1, 1, IO_OUT);
SDA = 1; SCL = 0;
QWait();QWait();
SCL = 1;QWait();QWait();
SDA = 0;QWait();QWait();
SCL = 0;QWait();QWait();QWait();QWait();QWait();
SCL = 1;QWait();QWait();
SDA = 1;QWait();QWait();
SCL = 0;QWait();QWait();
}

/**************************************************************************************************
* 函数名称:s_connectionreset
*
* 功能描述:与SHT10通信复位
*
* 参    数:无
*
* 返 回 值:无
**************************************************************************************************/
void s_connectionreset(void)
{
IO_DIR_PORT_PIN(1, 0, IO_OUT);
IO_DIR_PORT_PIN(1, 1, IO_OUT);
unsigned char i;
SDA = 1; SCL= 0;
for(i=0;i<9;i++)
{
SCL = 1;QWait();QWait();
SCL = 0;QWait();QWait();
}
s_transstart();
}

/**************************************************************************************************
* 函数名称:s_measure
*
* 功能描述:发送命令、读取SHT10温度或湿度数据
*
* 参    数:*p_checksum -- 校验和
*           mode -- 读取数据类型(3为温度,5为湿度)
*
* 返 回 值:er -- 操作结果
**************************************************************************************************/
char s_measure( unsigned char *p_checksum, unsigned char mode)
{
unsigned er=0;
unsigned int i,j;
s_transstart();                              //启动传输
switch(mode)
{
case 3  :er+=s_write_byte(3);break;    //发送温度读取命令
case 5  :er+=s_write_byte(5);break;    //发送湿度读取命令
default     :break;
}
IO_DIR_PORT_PIN(1, 1, IO_IN);                //将数据线设置为输入,以准备接收SHT10的ACK
for(i=0;i<65535;i++)
{
for(j=0;j<65535;j++)
{if(SDA == 0)
{break;}}
if(SDA == 0)
{break;}
}

if(SDA)                                     //SDA没有拉低,错误信息加1

{er += 1;}
d1 = s_read_byte(ACK);                     //数据读取
d2 = s_read_byte(ACK);
d3 = s_read_byte(noACK);
return er;
}

/**************************************************************************************************
* 函数名称:th_read
*
* 功能描述:调用相应函数,读取温度和数据数据并校验和计算
*
* 参    数:*t -- 温度值
*           *h -- 湿度值
*
* 返 回 值:无
**************************************************************************************************/
void th_read(int *t,int *h )
{
unsigned char error,checksum;
float humi,temp;
int tmp;
initIO();

s_connectionreset();                  //启动传输
error=0;
error+=s_measure(&checksum,5);       //读取湿度数据并校验
humi = d1*256+d2;

error+=s_measure(&checksum,3);      //读取温度数据并校验
temp = d1*256+d2;
if(error!=0) s_connectionreset();   //读取失败,通信复位
else                                //读取成功,计算数据
{
temp = temp*0.01  -  44.0 ;
humi = (temp - 25) * (0.01 + 0.00008 * humi) -0.0000028 * humi * humi + 0.0405 * humi-4;
if(humi>100)
{humi = 100;}
if(humi<0.1)
{humi = 0.1;}
}

tmp=(int)(temp*10)%10;

if(tmp>4)
{
temp=temp+1;
}
else
{
temp=temp;
}

*t=(int)temp;

tmp=(int)(humi*10)%10;

if(humi>4)
{
humi=humi+1;
}
else
{
humi=humi;
}

*h=(int)humi;

}

/**************************************************************************************************
* 函数名称:main
*
* 功能描述:读取温度、湿度和光照强度数据,并同过LCD显示
*
* 参    数:无
*
* 返 回 值:无
**************************************************************************************************/
void main()
{
int tempera;
int humidity;
char  s[16];
UINT8 adc0_value[2];
float num = 0;
SET_MAIN_CLOCK_SOURCE(CRYSTAL);                          // 设置系统时钟源为32MHz晶体振荡器

GUI_Init();                                              // GUI初始化
GUI_SetColor(1,0);                                       // 显示色为亮点,背景色为暗点
GUI_PutString5_7(25,6,"OURS-CC2530");                    //显示 OURS-CC2530
GUI_PutString5_7(10,22,"Temp:");
GUI_PutString5_7(10,35,"Humi:");
GUI_PutString5_7(10,48,"Light:");
LCM_Refresh();

while(1)
{
th_read(&tempera,&humidity);                            //读取温度和湿度
sprintf(s, (char*)"%d%d C",  ((INT16)((int)tempera / 10)), ((INT16)((int)tempera % 10)));  //将温度结果转换为字符串
GUI_PutString5_7(48,22,(char *)s);                      //显示结果
LCM_Refresh();
sprintf(s, (char*)"%d%d %%",  ((INT16)((int)humidity / 10)), ((INT16)((int)humidity % 10)));//将湿度结果转换为字符串
GUI_PutString5_7(48,35,(char *)s);                     //显示结果
LCM_Refresh();

/* AIN0通道采样 */
ADC_ENABLE_CHANNEL(ADC_AIN0);                          // 使能AIN0为ADC输入通道

/* 配置ADCCON3寄存器以便在ADCCON1.STSEL = 11(复位默认值)且ADCCON1.ST = 1时进行单一转换 */
/* 参考电压:AVDD_SOC引脚上的电压 */
/* 抽取率:512                     */
/* ADC输入通道:AIN0              */
ADC_SINGLE_CONVERSION(ADC_REF_AVDD | ADC_14_BIT | ADC_AIN0);

ADC_SAMPLE_SINGLE();                                   // 启动一个单一转换

while(!ADC_SAMPLE_READY());                            // 等待转换完成

ADC_ENABLE_CHANNEL(ADC_AIN0);                          // 禁止AIN0

adc0_value[0] = ADCL;                                      // 读取ADC值
adc0_value[1] = ADCH;                                      // 读取ADC值
adc0_value[0] = adc0_value[0]>>2;

num = (adc0_value[1]*256+adc0_value[0])*3.3/8192;  //有一位符号位,取2^13;
num /= 4;
num=num*913;                                        //转换为Lx
sprintf(s, (char*)"%d%d%d%d lx",  ((INT16)((int)num/1000)), ((INT16)((int)num%1000/100)),((INT16)((int)num%100/10)),((INT16)((int)num%10))); //将光照结果转换为字符串
GUI_PutString5_7(48,48,(char *)s);                    //显示结果
LCM_Refresh();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: