CC2530片内温度采集(串口发送)

头文件:

#include "iocc2530.h"

#define uint unsigned int
#define RLED P1_0
#define GLED P1_1
#define YLED P0_4

// Data
typedef unsigned char   BYTE;

// Signed numbers
typedef unsigned char   UINT8;
typedef unsigned char   INT8U;
typedef unsigned short  UINT16;
typedef unsigned short  INT16U;
typedef unsigned long   UINT32;
typedef unsigned long   INT32U;

// Signed numbers
typedef unsigned char   INT8;
typedef unsigned short  INT16;
typedef unsigned long   INT32;

#define ADC_REF_1_25_V  0X00
#define ADC_14_BIT      0X30
#define ADC_TEMP_SENS   0X0E

#define DISABLE_ALL_INTERRUPTS() (IEN0 = IEN1 = IEN2 = 0X00)

#define ADC_SINGLE_CONVERSION(settings)\
  do{ADCCON3 = (settings);}while(0)

#define ADC_SAMPLE_SINGLE()\
  do{ADC_STOP(); ADCCON1 |= 0X40;} while(0)

#define ADC_SAMPLE_READY() (ADCCON1 & 0X80)

#define ADC_STOP()\
  do {ADCCON1 |= 0X30;} while(0)

#define ADC14_TO_CELSIUS(ADC_VALUE) (((ADC_VALUE) >> 4) - 335)    // 计算温度公式value / 16 - 335

// 
void InitClock(void) {
  CLKCONCMD = 0X28;           // 定时器计数时钟设置为1MHz,系统时钟设置为32MHz
  while(CLKCONSTA & 0X40);    // 等待晶振稳定
}

// 初始化LED
void InitLEDIO(void) {
  P1DIR |= 0X03;          // P1_0,P1_1设为输出
  P0DIR |= 0X10;          // P0_4设为输出
  RLED = GLED = YLED = 1;
}


// 初始化T3
void InitT3(void) {
  T3CCTL0 = 0X44;   // 开中断,设置比较模式
  T3CC0 = 0XFA;     // 设置为250
  T3CTL |= 0X9A;    // 16分频    启动定时器    开溢出中断    模模式
  IEN1 |= 0X08;     // T3中断使能
  IEN0 |= 0X80;     // 开总中断
}

void InitUART0(void) {
  PERCFG = 0X00;        // 位置1 P0口
  P0SEL = 0X0C;         // P0_2,P0_3用作串口
  
  P2DIR &= ~0XC0;       // P0优先作为UART0
  U0CSR |= 0X80;        // 串口设置为UART模式
  
  U0GCR = 8;            
  U0BAUD = 59;        //设置波特率为9600
  
  UTX0IF = 1;         // 中断标志初始置位1
  U0CSR |= 0X40;      // 串口接收器使能
  IEN0 |= 0X84;       // 开总中断   开UART0中断
}

// 发送字符串
void UartTX_Send_String(char *Data, int len) {
  int j;
  for(j = 0; j < len; j++) {
    U0DBUF = *Data;
    Data++;
    while(UTX0IF == 0);     // 等待UART0 TX中断标志置1
    UTX0IF = 0;             // 清除中断标志
  }
}

void Delay(uint n) {
  uint i, j;
  for(j = 0; j < 10; j++) {
    for(i = 0; i < n; i++);
    for(i = 0; i < n; i++);
    for(i = 0; i < n; i++);
    for(i = 0; i < n; i++);
    for(i = 0; i < n; i++);
    for(i = 0; i < n; i++);
    for(i = 0; i < n; i++);
    for(i = 0; i < n; i++);
  }
}

代码:

#include "iocc2530.h"
#include "string.h"
#include "stdio.h"
#include "initUART_Timer.h"

INT16 AvgTemp;


// 温度传感器初始化
void initTempSensor(void) {
  DISABLE_ALL_INTERRUPTS();         // 关闭全部中断
  InitClock();            
  /*
  *((BYTE __xdata*)0x624B) = 0x01;  // 开启温度传感器,TR0的地址为0X624B
  *((BYTE __xdata*)0x61BD) = 0x01;  // 将温度传感器与ADC连接起来,ATEST地址为0x61BD
  */
  TR0 |= 0x01;
  ATEST |= 0x01;
}

/*  读取温度传感器AD值  */ 
INT8 getTemperature(void) {
//  UINT8 i;
//  UINT16 AdcValue;
  UINT16 value;
  
//  AdcValue = 0;
  ADC_SINGLE_CONVERSION(ADC_REF_1_25_V | ADC_14_BIT | ADC_TEMP_SENS);
  // ADCCON3 = (0x00 | 0x30 | 0x0e);
  // ADCCON3 = 内部参考电压 |12位分辨率 | 通道为内部温度传感器
  
  ADC_SAMPLE_SINGLE();            // 开启单通道ADC
  // ADCCON1开启一个新的转换序列,就是在ADC结束之后刷新检测通道
  
  while(!ADC_SAMPLE_READY());     // 等待AD转换完成

/*  */
  value = ADCL >> 2;              // ADCL寄存器低2位无效
  value |= (((UINT16)ADCH) << 6); // 把值移至高位
  
  return ADC14_TO_CELSIUS(value);  // 计算温度函数

/*  
  value = ADCL;
  value = ((int)ADCH << 8);
  value >>= 2;
  
  return value * 0.06229 - 311.43;  // 计算温度公式
*/
}

void main()
{
  char i;
  char TempValue[30] = {0};
  
  InitUART0();            // 初始化串口
  initTempSensor();       // 初始ADC
  
  while(1) {
    AvgTemp = 0;
    /**/
    for(i = 0; i < 64; i++) {
      AvgTemp += getTemperature();
      AvgTemp >>= 1;      // 每次累加后除2
    }
    
    
//    AvgTemp = getTemperature();
    memset(TempValue, 0, 30);
    sprintf(TempValue, "%d\n", (INT8)AvgTemp);
    // 把后面的参数格式化给第一个参数字符数组指针
    // TempValue = "ADTestRead = (INT8)AvgTemp) C\n", 
                                                       
    UartTX_Send_String(TempValue, strlen(TempValue)); // 串口发送
//    UartTX_Send_String("\n", 1);
    Delay(10000);
  }
}

这个是片内温度的采集以及通过串口发送,我也做了上位机:
在这里插入图片描述
部分代码:


    ui->lcdNumber->setDigitCount(4);    //显示位数
    ui->lcdNumber->setMode(QLCDNumber::Dec);    //十进制
    ui->lcdNumber->setSegmentStyle(QLCDNumber::Flat);       //显示方式
 QByteArray buf;
   buf = qSerPort.readAll();
   if(!buf.isEmpty())          //显示数据
   {
       QString ss = tr(buf);
       temperature = ss.toDouble();
       ui->lcdNumber->display(temperature);    //lcd显示数据
   }

   buf.clear();    //清空缓存区
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
DS18B20是单总线数字传感器,共有6种信号类型:复位脉冲、应答脉冲、写0、写1、读0和读1。所有这些信号,除了应答脉冲以外,都由主机发出同步信号。并且发送所有的命令和数据都是字节的低位在前。 这几个信号的时序如下: 1)复位脉冲和应答脉冲 单总线上的所有通信都是以初始化序列开始。主机输出低电平,保持低电平时间至少480us,以产生复位脉冲。接着主机释放总线,4.7K的上拉电阻将单总线拉高,延时15~60us,并进入接收模式(Rx)。接着DS18B20拉低总线60~240us,以产生低电平应答脉冲,若为低电平,再延时480us。 2)写时序 写时序包括写0时序和写1时序。所有写时序至少需要60us,且在2次独立的写时序之间至少需要1us的恢复时间,两种写时序均起始于主机拉低总线。写1时序:主机输出低电平,延时2us,然后释放总线,延时60us。写0时序:主机输出低电平,延时60us,然后释放总线,延时2us。 3)读时序 单总线器件仅在主机发出读时序时,才向主机传输数据,所以,在主机发出读数据命令后,必须马上产生读时序,以便从机能够传输数据。所有读时序至少需要60us,且在2次独立的读时序之间至少需要1us的恢复时间。每个读时序都由主机发起,至少拉低总线1us。主机在读时序期间必须释放总线,并且在时序起始后的15us之内采样总线状态。典型的读时序过程为:主机输出低电平延时2us,然后主机转入输入模式延时12us,然后读取单总线当前的电平,然后延时50us。 DS18B20的温度读取过程一般为:复位->发SKIPROM命令(0XCC)->发开始转换命令(0X44)->延时->复位->发送SKIPROM命令(0XCC)->发读存储器命令(0XBE)->连续读出两个字节数据(即温度)->结束。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值