CC2530_温湿度_串口通信
2015-06-29 00:00
211 查看
流程:
传感器读取温度、湿度、光照强度 ,通过串口间歇发送给PC。
使用CC2530 读取温湿度传感器SHT10 的温度和湿度数据,并通过CC2530 内部的ADC 得到光照传感器的数据。其中对温湿度的读取是利用CC2530 的I/O(P1.0 和P1.1)
模拟一个类IIC 的过程。对光照的采集使用内部的AIN0 通道。
传感器读取温度、湿度、光照强度 ,通过串口间歇发送给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(); } }
相关文章推荐
- [Swust OJ 402]--皇宫看守(树形dp)
- perl grep 和 map 简单用法
- IO - 同步,异步,阻塞,非阻塞 (亡羊补牢篇)
- 美团酒店Node全栈开发实践
- mysql 常用命令
- 硅谷的实习生们:多数人青睐谷歌
- Maven 中央库 配置
- window.onload和$(function(){})的区别
- Javascript闭包(Closure)
- VO , PO , BO , QO , DAO , POJO
- 易宝典文章——玩转Office 365中的Exchange Online服务 之十 怎样在Exchange Online中配置邮件转发
- cas
- 简明 Git 命令速查表(中文版)
- Linux常用的shell命令
- Docker简明教程
- Nginx 重写规则指南
- PC硬件的那些权威认证
- 研究国内软件加密狗的集成与使用
- PHP_数组常用处理函数
- PHP_常用字符串处理函数