Protues仿真LCD1602闹钟,闹钟音乐是一首天空之城。
本帖最后由 downtoearth 于 2013-3-20 22:39 编辑全部代码是自己编写的,没有一句抄杂,这有一点满足感。程序只用到一个大循环,本来想试试
多任务的,(调度机)但想不通当任务被调用时,被调用的函数体应该怎样写,还有那些
参数怎样交换。于是就写成现在这个样子。程序是没有阻塞cpu的地方。有兴趣的朋友可以看看!
程序有小个BUG,有点累不想改了。不知有没有人找到出来!有心看的就可以找到操作方法,不想说了!
这里高手多,望有高手指点下!
仿真文件:
程序:/********************************************************************
Program_Name : LCD1602 Clock
Writers : neo
Writing Time : 2013/3/6 To 2013/3/20
Hardware Support :LCD1602 AT89C51
********************************************************************/
#include <reg51.h>
#include <intrins.h>
#include "..\My_Header_Files\MacroAndConst.H"
/*******************************************************************/
#define LCD_DataIO P0
#define FirstRow 0
#define SecondRow1
#define ON 1
#define OFF 0
#define Delay() { _nop_() ; _nop_(); }
/*******************************************************************/
sbit LCD_RS = P2^0 ;
sbit LCD_RW = P2^1 ;
sbit LCD_EN = P2^2 ;
sbit DS1302_RST= P3^0 ;
sbit DS1302_SCLK = P3^1 ;
sbit DS1302_IO = P3^2 ;
sbit Buzzer = P3^6 ;
/*******************************************************************/
uint code Table[]= {// 1 #1 2 #2 3 4 #4 5 #5 6 #6 7
63628,63731,63835,63928,64021,64103,64185,64260,64331,64400,64463,64524,//低音1-7
64580,64633,64684,64732,64777,64820,64860,64898,64934,64968,64994,65030, //中音1-7
65058,65085,65110,65134,65157,65178,65198,65217,65235,65252,65268,65283 //高音1-7
};
//1 #1 2 #2 3 4 #4 5 #5 6 #6 7
enum {L_DO, L_sDO,L_RE, L_sRE, L_ME,L_FA, L_sFA,L_SO, L_sSo, L_LA, L_sLA, L_SI,// 12
DO, sDO, RE, sRE, ME, FA, sFA, SO, sSo, LA, sLA, SI,// 12
H_DO, H_sDO,H_RE, H_sRE, H_ME,H_FA, H_sFA,H_SO, H_sSo, H_LA, H_sLA, H_SI, End, Zero}; // 14
uchar code SkyCity_ThemeSongTable[] =
{
LA,SI,H_DO,SI,H_DO,H_ME,SI,ME,ME,LA,SO,LA,H_DO,SO,Zero,ME,ME,FA,ME,FA,H_DO, // 21
ME,Zero,H_DO,H_DO,H_DO,SI,sFA,sFA,SI,SI,Zero,LA,SI,H_DO,SI,H_DO,H_ME,SI,Zero,ME,ME,LA,SO,LA,H_DO, // 25
SO,Zero,ME,FA,H_DO,SI,SI,H_DO,H_RE,H_RE,H_ME,H_DO,Zero,H_DO,SI,LA,LA,SI,sSo,LA,Zero,H_DO,H_RE,H_ME,H_RE,H_ME,H_SO, //27
H_RE,Zero,SO,SO,H_DO,SI,H_DO,H_ME,H_ME,Zero,Zero,LA,SI,H_DO,SI,H_RE,H_RE,H_DO,SO,SO,Zero,H_FA,H_ME,H_RE,H_DO, // 25
H_ME,H_ME,Zero,H_ME,H_LA,H_SO,H_SO,H_ME,H_RE,H_DO,Zero,H_DO,H_RE,H_DO,H_RE,H_RE,H_SO,H_ME,Zero,H_ME, // 20
H_LA,H_SO,H_ME,H_RE,H_DO,Zero,H_DO,H_RE,H_DO,H_RE,H_RE,SI,LA,Zero,LA,SI,LA,End// 18
};
uchar code Beat[] =
{
4,4,8,4,8,8,32,4,4,8,4,8,8,16,8,4,4,8,4,4,8,
16,4,4,4,4,8,4,8,8,16,8,4,4,8,4,8,8,16,8,4,4,8,4,8,8,
32,4,4,8,4,4,8,8,4,4,4,8,8,8,4,4,4,8,8,16,8,4,4,8,4,8,8,
16,8,4,4,4,4,8,8,16,8,8,4,4,8,8,4,4,8,4,8,8,8,8,8,8,
64,16,8,8,16,8,8,4,4,8,4,4,8,4,4,4,8,16,8,8,
16,16,4,4,16,4,4,8,4,4,4,8,16,8,4,4,64
};
bit g_bSystemTime40Ms0 ;
bit g_bSystemTime40Ms1 ;
bit g_bPlayMusic ;
bit g_bSetFlag ;
bit g_bAlertOpenAndClose ;
uint TempTH0 , TempTL0 ;
/*******************************************************************/
uchar LCD1602_ReadBusy(void)
{
uchar BusyState ;
LCD_RS = 0 ;
LCD_RW = 1 ;
LCD_EN = 1 ;
Delay() ;
BusyState = LCD_DataIO ;
LCD_EN = 0 ;
return BusyState ;
}
/*******************************************************************/
void LCD1602_WriteCommand(uchar LCD_Com)
{
while ( LCD1602_ReadBusy()&0x80 ) ;
LCD_RS = 0 ;
LCD_RW = 0 ;
LCD_EN = 1 ;
LCD_DataIO = LCD_Com ;
Delay() ;
LCD_EN = 0 ;
}
/*******************************************************************/
void LCD1602_WriteData(uchar LCD_Data)
{
while ( LCD1602_ReadBusy()&0x80 ) ;
LCD_RS = 1 ;
LCD_RW = 0 ;
LCD_EN = 1 ;
LCD_DataIO = LCD_Data ;
Delay() ;
LCD_EN = 0 ;
}
/*******************************************************************/
void LCD1602_Init(void)
{
LCD1602_WriteCommand(0x38) ;
LCD1602_WriteCommand(0x06) ;
LCD1602_WriteCommand(0x0c) ;
LCD1602_WriteCommand(0x01) ;
}
/*******************************************************************/
void LCD1602ShowChar(bit x , uchar y ,uchar C)
{
if ( x ) LCD1602_WriteCommand(0xc0+y) ;
else LCD1602_WriteCommand(0x80+y) ;
LCD1602_WriteData(C) ;
}
/*******************************************************************/
void LCD1602ShowString(bit x , uchar y ,uchar *str)
{
if ( x ) LCD1602_WriteCommand(0xc0+y) ;
else LCD1602_WriteCommand(0x80+y) ;
while (*str)
{
LCD1602_WriteData(*str) ;
str++ ;
}
}
/*******************************************************************/
void Timer0_Init (void)
{
TMOD |= 0x01 ;
TH0 = TempTH0 ;
TL0 = TempTL0 ;
ET0 = 1 ;
EA = 1 ;
}
/*******************************************************************/
void Timer0_Isr (void) interrupt 1 using 1
{
TH0 = TempTH0 ;
TL0 = TempTL0 ;
Buzzer = ~Buzzer ;
}
/*******************************************************************/
void Timer1_Init (void)
{
TMOD |= 0x10 ;
TH1 = -40000 / 256 ;
TL1 = -40000 % 256 ;
ET1 = 1 ;
EA = 1 ;
TR1 = 1 ;
}
/*******************************************************************/
void Timer1_Isr (void) interrupt 3 using 1
{
TH1 = -40000 / 256 ;
TL1 = -40000 % 256 ;
g_bSystemTime40Ms0 = 1 ;
g_bSystemTime40Ms1 = 1 ;
}
/*******************************************************************/
void PlayMusic (void)
{
static uchar s_u8BeatCount ;
static uchar i ;
if ( g_bPlayMusic == ON )
{
if ( g_bSystemTime40Ms0 )
{
g_bSystemTime40Ms0 = 0 ;
if ( ++s_u8BeatCount == Beat )
{
s_u8BeatCount = 0 ;
if ( SkyCity_ThemeSongTable == Zero ) TR0 = 0 ;
else {
TempTH0 = Table] / 256 ;
TempTL0 = Table] % 256 ;
TR0 = 1 ;
}
i++ ;
if ( SkyCity_ThemeSongTable == End )
{
TR0 = 0 ;
i = 0 ;
g_bPlayMusic = g_bAlertOpenAndClose = OFF ;
LCD1602ShowChar(SecondRow,14,' ') ;
}
}
}
}
else {
TR0 = 0 ;
i = 0 ;
s_u8BeatCount = 0 ;
}
}
/*******************************************************************/
sbit SetKey = P1^0 ;
sbit PlusKey = P1^1 ;
sbit ReduceKey= P1^2 ;
sbit ConfirmKey = P1^3 ;
void GetKey(uchar *pKeyValue)
{
static uchar s_u8State = 0x10 ;
uchar KeyTemp = 0x00 ;
uchar LastKey = 0x00 ;
if ( !SetKey ) KeyTemp = 0x01 ;
if ( !PlusKey ) KeyTemp = 0x02 ;
if ( !ReduceKey ) KeyTemp = 0x03 ;
if ( !ConfirmKey ) KeyTemp = 0x04 ;
switch ( s_u8State )
{
case 0x10 : if ( KeyTemp != 0x00 ) s_u8State = 0x20 ;
break ;
case 0x20 : if ( KeyTemp != 0x00 ) {
s_u8State = 0x30 ;
LastKey = KeyTemp ;
}
else s_u8State = 0x10 ;
break ;
case 0x30 : if ( KeyTemp == 0x00 ) s_u8State = 0x10 ;
break ;
}
*pKeyValue = LastKey ;
}
/*******************************************************************/
uchar DS1302Read (uchar Address)
{
uchar i ;
uchar DataTemp = 0x00 ;
DS1302_RST = 1 ;
for ( i=0 ; i<8 ; i++)
{
DS1302_IO = Address & 0x01 ;
DS1302_SCLK = 0 ;
Address >>=1 ;
DS1302_SCLK = 1 ;
}
for ( i=0 ; i<8 ; i++ )
{
DataTemp >>= 1;
DS1302_SCLK = 0 ;
if ( DS1302_IO ) DataTemp |= 0x80 ;
DS1302_SCLK = 1 ;
}
DS1302_RST = DS1302_SCLK = DS1302_IO = 0 ;
return DataTemp ;
}
/*******************************************************************/
void DS1302Write(uchar Address, uchar Data)
{
uchar i ;
DS1302_RST = 1 ;
for ( i=0 ; i<8 ; i++)
{
DS1302_IO = Address & 0x01 ;
DS1302_SCLK = 1 ;
Address >>=1 ;
DS1302_SCLK = 0 ;
}
for ( i=0 ; i<8 ; i++ )
{
DS1302_IO = Data & 0x01 ;
DS1302_SCLK = 1 ;
Data >>= 1 ;
DS1302_SCLK = 0 ;
}
DS1302_RST = DS1302_SCLK = DS1302_IO = 0 ;
}
/*******************************************************************/
void DisplayAndSetTime (uchar KeyValue ,uchar *DispBuff)
{
uchar Second , Minute , Hour ;
uchar TempSecond ;
static char TempMinute, TempHour ;
static bit SelectMinuteAndHour ;
static bit SetTimeMode ;
Second = DS1302Read(0x81) ;
switch ( KeyValue )
{
case 0x01 : if ( !SetTimeMode ) {
SetTimeMode = 1 ;
g_bSetFlag= 1 ;
TempMinute =( Minute / 16 ) * 10+ Minute % 16 ;
TempHour =( Hour / 16 ) * 10+ Hour % 16 ;
}
else SelectMinuteAndHour = ~SelectMinuteAndHour ;
break ;
case 0x02 : if ( SetTimeMode ) {
if ( !SelectMinuteAndHour && ++TempHour > 23 ) TempHour = 0 ;
if (SelectMinuteAndHour && ++TempMinute > 59 ) TempMinute = 0 ;
}
break ;
case 0x03 : if ( SetTimeMode ) {
if ( !SelectMinuteAndHour && --TempHour < 0) TempHour = 0 ;
if (SelectMinuteAndHour && --TempMinute < 0 )TempMinute = 0 ;
}
break ;
case 0x04 : if ( SetTimeMode ){
SetTimeMode = SelectMinuteAndHour = 0 ;
Minute = (TempMinute / 10 )<<4 | TempMinute % 10 ;
Hour = (TempHour / 10 )<<4 | TempHour % 10 ;
DS1302Write(0x8e,0x00) ;
DS1302Write(0x82,Minute) ;
DS1302Write(0x84,Hour) ;
DS1302Write(0x8e,0x80) ;
g_bSetFlag= 0 ;
}
else g_bPlayMusic = g_bAlertOpenAndClose = OFF ;
break ;
}
if (!SetTimeMode) {
if ( Second != TempSecond ){
TempSecond = Second ;
Minute = DS1302Read(0x83) ;
Hour = DS1302Read(0x85) ;
DispBuff = ' ' ;
DispBuff = Second % 16 + '0' ;
DispBuff = Second / 16 + '0' ;
DispBuff = ':' ;
DispBuff = Minute % 16 + '0' ;
DispBuff = Minute / 16 + '0' ;
DispBuff = ':' ;
DispBuff = Hour % 16 + '0' ;
DispBuff = Hour / 16 + '0' ;
DispBuff = ' ' ;
LCD1602ShowString(FirstRow,2,"Current Time ") ;
LCD1602ShowString (SecondRow,3,DispBuff);
}
}
else {
DispBuff = Second % 16 + '0' ;
DispBuff = Second / 16 + '0' ;
DispBuff = ':' ;
DispBuff = TempMinute % 10 + '0' ;
DispBuff = TempMinute / 10 + '0' ;
DispBuff = ':' ;
DispBuff = TempHour % 10 + '0' ;
DispBuff = TempHour / 10 + '0' ;
if (Second%2) {
if (SelectMinuteAndHour ) DispBuff = DispBuff = ' ' ;
else DispBuff = DispBuff = ' ' ;
}
LCD1602ShowString(FirstRow,2,"Set Time") ;
LCD1602ShowString (SecondRow,4,DispBuff);
}
}
/*******************************************************************/
void DisplayAndSetDate (uchar KeyValue,uchar *DispBuff)
{
uchar Day , Month , Year ;
uchar code EverMonthDay ={31,28,31,30,31,30,31,31,30,31,30,31} ;
uchar Second, TempSecond ;
charTempDay , TempMonth , TempYear ;
static uchar s_u8SetDateState ;
static bit SetDateMode ;
Second = DS1302Read(0x81) ;
switch ( KeyValue )
{
case 0x01 : if ( !SetDateMode ) {
SetDateMode = 1 ;
g_bSetFlag= 1 ;
TempDay = ( Day >> 4 ) * 10 + Day % 16 ;
TempMonth = ( Month >> 4 ) * 10 + Month % 16 ;
TempYear= ( Year >>4 ) * 10 + Year % 16;
}
else s_u8SetDateState = (s_u8SetDateState+1) % 3;
break ;
case 0x02 : if ( SetDateMode )
{
switch ( s_u8SetDateState )
{
case 0 : if ( ++TempYear >99 ) TempYear = 0 ; break ;
case 1 : if ( ++TempMonth > 12 ) TempMonth= 0 ; break ;
case 2 : if ( ++TempDay > EverMonthDay) TempDay = 0 ; break ;
}
}
break ;
case 0x03 : if ( SetDateMode )
{
switch ( s_u8SetDateState )
{
case 0 : if ( --TempYear< 0 ) TempYear = 99 ; break ;
case 1 : if ( --TempMonth < 0 ) TempMonth= 12 ; break ;
case 2 : if ( --TempDay < 0 ) TempDay= EverMonthDay ;break ;
}
}
break ;
case 0x04 : if ( SetDateMode ){
SetDateMode = s_u8SetDateState = 0 ;
Day = (TempDay / 10 )<<4 | TempDay % 10 ;
Month= (TempMonth / 10 )<<4 | TempMonth % 10 ;
Year = (TempYear/ 10 )<<4 | TempYear% 10 ;
DS1302Write(0x8e,0x00);
DS1302Write(0x86,Day) ;
DS1302Write(0x88,Month) ;
DS1302Write(0x8c,Year);
DS1302Write(0x8e,0x80);
g_bSetFlag= 0 ;
}
elseg_bPlayMusic = g_bAlertOpenAndClose = OFF ;
break ;
}
if ( !SetDateMode ){
if (Second != TempSecond ) {
TempSecond = Second ;
Day = DS1302Read(0x87) ;
Month = DS1302Read(0x89) ;
Year= DS1302Read(0x8d) ;
DispBuff = '2' ;
DispBuff = '0' ;
DispBuff = Year/ 16 + '0' ;
DispBuff = Year% 16 + '0' ;
DispBuff = '-' ;
DispBuff = Month / 16 + '0' ;
DispBuff = Month % 16 + '0' ;
DispBuff = '-' ;
DispBuff = Day / 16 + '0' ;
DispBuff = Day % 16 + '0' ;
LCD1602ShowString(FirstRow,2,"Current Date ") ;
LCD1602ShowString(SecondRow,3,DispBuff) ;
}
}
else {
DispBuff = '2' ;
DispBuff = '0' ;
DispBuff = TempYear/ 10 + '0' ;
DispBuff = TempYear% 10 + '0' ;
DispBuff = '-' ;
DispBuff = TempMonth / 10 + '0' ;
DispBuff = TempMonth % 10 + '0' ;
DispBuff = '-' ;
DispBuff = TempDay / 10 + '0' ;
DispBuff = TempDay % 10 + '0' ;
if (Second%2) {
switch ( s_u8SetDateState )
{
case 0 : DispBuff = 0xff ; DispBuff = 0xff ; break ;
case 1 : DispBuff = 0xff ; DispBuff = 0xff ; break ;
case 2 : DispBuff = 0xff ; DispBuff = 0xff ; break ;
}
}
LCD1602ShowString(FirstRow,2,"Set Date ") ;
LCD1602ShowString(SecondRow,3,DispBuff) ;
}
}
/*******************************************************************/
void SetAlert (uchar KeyValue, uchar *DispBuff)
{
static char s_u8AlertMinute = 0, s_u8AlertHour = 0 ;
static bit s_bSelectMinuteAndHour ;
static bit s_bSetAlertOpen ;
uchar Second , Minute , Hour;
Second = DS1302Read(0x81) ;
switch (KeyValue)
{
case 0x01 : if (!s_bSetAlertOpen) s_bSetAlertOpen = g_bSetFlag = 1 ;
else s_bSelectMinuteAndHour = ~s_bSelectMinuteAndHour ;
break ;
case 0x02 : if (s_bSetAlertOpen) {
if (!s_bSelectMinuteAndHour && ++s_u8AlertHour > 23) s_u8AlertHour = 0 ;
if ( s_bSelectMinuteAndHour && ++s_u8AlertMinute > 59) s_u8AlertMinute = 0 ;
}
break ;
case 0x03 : if (s_bSetAlertOpen) {
if (!s_bSelectMinuteAndHour && --s_u8AlertHour < 0) s_u8AlertHour = 23 ;
if ( s_bSelectMinuteAndHour && --s_u8AlertMinute < 0) s_u8AlertMinute = 59 ;
}
break ;
case 0x04 : if (s_bSetAlertOpen) {
s_bSetAlertOpen = s_bSelectMinuteAndHour = g_bSetFlag= 0 ; g_bAlertOpenAndClose = ON ;
}
else g_bPlayMusic = g_bAlertOpenAndClose = OFF ;
break ;
}
if (g_bAlertOpenAndClose == ON ) DispBuff = 'A' ;
else DispBuff = ' ' ;
DispBuff= ' ' ;
DispBuff = ' ' ;
DispBuff = ' ' ;
DispBuff = ' ' ;
DispBuff = s_u8AlertMinute % 10 + '0' ;
DispBuff = s_u8AlertMinute / 10 + '0' ;
DispBuff = ':' ;
DispBuff = s_u8AlertHour % 10 + '0' ;
DispBuff = s_u8AlertHour / 10 + '0' ;
DispBuff = ' ' ;
DispBuff = ' ' ;
if (Second%2&&s_bSetAlertOpen) {
if (s_bSelectMinuteAndHour) DispBuff = DispBuff = '*' ;
else DispBuff = DispBuff = '*' ;
}
LCD1602ShowString(FirstRow,2,"Current Alert") ;
LCD1602ShowString (SecondRow,3,DispBuff);
if ( g_bAlertOpenAndClose ) {
Hour = DS1302Read(0x85) ;
Hour = (Hour >> 4) * 10 + Hour % 16;
if (s_u8AlertHour == Hour )
{
Minute = DS1302Read(0x83) ;
Minute = (Minute >> 4) * 10 + Minute % 16 ;
if (s_u8AlertMinute == Minute ) g_bPlayMusic = ON ;
}
}
}
/*******************************************************************/
uchar s_u8DisplayAndControlState = 0x10 ;
void DisplayAndControl (void)
{
uchar KeyValue = 0x00 ;
uchar DispBuff ={0} ;
static uints_u16TimeCount0;
if ( g_bSystemTime40Ms1 )
{
g_bSystemTime40Ms1 = 0 ;
GetKey(&KeyValue) ;
if ( !g_bSetFlag ) s_u16TimeCount0++ ;
switch (s_u16TimeCount0)
{
case 300 : s_u8DisplayAndControlState = 0x20 ; break ;
case 400 : s_u8DisplayAndControlState = 0x10 ; break ;
case 700 : s_u8DisplayAndControlState = 0x30 ; break ;
case 800 : s_u8DisplayAndControlState = 0x10 ; s_u16TimeCount0 = 0 ; break ;
default : break ;
}
}
switch ( s_u8DisplayAndControlState )
{
case0x10 : DisplayAndSetTime(KeyValue,DispBuff);break ;
case0x20 : DisplayAndSetDate(KeyValue,DispBuff);break ;
case0x30 : SetAlert(KeyValue,DispBuff) ; break ;
}
}
/*******************************************************************/
void main (void)
{
Timer0_Init() ;
Timer1_Init() ;
P1 = 0x0f ;
Buzzer = 0 ;
LCD1602_Init();
g_bPlayMusic = OFF ;
while(1) {
DisplayAndControl();
PlayMusic();
}
}
楼主 为什么有
if( SkyCity_ThemeSongTable == Zero )
if ( SkyCity_ThemeSongTable == End ) ?
SkyCity_ThemeSongTable不是固定值吗,这里面是怎么播放音乐的? zjsxwc 发表于 2013-3-20 19:59 static/image/common/back.gif
楼主 为什么有
if( SkyCity_ThemeSongTable == Zero )
if ( SkyCity_ThemeSongTable == End ) ?
那个发贴程序有问题,该成插入代码就无问题了。
页:
[1]