刚刚接触NEC不久,希望和大家共同学习,共同提高,我的QQ:386132185,希望能和更多的网友认识,加我的朋友请标明是学习单片机的。谢谢
#include<io78f9234.h>
#include<intrinsics.h>
//#include<migration.h>
#pragma location = 0X0080
__root const unsigned char XUAN=0X98;//选项字节,设置实用外部高速时钟电路
#define _NOP __no_operation()
#define uchar unsigned char
#define uint unsigned int
#define clrwdt() WDTM=0x77//屏蔽看门狗
#define BIAS 0X52//LCD1/2偏压,4个COM端_在改程序中命令标志为3为:100,命令代码末尾任意
#define SYSDIS 0X00//关闭系统振荡器和LCD偏压发生器
#define SYSEN 0X02//打开系统振荡器
#define LCDOFF 0X04//关闭LCD偏压发生器
#define LCDON 0X06//开启LCD偏压发生器
#define XTAL 0X28//外部时钟源
#define RC256 0X30//片内RC振荡器0
#define TONEON 0X12//打开声音输出
#define TONEOFF 0X10//关闭声音输出
#define WDTDIS 0X0a//看门狗溢出标志输出失效
#define WDTEN 0X0c//看门狗溢出标志有效
#define NORMAL 0Xc6//普通模式
#define dat P12_bit.no0//数据引脚
#define cs P13_bit.no0//片选引脚
#define wr P4_bit.no5//写信号引脚
#define rd P4_bit.no2//读信号引脚
__saddr char cont,cnt11,cnt12,cnt3=1,cnt13,cnt4,cnt14;
__saddr uchar readdata=0x00,rdata;//用于读数据用
__saddr uchar disbuff1[10]={0xFA,0x60,0xD6,0xF4,0x6C,0xBC,0xBE,0xE0,0xFE,0xFC};//显示缓存,数据,每个地址发两次,从高到低,每次发送4位,用于显示个位数字
__saddr uchar disbuff2[7]={0xFA,0x60,0xD6,0xF4,0x6C,0xBC,0xfa};//显示缓存,数据,每个地址发两次,从高到低,每次发送4位,用于显示分钟十位
__saddr uchar disbuff3[3]={0xFA,0x60,0xD6};//显示缓存,数据,每个地址发两次,从高到低,每次发送4位,用于显示小时十位
__saddr uchar col1[7]={0xab,0x01,0x67,0x45,0xcd,0xcd,0xab};
__saddr uchar cont1;
__saddr uchar pan=1;
__saddr uint cnt1,cnt2;
__saddr uint fen,shi,yanshi1=500,yanshi2=500;
//延时,毫秒级
void delayms(uint ms)//准确延时1ms,当ms=1时
{
uint i,j;
for(i=0;i<ms;i++)
for(j=0;j<460;j++);
}
//延时,毫秒级
void delaytms(uint ms)//准确延时1ms,当ms=1时
{
TMIF000=1;
uint i,j;
for(i=0;i<ms;i++)
for(j=0;j<460;j++);
TMIF000=0;
}
//发送数据函数,高位在前发送,用于传送格式代码和地址
void wrhdata(uchar data,uchar cnt)
{
cs=0;
uchar i;
for(i=0;i<cnt;i++)
{
if((data&0x80)==0)
dat=0;
else dat=1;
__no_operation();
wr=0;
__no_operation();
__no_operation();
wr=1;
data<<=1;
}
//cs=1;
}
//发送数据函数,低位在前发送,用于发送数据
void wrldata(uchar data,uchar cnt)
{
cs=0;
uchar i;
for(i=0;i<cnt;i++)
{
if((data&0x01)==0)
dat=0;
else dat=1;
wr=0;
__no_operation();
wr=1;
data>>=1;
}
//cs=1;
}
//发送命令代码函数
void sendcmd(uchar cmd)
{
cs=0;
__no_operation();
wrhdata(0x80,4);
wrhdata(cmd,8);
__no_operation();
cs=1;
}
//发送普通命令代码函数
void sendcmdNORMAL(uchar cmd)
{
cs=0;
__no_operation();
wrhdata(0x90,4);
wrhdata(cmd,8);
__no_operation();
cs=1;
}
//写入数据函数
void senddata(uchar addr,uchar data)
{
cs=0;
__no_operation();
wrhdata(0xa0,3);
wrhdata(addr<<2,6);
wrldata(data,4);
cs=1;
__no_operation();
}
//16位定时器TM000初始化函数
void init_TM000(void)
{
TMC00=0x00;//禁止定时器
CRC00=0X00;//设定CR000作为比较寄存器使用
CR000=0x007d;//设置计时次数,计时为0.5S/25
PRM00=0XA2;//设定预分频为31.25KHz
TMC00=0X0C;//设定定时器计时完成后自动清零
TMMK000=0;//允许定时器中断
}
//定时器TM000中断服务函数
#pragma vector=INTTM000_vect
__interrupt void INTTM000_Server(void)
{
TMIF000=0;
TMMK80=0;
pan++;
cont++;
cnt1++;
if(cont>125)
{
cont=0;
col1[cnt12]= (col1[cnt12]>>4)|(col1[cnt12]<<4);
senddata(0x04,col1[cnt12]);
}
/*时钟显示程序*/
if(cnt1>15000)//分钟的个位十位显示
{
cnt1=0;
cnt2++;
cnt4++;
cnt11=cnt4%10,//计算分钟个位
cnt12=cnt4/10;//计算分钟十位
senddata(0x07,disbuff1[cnt11]>>4);
senddata(0x06,disbuff1[cnt11]);
senddata(0x05,disbuff2[cnt12]>>4);
senddata(0x04,disbuff2[cnt12]);
if(cnt2>59)//小时的个位十位显示
{
cnt4=0;
cnt2=0;
cnt3++;
if(cnt3>23) cnt3=0;
cnt13=cnt3%10;//计算小时个位
cnt14=cnt3/10;//计算小时十位
senddata(0x03,disbuff1[cnt13]>>4);
senddata(0x02,disbuff1[cnt13]>>0);
senddata(0x01,disbuff3[cnt14]>>4);
senddata(0x00,disbuff3[cnt14]>>0);
/*if(cnt3>23)
{
cnt3=0;
}
else __no_operation();*/
}
else __no_operation();
}
else __no_operation();
}
//定时器TM80初始化函数
void init_TM80(void)
{
TMC80=0x00;//禁止定时器
CR80=50;//设置计时次数
TMC80=0x82;//允许定时器,设置计时频率为31.25KHZ
TMMK80=0;//允许定时器中断
}
//定时器TM80中断服务函数
#pragma vector=INTTM80_vect
__interrupt void INTTM80_Server(void)
{
TMIF80=0;
//TMMK000=0;
}
void main()
{
cs=1;
PCC=0X00;//以下两行为设置cpu时钟为8M
PPCC=0X00;//
WDTM=0X77;//屏蔽看门狗
PM4=0X02;//设置P4口位输入、输出状态
//P4=0x00;//设置P4口初值
MK1=0X85;//屏蔽外部中断3
INTM1=0X01;//设定外部中断3上升沿有效
PMK3=0; //允许外部中断3
PM12_bit.no0=0;//设定数据位输出口状态
P4_bit.no0=1;//点亮背光板
P0=0X07;//设定p0口状态
PM0=0X07;//设定p00,p01,p02为输入端口
PU0=0X07;//p00,p01,p02使用内部上拉电阻
//P0_bit.no3=0;
sendcmd(RC256);
sendcmd(BIAS);
sendcmd(SYSEN);
sendcmd(LCDON);
sendcmdNORMAL(NORMAL);
senddata(0x00,0xfa);
senddata(0x01,0xfa>>4);
senddata(0x02,0xfa);
senddata(0x03,0xfa>>4);
senddata(0x04,0xfb);
senddata(0x05,0xfa>>4);
senddata(0x06,0xfa);
senddata(0x07,0xfa>>4);
init_TM80();
init_TM000();
__enable_interrupt();//开中断
while(pan)
{
//yanshi1=500;
//yanshi2=500;
/*按键程序*/
if(P0<7)//判断设置键是否按下
{
yanshi1=0;
yanshi2=10;
delayms(10);//消除抖动
if(P0<7)//判断设置键是否按下
{
TMMK000=1;
switch (P0)
{
case 0x00:__no_operation();break;//三键同时按下
case 0x01:__no_operation();break;//P01\P02同时按下
case 0x02:__no_operation();break;//P00、P02同时按下
case 0x03://P02键按下,确定设定的状态,退出设置模式
{
pan=0;
cont1=0;
TMMK000=0;
}
break;
case 0x04:__no_operation();break;//P01\P00同时按下
case 0x05://P01键按下,对应按键次数设定数字时钟相应的位,每按键一下,对应的位数字自加1
{
__no_operation();
switch(cont1)
{
case 0:__no_operation();break;//确定当前值,退出设定模式,所有数据正常显示
case 1://修改小时数据,小时数据闪烁
{
yanshi1=0;
yanshi2=150;
if(cnt3>23) cnt3=0;
cnt13=cnt3%10;//计算小时个位
cnt14=cnt3/10;//计算小时十位
cnt3++;
}
break;
case 2://修改分钟数据,分钟数据闪烁
{
yanshi1=0;
yanshi2=150;
if(cnt4>59) cnt4=0,cnt2=0;
else cnt2++,cnt4++;
cnt11=cnt4%10,//计算分钟个位
cnt12=cnt4/10;//计算分钟十位
}
break;
case 3:__no_operation();break;
}
}
break;
case 0x06://P00键按下,进入设置时间状态,对应按键的次数,依次设定不同的位
{
cont1++;
if(cont1>3) cont1=0;
else __no_operation();//yanshi1=500,yanshi2=500;
}
break;
}
}
else __no_operation();
}
else
{
yanshi1=500;
yanshi2=500;
}
// 相应的修改位闪烁
if(cont1>0)
{
switch(cont1)
{
case 0:__no_operation();break;
case 1:
{
senddata(0x03,0);
senddata(0x02,0);
senddata(0x01,0);
senddata(0x00,0);
delayms(yanshi1);
senddata(0x03,disbuff1[cnt13]>>4);
senddata(0x02,disbuff1[cnt13]);
senddata(0x01,disbuff3[cnt14]>>4);
senddata(0x00,disbuff3[cnt14]);
delayms(yanshi2);
}
break;
case 2:
{
senddata(0x07,0);
senddata(0x06,0);
senddata(0x05,0);
senddata(0x04,0);
delayms(yanshi1);
senddata(0x07,disbuff1[cnt11]>>4);
senddata(0x06,disbuff1[cnt11]);
senddata(0x05,disbuff2[cnt12]>>4);
senddata(0x04,disbuff2[cnt12]);
delayms(yanshi2);
}
break;
case 3:__no_operation();break;
}
}
else __no_operation();
}
}
|