读书人

真是好的

发布时间: 2012-03-28 15:40:03 作者: rapoo

求助 真是好的
不知道哪位好心的人可以我
我真的做不出

以下是用AVR做的
包含LCD module (LCD 可示行) 部分已做出了 一定正


按A始算00:00.0始 到99:59.9
再按一次A停止 如跑到35:11.9 按A停在35:11.9再按一次A35:11.9 始(都示在第一行)

按B 停止在第二行 但第一行仍然在

按D 把所有0 就是回到00:00.0的

以下是LCD module 的程(一定正的)
是LCD_Ddriver.c
#include <avr/io.h>
#include <util/delay.h>
#include "LCD_Driver.h "

//internal funciton prototypes
void LCD_init();
void LCD_cmd_nibble(char c);
void LCD_dat_nibble(char c);

/* to write the higer nibble of a command to LCD module */
void LCD_cmd_nibble(char c)
{
//output the higher nibble to LCD with RS=0,RD=0,EN=0
LCD_PORT = c & 0xF0;
LCD_PORT = LCD_PORT | (1 < <EN);
_delay_us(1);//EN=1 for at least .5us
LCD_PORT = LCD_PORT & (~(1 < <EN));
_delay_us(1);//at least 1us for each cycle
}

/* to write the higer nibble of a data byte to LCD module */
void LCD_dat_nibble(char c)
{
//output the higher nibble to LCD with RS=0,RD=0,EN=0
LCD_PORT = c & 0xF0;
LCD_PORT = LCD_PORT | (1 < <RS);//for writing data
LCD_PORT = LCD_PORT | (1 < <EN);
_delay_us(1);//EN=1 for at least .5us
LCD_PORT = LCD_PORT & (~(1 < <EN));
_delay_us(1);//at least 1us for each cycle
}

/* to write a command to LCD module */
void LCD_command(char cmd)
{
LCD_cmd_nibble(cmd);//higher nibble
LCD_cmd_nibble(cmd < <4);//lower nibble
_delay_ms(2);//max cmd processing time: 1.64ms
}

/* to display a character in LCD module at the current position*/
void LCD_display(char character)
{
LCD_dat_nibble(character);//higher nibble
LCD_dat_nibble(character < <4);//lower nibble
_delay_us(50);//max data processing time: 40us
}

/* to initialize the LCD module */
void LCD_init()
{
_delay_ms(15);

LCD_DDR = 0xFF;//LCD port as output

LCD_cmd_nibble(0x30);//set the LCD module as 8-bit mode three times
_delay_ms(5);
LCD_cmd_nibble(0x30);
_delay_ms(5);
LCD_cmd_nibble(0x30);
_delay_ms(5);

LCD_cmd_nibble(0x20);//set the LCD module as 4-bit mode
_delay_ms(5);

//from now on the LCD module works as 4-bit mode
//write cmd as normal
LCD_command(0x28);//4-bit mode, 2-line dispay, 5x7 dot char font


LCD_command(0x08);//display OFF
LCD_command(0x01);//clear dispay
LCD_command(0x06);//cursor increment, no shift
LCD_command(0x0F);//dispay ON with cursor on and blinking
}

是LCD_Ddriver.h

#ifndef LCD_DRIVER_H
#define LCD_DRIVER_H


#define LCD_PORTPORTB
#define LCD_DDRDDRB
#define RS0//pin0
#define RD1//pin1
#define EN2//pin2
//pin3: unused
//pin4-pin7: 4-bit data bus

/****** LCD funciton prototypes *********/
void LCD_init();//must be called before the LCD module is usable
void LCD_command(char cmd);//write a command to LCD module
void LCD_display(char ch);//display a character in LCD module
//at the current position set by LCD_command()

#endif


以下就是要做的主程式
我只把一些字示在LCD上 但不
以下就是示在LCD上的字的程
#include <avr/io.h>
#include <util/delay.h>

#include "LCD_Driver.h "

int main()
{
char str[]= "Hello, world! ";
int i;

//initialize LCD module
LCD_init();

//write character to LCD to display
LCD_display( 'A ');

//move cursor to 2nd line, 1st position and then display characters
LCD_command(0xC0);
i=0;
while(str[i])
{
LCD_display(str[i++]);
}

while(1);
return 0;
}




[解决办法]
计时需要用到AVR片内定时器(我没有用过,你自己去看spec啊)。设置定时器10ms中端一次(100ms也行,随便你)。自己handle定时器中断。伪代码如下:
void timer_isr(void)
{
if (run)
{
++timer_reg;
if (有必要更新显示数据)
刷新LCD显示数据;
}
}

键盘中断处理程序如下:
void key_isr(void)
{
switch (key)
{
case A:
run = !run;
break;
case B:
// do something
break;
case D;
run = 0;
把时间寄存器置零;
break;
}
}

main函数做一下初始化,然后就可以睡大觉了。
[解决办法]
想LCD中输出字符的是这句
LCD_display( '5 ');
首先你获取时间tm
然后分别提取出tm的年月日时分秒,以整数形式保存到如下变量中。
int year,month,day,hour,minute,second;
将整数转换为字符的函数在你的库文件中已提供
ToString(data, data_str);
例如:
char str_year[5];
ToString(year,str_year);
然后依次往设备中输出str_year的字符就可以了
int i=0;
while(1)
{
ch = data_str[i];
if (ch == '\0 ')
{
break;
}
LCD_display(ch);
i++;
}
依次类推,月日时分秒也输出。
如果输出期间发生输出不停止或乱码,甚至内存地址访问出错,注意检查每次将
数字转换为字符后 '\0 '的位置是否准确。
[解决办法]
利用午休时间做的,不太严谨,但应该够你参考了。
首先说一声,如果你的要求不是windows平台的,那就别往下看了,请教高人去吧……
#include <iostream>
using namespace std;
#include <windows.h>
#include <mmsystem.h>
bool time_change_string(DWORD dw,char * szData);
void main()
{
DWORD dwTimeBegin=timeGetTime();//起始时间
DWORD dwCurrentTime=timeGetTime();//当前时间


DWORD dwPauseTime = 0; //中断的时间,既暂停的时间
char strCount[20]= " ";//计时时间字符内容
char strPause[20]= " "; //暂停时间字符内容
BOOL bContinue=TRUE;//表示当前是否处于计时状态
int Key_A_State=0; //状态变量,0表示没有按过A,1表示已经按过A
//该变量影响是否重新计时
BOOL bDown=FALSE;
while(1)
{
system( "cls ");

if(bContinue)
dwCurrentTime=timeGetTime();
else
dwCurrentTime=dwCurrentTime;

//如果按下D,则重置起始时间
if(GetAsyncKeyState( 'D ') & 0x8000)
dwTimeBegin=timeGetTime();
//如果按下B,确定暂停时间字符串
if(GetAsyncKeyState( 'B ') & 0x8000)
time_change_string(dwCurrentTime-dwTimeBegin,strPause);
//如果抬起A,设置状态变量Key_A_State为0
if(!(GetAsyncKeyState( 'A ') & 0x8000))
{
Key_A_State=0;
}
//如果按下A,计时暂停
if(GetAsyncKeyState( 'A ') & 0x8000)
{
if(Key_A_State==0)
{
if(bDown)
{
//如果Key_A_State==1,那么这时按下A表示继续计时
//要让起始时间变为加上暂停的总时间
//例如:12:08:2 时暂停,12:12:5时重新开始计时
//那要让起始时间增加00:04:3才能达到效果
dwTimeBegin += (timeGetTime()-dwPauseTime);
bContinue=TRUE;
bDown=FALSE;
}
else
{
bContinue=FALSE;
dwPauseTime = dwCurrentTime;
bDown=TRUE;
}
}
Key_A_State=1;
}
time_change_string(dwCurrentTime-dwTimeBegin,strCount);
cout < <strCount < <endl;
cout < <strPause < <endl;
}
system( "pause ");
}

bool time_change_string(DWORD dw,char * szData)
{
//szData的总长度没做过多检测,请传递实参时确认一下其字符长度大于等于8个字符
if(!szData)
return false;
int count_seconds=dw/1000;//总秒数
int count_minutes=count_seconds/60;//总分数

//*************确定分钟字符内容*******************//
if(count_minutes==0)
{
//如果一分钟都没有,确定分钟的字符 "00 "
szData[0]=szData[1]= '0 ';
}
else
{
if(count_minutes <10)
{
//小于10分
szData[0]= '0 ';
wsprintf(szData+1, "%d ",count_minutes);
}
else
{
wsprintf(szData, "%d ",count_minutes);
}
}
szData[2]= ': ';
//***************分钟结束*********************//


//*************确定秒字符内容*******************//
count_seconds%=60;//总秒数变为去掉分钟后的剩余秒数
if(count_seconds==0)
{
//如果是整分,确定秒的字符 "00 "
szData[3]=szData[4]= '0 ';
}
else
{
if(count_seconds <10)
{
//小于10秒
szData[3]= '0 ';
wsprintf(szData+4, "%d ",count_seconds);
}
else
{
wsprintf(szData+3, "%d ",count_seconds);
}
}
szData[5]= ': ';
//***********************秒结束*****************//

//********************十分之一秒***************//
dw%=1000; //dw变为去掉所有秒以后的滴答计数
int count_milseconds = dw/100; //十分之一秒总数,保证只有1位数字
wsprintf(szData+6, "%d ",count_milseconds);
szData[8]= '\0 ';
//********************十分之一秒结束***********//
}


bool time_change_string(DWORD dw,char * szData)是我自己做的将滴答计数转换为字符的函数
其实你完全可以把内部代码换成ToString,你自己的库方法。

timeGetTime()是获取从你的计算机开机后到当前的总滴答计数,大约每秒为1000次。
也就是说,第二次调用该函数得到的返回值减去第一次调用的返回值,就是2次间隔的滴答数之差。
但该函数要求包含#include <mmsystem.h> ,而且你的项目属性里要包含附加依赖项winmm.lib。
返回值为DWORD,所以包含一下 <windows.h>

读书人网 >C语言

热点推荐