用马老师实验板+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();
};
} 这么长啊 按键不是无效,而是要长按很长时间才会有用,按键接口函数read_key(void)有问题。
页:
[1]