snow_waker 发表于 2007-12-30 10:45:20

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

代码如下,按键的程序参考马老师的程序,怀疑是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,time,ttime; //
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; //DS18B20 devices ROM code storage area

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

}

/*用于计算显示时间的中断程序*/
interrupt 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,-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 = 12; time = 00; time = 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 >= 60) // 秒数+1,如大于等于60秒,以下为时间调整
                {
                time = 0;
                        if (++time >= 60)
                        {
                        time = 0;
                        if (++time >= 24) time = 0;
                        }
                }
      }
/***********校对时间按键检测********************/
if (key_stime_ok) // 10ms 到,开始校对
   {
   key_stime_ok = 0;
   if (read_key_set()) //判断校对按键是否按下
       key_set=~key_set;
   if (read_key_sec()) // 调用按键接口程序
       { // 按键确认按下
      if (++time >= 60) // 秒加1,以下为时间调整
         {
         time = 0;
         if (++time >= 60)
            {
            time = 0;
            if (++time >= 24) time = 0;
            }
         }
       }
   if (read_key_min())
       { // 按键确认按下
         if (++time >= 60)
            {
            time = 0;
            if (++time >= 24) time = 0;
            }
       }      
   if (read_key_hor())    //&&key_set
       {//按键确认按下
         if (++time>=24)
         {
            time=0;
         }
       }
   }
/**************************************************/      
       temp=ds18b20_temperature(&rom_code);//取温度值
       inttemp= temp*10; //乘10取整数,小数点后一位变成个位
       temp_h=inttemp/10; //百位和十位取值成整数位,在小数点前显示
       temp_l=inttemp%10; //取余得个位,即小数点后一位
       /*判断正负温度*/
       //ds18b20_read_spd(&rom_code);
       if (__ds18b20_scratch_pad.temp_msb>>3)
                sign='-';   
       /*为符号位赋值*/
       display();
       display_temp();
      };
}

hl0716 发表于 2007-12-30 11:05:22

这么长啊

lcd128x64 发表于 2008-1-10 21:30:39

按键不是无效,而是要长按很长时间才会有用,按键接口函数read_key(void)有问题。
页: [1]
查看完整版本: 用马老师实验板+18b20+1602做的电子钟+温度计,电子钟校对时间按钮无效?请指正!