查看: 797|回复: 0
打印 上一主题 下一主题

mega128+18B20+12864 的程序

[复制链接]
跳转到指定楼层
沙发
发表于 2016-6-14 18:53:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include <iom128v.h>
#include <macros.h>
#define uchar unsigned char
#define uint  unsigned int

#define DS18B20 PF0
#define RESOLU_9              0X1F        //即分别对应config 中的R1 R0=00 01 10 11
#define RESOLU_10             0X3F
#define RESOLU_11             0X5F
#define RESOLU_12             0X7F

#define RD_ROM                                       0X33   //总线上只有一个设备时才可能使用该命令
#define MATCH_ROM                              0X55
#define SKIP_ROM                              0XCC
#define SEARCH_ROM                            0XF0
#define ALARM_ROM                                         0XEC

#define TEMP_TRANS                            0X44  //启动温度转换
#define RD_SCRATCHPAD                   0XBE  //从暂存存储器中读字节(9字节)从字节0开始,可由复位中断读
#define WR_SCRATCHPAD                   0X4E //写数值到暂存存储器地址2和3(TH,TL温度触发器)
#define COPY_SCRATCHPAD                 0X48 //将暂存存储器中数值调入E2中(仅地址2、3:TH,TL高低温触发)
#define RECALL_E2                                        0XB8 //将非易失性存储器中的数值重新调入暂存存储器
#define RD_POWER                                        0XB4  //发18B20电源方式的信号到主机

/******************************************************************
- 功能描述:延时函数
- 隶属模块:延时
- 函数属性:外部,供用户使用
- 参数说明:us:us级的延时
- 返回说明:无
- 注:无
******************************************************************/
void delay_us(uint us)                  
{
                  uint i;
                  us = us*5/4;                           //5/4是在8MHz晶振下,通过软件仿真反复实验得到的数值
                  for(i=0; i<us; i++);
}



/******************************************************************
- 功能描述:延时函数
- 隶属模块:延时
- 函数属性:外部,供用户使用
- 参数说明:ms:ms级的延时
- 返回说明:无
- 注:无
******************************************************************/
void delay(uint ms)                  
{
                  uint i,j;
                  for(i=0; i<ms; i++)
                     for(j=0; j<1141; j++);        
}



/******************************************************************
- 功能描述:18b20的初始化
- 隶属模块:18b20
- 函数属性:内部
- 参数说明:无
- 返回说明:无
- 注:无
******************************************************************/
void _18B20_Init(void)
{
                  DDRF |= BIT(DS18B20);      
                  PORTF &= ~BIT(DS18B20);      //主机(Master Tx)发送复位脉冲
                  delay_us(600);               //拉低至少480us
                  PORTF |= BIT(DS18B20);
                  delay_us(40);                                         //18B20等待15-60us再响应主机复位脉冲发存在脉冲
                  
                  DDRF &= ~BIT(DS18B20);       //配置为输入,等待18B20发主机发存在脉冲
                  while(PINF & BIT(DS18B20));  //等待18B20拉低总线(ds18b20 Tx)
                  delay_us(150);
                  while(!(PINF & BIT(DS18B20))); ////等待18B20释放总线
                  DDRF |= BIT(DS18B20);
}



/******************************************************************
- 功能描述:18b20的写入字节
- 隶属模块:18b20
- 函数属性:内部
- 参数说明:DaCmd为要写入的字节
- 返回说明:无
- 注:无
******************************************************************/
void Write_18B20(uchar DaCmd)   //所有写时间片操作至少需要60us
{
                  uchar i = 0;
                  for(i=0; i<8; i++)
                     {
                                   DDRF |= BIT(DS18B20);   //配置为输出
                                          PORTF &= ~BIT(DS18B20); //拉低总线,启动写数据位
                                          delay_us(2);            //每个独立的写周期都要1us的恢复时间
                              if(DaCmd & 0x01)
                                             PORTF |= BIT(DS18B20);   //DQ线拉低后15-60us,18b20对总线采样
                                        else                          //总线为高则写1操作,为低则写0操作
                                             PORTF &= ~BIT(DS18B20);         
                              delay_us(60);
                                        PORTF |= BIT(DS18B20);  //释放总线
                                        DaCmd >>= 1;        
                          }
                 delay_us(50);   
}



/******************************************************************
- 功能描述:18b20的读出字节
- 隶属模块:18b20
- 函数属性:内部
- 参数说明:无
- 返回说明:返回读出的字节
- 注:无
******************************************************************/
uchar Read_18B20(void)
{
                        uchar i = 0;
                        uchar recByte = 0;
                        for(i=0; i<8; i++)
                           {
                                    recByte >>= 1;
                                        DDRF |= BIT(DS18B20);    //配置为输出
                                        PORTF &= ~BIT(DS18B20);  //主机拉低总线,启起读操作
                             //delay_us(1);          //不能有延时
                                        PORTF |= BIT(DS18B20);
                                   delay_us(5);
                                        DDRF &= ~BIT(DS18B20);   //配置为输入,开始读取数据位
                                        if(PINF & BIT(DS18B20))
                                                recByte |= 0x80;
                                   delay_us(60);
                                }
                        return  recByte;
}



/******************************************************************
- 功能描述:18b20的分辨率调整
- 隶属模块:18b20
- 函数属性:外部
- 参数说明:RESOLU_9;RESOLU_10;RESOLU_11;RESOLU_12(对应9--12位分辨率)
- 返回说明:无
- 注:无
******************************************************************/
void Adjust_Resolu(uchar resolu)  //调整分辨率resolu:0x1f,0x3f,0x5f,0x7f
{                                                                                              //分别对应0.5c,0.25,0.125,0.0625

                  _18B20_Init();
                  Write_18B20(SKIP_ROM);
                  Write_18B20(WR_SCRATCHPAD);
                  Write_18B20(0x44);         //设置TH
                  Write_18B20(0x86);                    //设置TL
                  Write_18B20(resolu);                   //设置配置寄存器R1 R0=01(分辨率10bit)         
                  _18B20_Init();
                  Write_18B20(SKIP_ROM);
                  Write_18B20(COPY_SCRATCHPAD);
}




/******************************************************************
- 功能描述:18b20的读出温度
- 隶属模块:18b20
- 函数属性:外部
- 参数说明:无
- 返回说明:Temp_H:返回温度的16进制
- 注:g_TH, g_TL存放返回温度16进制的高低字节
******************************************************************/
uchar g_TH, g_TL;  //全局变量

uint Convert_T(void)
{   
          uint Temp_H = 0;   //定义为无符整型(16bit),最后用于存放温度
                  uchar Temp_L = 0;
                  uchar inter = 0;
                  uchar decim =0;
                  uchar i = 0;
          _18B20_Init();
                  Write_18B20(SKIP_ROM);  //单点总线,选择跳过ROM检测
                  Write_18B20(TEMP_TRANS);
                  delay(800);          //温度转换需要750ms的时间,不然每次读的是上次值
                                             
                  _18B20_Init();
                  Write_18B20(SKIP_ROM);
                  Write_18B20(RD_SCRATCHPAD);
          Temp_L = Read_18B20();    //该字节的低4位是温度的小数部分
                  Temp_H = Read_18B20();   //该字节的高5位是符号位,为0是表正温度,为1时为负
                  g_TH = Read_18B20();          //温度上限和下限,用于报警
          g_TL = Read_18B20();
                                    
                  Temp_H =(Temp_H<<8) | (Temp_L);   //转化为16位数据
                  return Temp_H;
}


/******************************************************************
- 功能描述:18b20的扩展性功能模块
- 隶属模块:18b20
- 函数属性:外部
- 参数说明:带入温度的16进制
- 返回说明:neg_flag:为负温度标志位
- 注:可以判断温度正负并转换为ACS码
******************************************************************/
uchar g_temperature[5];  //全局数组,用来存放温度

uchar Split_temp(uint temp_val)
{
          uchar inter = 0;
                  uchar decim = 0;
                  uchar neg_flag = 0;   //负数标记
                  if((temp_val) & (0xF000))
                                   {
                                                  temp_val = ~temp_val+1;
                                                neg_flag = 1;   //表明为负温度
                                 }
                  else
                       {
                                           neg_flag = 0;
                                 }               
                                 
                  inter = (uchar)(temp_val*0.0625);          //取整数部分                                                                          
                  decim = (uchar)(temp_val & 0xf)*0.625;  //10位分辨率bit0,bit1未定义,权值为0
                                                                                                         //扩大10倍,后取整,保留一位小数,有强制转换float->char                 
                  if(inter >= 100)
                            inter = 0;
                  g_temperature[0] = inter/10 +'0';
                  g_temperature[1] = inter%10 +'0';
                  g_temperature[2] = '.';
                  g_temperature[3] = decim +'0';
                  return neg_flag;
}

/******************************************************************
- 功能描述:向LCD中写入命令
- 隶属模块:LCD模块
- 函数属性:外部,供用户使用
- 参数说明:com:为命令控制字
- 返回说明:实现向LCD中写入控制命令
- 注:无
******************************************************************/
void write_com(uchar com)
{
       PORTB&=~BIT(0);  //RS
           PORTB&=~BIT(1);  //RW
           PORTD=com;
           PORTB|=BIT(2);   //EN
           delay(1);
           PORTB&=~BIT(2);  //EN
}

/******************************************************************
- 功能描述:向LCD中写入数据
- 隶属模块:LCD模块
- 函数属性:外部,供用户使用
- 参数说明:dat:为写入的数据
- 返回说明:实现向LCD中写入数据
- 注:无
******************************************************************/
void write_dat(uchar dat)
{     
       PORTB|=BIT(0);  //RS
           PORTB&=~BIT(1);  //RW
           PORTD=dat;
           PORTB|=BIT(2);   //EN
           delay(1);
           PORTB&=~BIT(2);   //EN
  
}

/******************************************************************
- 功能描述:LCD初始化
- 隶属模块:LCD模块
- 函数属性:内部
- 参数说明:无
- 返回说明:实现LCD的初始化
- 注:无
******************************************************************/
  void lcd_Init() //lcd初始化
{
      DDRD=0XFF;  //数据端
          DDRB|=BIT(0)|BIT(1)|BIT(2);   //控制端 RS RW EN
          PORTB&=~BIT(2);
          write_com(0X30);
          delay(1);
          write_com(0X01);
          delay(1);
          write_com(0X0C);
          delay(1);
          write_com(0X06); //如果为07且write_com(0X18)。。显示为右到左的现实直到消失,如果为06且write_com(0X18)为右到左显示
                           //07表示右边到左边显示出来。。06为光标处出现
}

void main()
{
   uchar i;
   uint Temperature,Tem;
   lcd_Init();               //液晶初始化
   Adjust_Resolu(RESOLU_11);
   while(1)
        {
          Temperature=(Convert_T());   //除以100保留小数点后2位,符合18b20的10位精度
          Tem=Temperature*6.25;
          g_temperature[4]=Tem/1000+'0';
          g_temperature[3]=Tem%1000/100+'0';
          g_temperature[2]='.';
          g_temperature[1]=Tem%100/10+'0';
          g_temperature[0]=Tem%10+'0';
          write_com(0X80);
          delay(1);
          write_dat(g_temperature[4]);
          delay(1);
          write_dat(g_temperature[3]);
          delay(1);
          write_dat(g_temperature[2]);
          delay(1);         
          write_dat(g_temperature[1]);
          delay(1);
          write_dat(g_temperature[0]);
          delay(1);
        }
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入因仑

本版积分规则

快速回复 返回顶部 返回列表