搜索
bottom↓
回复: 2

用马老师实验板+18b20+1602做的电子钟+温度计,电子钟校对时间按钮无效?请指正!

[复制链接]

出0入0汤圆

发表于 2007-12-30 10:45:20 | 显示全部楼层 |阅读模式
代码如下,按键的程序参考马老师的程序,怀疑是B口的问题,我最开始吧18b20接在B口上就怎么也检测不到,这次是按键检测不到,换了一块M16也是这个问题,其他都正常。

/*****************************************************
Project :   18B20测温代码
Version :           
Date    : 2007-12-28
Author  : Jeff                        
Company :                                 
Comments:  CodeVisionAVR1.25.7Prof.中调试成功   

Chip type           : ATmega16L
Program type        : Application
Clock frequency     : 4.000000 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 256
/*   1602和MEGA 16L的连接方式如下:                                           */
/*     RS------> PC0                                                          */
/*     RW------> PC1                                                          */
/*     E ------> PC2                                                          */
/*     FREE----> PC3                                                          */
/*     D4------> PC4                                                          */
/*     D5------> PC5                                                          */
/*     D6------> PC6                                                          */
/*     D7------> PC7                                                          */
/*  修改时间按键与16L的连接  */
/*     k1------> PB0         */
/*     k2------> PB1         */
/*     k3------> PB2         */
/*     k4------> PB3         */
/*****************************************************/
#define MAX_DEVICES 8  
#include <mega16.h>
#include <delay.h>
#include <stdio.h>


// DS1820 Temperature Sensor functions
#include <ds18b20.h>
#include <lcd.h>
#asm
.equ __lcd_port=0x15
#endasm

// 1 Wire Bus functions
#include <1wire.h>
#asm
   .equ __w1_port=0x1b
   .equ __w1_bit=0
#endasm

int inttemp,temp_h,temp_l;
float temp;//定义温度  
//struct __ds18b20_scratch_pad_struct __ds18b20_scratch_pad;
char sign='';        
char lcd_buffer[33],time[3],ttime[6]; //
char time_counter,key_stime_counter;
bit time_1s_ok,key_stime_ok,key_set=0;
unsigned char ds18b20_devices;//number of DS1820 devices connected to the 1 Wire bus                       
unsigned char rom_code[MAX_DEVICES][9]; //DS18B20 devices ROM code storage area

void display(void)
{
       lcd_clear();
       lcd_gotoxy(0,0);
       ttime[5]=time[2]/10;
       ttime[4]=time[2]%10;
       ttime[3]=time[1]/10;
       ttime[2]=time[1]%10;
       ttime[1]=time[0]/10;
       ttime[0]=time[0]%10;
       sprintf(lcd_buffer,"TIME:%d%d:%d%d:%d%d\n",ttime[5],ttime[4],ttime[3],ttime[2],ttime[1],ttime[0]);//把现实内容放入显示buffer
       lcd_puts(lcd_buffer);

}

/*用于计算显示时间的中断程序*/
interrupt [TIM0_COMP] void timer0_comp_isr(void)
{
  //display(); // LCD 扫描显示
  if (++key_stime_counter >=5)
  {
    key_stime_counter = 0;
    key_stime_ok = 1; // 10ms 到
    if (++time_counter >= 100)
     {
       time_counter = 0;
       time_1s_ok = 1; // 1s 到
     }
   }
}



void display_temp(void)
{
       lcd_gotoxy(0,1);
       sprintf(lcd_buffer,"TEMP:%s%d.%d\xDFC\n\r",sign,temp_h,temp_l);
       lcd_puts(lcd_buffer);
       delay_ms(500);   
}

/*按键检测程序*/
#define key_input_sec PINB.0 // 秒校对按键输入口
#define key_input_min PINB.1 // 分校对按键输入口
#define key_input_hor PINB.2 // 时校对按键输入口  
#define key_input_set PINB.3 // 校对开始按键
#define key_state_0 0
#define key_state_1 1
#define key_state_2 2

char read_key_set(void)
{
  static char key_state_set = 0;
  char key_press, key_return = 0;
  key_press = key_input_set; // 读按键I/O 电平
  switch (key_state_set)
    {
      case key_state_0: // 按键初始态
        if (!key_press) key_state_set = key_state_1; // 键被按下,状态转换到键确认态
        break;
      case key_state_1: // 按键确认态
        if (!key_press)
        {
          key_return = 1; // 按键仍按下,按键确认输出为"1"
          key_state_set = key_state_2; // 状态转换到键释放态
         }
        else
        key_state_set = key_state_0; // 按键已抬起,转换到按键初始态
        break;
     case key_state_2:
        if (key_press) key_state_set = key_state_0; //按键已释放,转换到按键初始态
        break;
    }
    return key_return;
}  

char read_key_sec(void)
{
  static char key_state_sec = 0;
  char key_press, key_return = 0;
  key_press = key_input_sec; // 读按键I/O 电平
  switch (key_state_sec)
    {
      case key_state_0: // 按键初始态
        if (!key_press) key_state_sec = key_state_1; // 键被按下,状态转换到键确认态
        break;
      case key_state_1: // 按键确认态
        if (!key_press)
        {
          key_return = 1; // 按键仍按下,按键确认输出为"1" (1)
          key_state_sec = key_state_2; // 状态转换到键释放态
         }
        else
        key_state_sec = key_state_0; // 按键已抬起,转换到按键初始态
        break;
     case key_state_2:
        if (key_press) key_state_sec = key_state_0; //按键已释放,转换到按键初始态
        break;
    }
    return key_return;
}  

char read_key_min(void)
{
  static char key_state_min = 0;
  char key_press, key_return = 0;
  key_press = key_input_min; // 读按键I/O 电平
  switch (key_state_min)
    {
      case key_state_0: // 按键初始态
        if (!key_press) key_state_min = key_state_1; // 键被按下,状态转换到键确认态
        break;
      case key_state_1: // 按键确认态
        if (!key_press)
        {
          key_return = 1; // 按键仍按下,按键确认输出为"1" (1)
          key_state_min = key_state_2; // 状态转换到键释放态
         }
        else
        key_state_min = key_state_0; // 按键已抬起,转换到按键初始态
        break;
     case key_state_2:
        if (key_press) key_state_min = key_state_0; //按键已释放,转换到按键初始态
        break;
    }
    return key_return;
}

char read_key_hor(void)
{
  static char key_state_hor = 0;
  char key_press, key_return = 0;
  key_press = key_input_hor; // 读按键I/O 电平
  switch (key_state_hor)
    {
      case key_state_0: // 按键初始态
        if (!key_press) key_state_hor = key_state_1; // 键被按下,状态转换到键确认态
        break;
      case key_state_1: // 按键确认态
        if (!key_press)
        {
          key_return = 1; // 按键仍按下,按键确认输出为"1" (1)
          key_state_hor = key_state_2; // 状态转换到键释放态
         }
        else
        key_state_hor = key_state_0; // 按键已抬起,转换到按键初始态
        break;
     case key_state_2:
        if (key_press) key_state_hor = key_state_0; //按键已释放,转换到按键初始态
        break;
    }
    return key_return;
}



/*ds18b20初始化程序*/
void DS18B20_cfg(void)
          //Search DS18B20 Device and Configure each DS18B20 device;
{   
    unsigned char i;
    // detect how many DS18B20 devices are connected to the 1 Wire bus  
    ds18b20_devices=w1_search(DS18B20_SEARCH_ROM_CMD,rom_code);   
   
    // configure each DS18B20 device for 12 bit temperature measurement resolution  
    for (i=0;i<ds18b20_devices;i++)
      ds18b20_init(&rom_code[i++][0],-20,30,DS18B20_12BIT_RES);
}  

/************************************************************************/
void main(void)
{
//PORTA = 0x00;
DDRB = 0x00;
TCCR0 = 0x0B; // 内部时钟,64 分频(4M/64=62.5KHz),CTC 模式
TCNT0 = 0x00;
OCR0 = 0x7C; // OCR0 = 0x7C(124),(124+1)/62.5=2ms
TIMSK = 0x02; // 允许T/C0 比较匹配中断
time[2] = 12; time[1] = 00; time[0] = 00; // 设时间初值12:00:00
w1_init();// 1 Wire Bus initialization
lcd_init(16);
lcd_clear();
lcd_gotoxy(0,0);
DS18B20_cfg(); //检测DS18B20是否存在

if(ds18b20_devices)
{
lcd_putsf("Init Successful");  
}
else
{  
   lcd_putsf("ERROR !!!");
   lcd_gotoxy(0,1);
   lcd_putsf("Out of connect!");
   while(1);
}
#asm("sei")
while(1)
      {
/*时间累加程序*/      
      if (time_1s_ok) // 1 秒到
        {
        time_1s_ok = 0;
       // point_on = ~point_on; // 秒闪烁标志
        if (++time[0] >= 60) // 秒数+1,如大于等于60秒,以下为时间调整
                {
                time[0] = 0;
                        if (++time[1] >= 60)
                        {
                        time[1] = 0;
                        if (++time[2] >= 24) time[2] = 0;
                        }
                }
        }
/***********校对时间按键检测********************/
  if (key_stime_ok) // 10ms 到,开始校对
   {
     key_stime_ok = 0;
     if (read_key_set()) //判断校对按键是否按下
       key_set=~key_set;
     if (read_key_sec()) // 调用按键接口程序
       { // 按键确认按下
        if (++time[0] >= 60) // 秒加1,以下为时间调整
         {
         time[0] = 0;
           if (++time[1] >= 60)
            {
              time[1] = 0;
              if (++time[2] >= 24) time[2] = 0;
            }
         }
       }
     if (read_key_min())
       { // 按键确认按下
           if (++time[1] >= 60)
            {
              time[1] = 0;
              if (++time[2] >= 24) time[2] = 0;
            }
       }      
     if (read_key_hor())    //&&key_set
       {//按键确认按下
         if (++time[2]>=24)
           {
              time[2]=0;
           }
       }
     }  
/**************************************************/      
       temp=ds18b20_temperature(&rom_code[0][0]);//取温度值
       inttemp= temp*10; //乘10取整数,小数点后一位变成个位
       temp_h=inttemp/10; //百位和十位取值成整数位,在小数点前显示
       temp_l=inttemp%10; //取余得个位,即小数点后一位
       /*判断正负温度*/
       //ds18b20_read_spd(&rom_code[0][0]);
       if (__ds18b20_scratch_pad.temp_msb>>3)
                sign='-';   
       /*为符号位赋值*/
       display();
       display_temp();
      };
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2007-12-30 11:05:22 | 显示全部楼层
这么长啊

出0入0汤圆

发表于 2008-1-10 21:30:39 | 显示全部楼层
按键不是无效,而是要长按很长时间才会有用,按键接口函数read_key(void)有问题。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-18 15:31

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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