个人觉得本题主要考的是定时器,本题如果直接用数码管延时扫描的话会很棘手,之前数码管显示函数我一般都是先位选后段选接着在后面延时个1毫秒,现在这题目用这种方式写好像不太行,正因为不行,我卡在这地方太久了,如果大哥大姐能用这种方法做的话希望你们能教一下我,谢谢!
好了,下面是我刚编完的程序,步数挺多的。。。:
main.c
#include "STC15F2K60S2.h"
#include "iic.h"
#define uchar unsigned char
#define uint unsigned int
uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};//数码管段
uchar code mode1_2[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//模式1.2灯数组
uchar code mode3_4[]={0x7e,0xbd,0xdb,0xe7}; //模式3.4灯数组
uchar yi,er,san,si,wu,liu,qi,ba;//数码管的8个位
uchar jiange=4; //运行间隔.用于显示在数码管上.或赋值给jiange1~jiange4;
uchar modeset=1;//设置运行间隔时的模式
uchar jiange1,jiange2,jiange3,jiange4;
uchar level; //亮度等级
uchar light; //=PCF8591的3通道
uchar mode=1;//流水灯工作模式
uchar reserve;//保护现场
uchar S6count=0;//0为关数码管状态,1为数码管显示且闪模式位,2为数码管显示且闪运行间隔;
bit S7=0; //S7按键按下为1表示流水灯启动工作
bit bling=0; //用于数码管0.8秒闪烁
bit AD_flag=1; //AD采集
bit PWM; //用于亮度
bit flag=0; //读EEPROM的条件之一
void delayms(uint ms);//1毫秒延时子程序
void keyscan(void);//独立按键扫描
void allinit(void);//关闭继电器蜂鸣器数码管LED灯
void Timer1Init(void);
void Timer0Init(void);
void S6DATAPRO();//S6按键下的一些数据处理
void main(void)
{
// Write_EEPROM(0x01,4);delayms(10);
// Write_EEPROM(0x02,4);delayms(10);
// Write_EEPROM(0x03,4);delayms(10);
// Write_EEPROM(0x04,4);delayms(10);
jiangge1=Read_EEPROM(0x01);delayms(10);
jiangge2=Read_EEPROM(0x02);delayms(10);
jiangge3=Read_EEPROM(0x03);delayms(10);
jiangge4=Read_EEPROM(0x04);delayms(10);
jiangge=jiangge1;
allinit();
Timer1Init();
Timer0Init();
EA=1;ET0=1;ET1=1;
while(1)
{
keyscan();
S6DATAPRO();
}
}
void delayms(uint ms)
{
uint i,j;
for(i=ms;i>0;i--)
for(j=845;j>0;j--);
}
void keyscan(void)
{
if(P30==0)
{
//delayms(5);
if(P30==0)
{
if(S7==0){S7=1;TR0 =1;}
else S7=0;
}
while(!P30);
}
else if(P31==0)
{
delayms(5);
if(P31==0)
{
S6count++;
flag=1;
}
while(!P31);
}
else if(P32==0)
{
//delayms(5);
if(P32==0)
{
flag=1; //加按键
if(S6count==1)
{
modeset++;
if(modeset==5)modeset=1;
}
else if(S6count==2)
{
jiangge++;
if(jiangge==13)jiangge=12;
}
}
while(!P32);
}
else if(P33==0)
{
//delayms(5);
flag=1;
if(P33==0 && S6count!=0)//减按键
{
if(S6count==1)
{
modeset--;
if(modeset==0)modeset=4;
}
else if(S6count==2)
{
jiangge--;
if(jiangge==3)jiangge=4;
}
}
while(P33==0 && S6count!=0);
if(P33==0 && S6count==0)//显示亮度等级按键
{
yi=er=san=si=wu=liu=11;qi=10;ba=level;
}
}
}
void allinit(void)
{
P2=0xA0;P0=0x00;//关闭凤鸣器继电器
P2=0x80;P0=0xFF;//关闭led灯
P2=0xC0;P0=0xFF;//选择所有数码管
P2=0xFF;P0=0xFF;//关闭所有数码管
}
void S6DATAPRO()
{
if(S6count==0 && P33==1)
{
yi=11;er=11;san=11;si=11;wu=11;liu=11;qi=11;ba=11;
}
else if(bling==1 && S6count==1)
{
yi=10;er=11;san=10;si=11;wu=jiangge/10;liu=jiangge%10;qi=0;ba=0;
}
else if(bling==1 && S6count==2)
{
yi=10;er=modeset;san=10;si=11;wu=11;liu=11;qi=11;ba=11;
}
else if(bling==0 && S6count!=0)
{
yi=10;er=modeset;san=10;si=11;wu=jiangge/10;liu=jiangge%10;qi=0;ba=0;
}
}
void Timer0Init(void) //100微秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xAE; //设置定时初值
TH0 = 0xFB; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 0; //定时器0开始计时
}
void Timer1Init(void) //2毫秒@11.0592MHz
{
AUXR |= 0x40; //定时器时钟1T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x9A; //设置定时初值
TH1 = 0xA9; //设置定时初值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
}
void TIM0_isr() interrupt 1
{
static uchar PWMcount=0;
static uint numcount=0;
static uchar number=0;
PWMcount++;numcount++;
reserve=P0;P0=0xff;
if(PWMcount==80)
{
PWMcount=0;
PWM=1;
}
if(level==1 && PWMcount==20)PWM=0;
else if(level==2 && PWMcount==40)PWM=0;
else if(level==3 && PWMcount==60)PWM=0;
else if(level==4) PWM=1;
if(mode==1 && numcount==jiangge1*1000)
{
numcount=0;
if(S7==1)number++;
if(number==8)
{
number=7;mode=2;
}
}
else if(mode==2 && numcount==jiangge2*1000)
{
numcount=0;
if(S7==1)number--;
if(number==255)
{
number=0;mode=3;
}
}
else if(mode==3 && numcount==jiangge3*1000)
{
numcount=0;
if(S7==1)number++;
if(number==4)
{
number=3;mode=4;
}
}
else if(mode==4 && numcount==jiangge4*1000)
{
numcount=0;
if(S7==1)number--;
if(number==255)
{
number=0;mode=1;
}
}
if(PWM==1)
{
switch(mode)
{
case 1: P2=0x80;P0=mode1_2[number];break;
case 2: P2=0x80;P0=mode1_2[number];break;
case 3: P2=0x80;P0=mode3_4[number];break;
case 4: P2=0x80;P0=mode3_4[number];break;
}
}
else if(PWM==0)
{
P2=0x80;P0=0xff;
}
P2=0xff;P0=reserve;
}
void TIM1_isr() interrupt 3
{
static uint shan=0;
static uchar ADscan=0;
static uchar SEG=0;
shan++;ADscan++;SEG++;
if(shan==400)
{
shan=0;bling=!bling;
}
if(AD_flag==1)
{
light=PCF8591(0x03);
if(light<25)level=1;
else if(light<50)level=2;
else if(light<75)level=3;
else if(light<100)level=4;
}
if(S6count==1&& flag==1)
{
switch(modeset)
{
case 1: jiangge=Read_EEPROM(0x01);flag=0;break;
case 2: jiangge=Read_EEPROM(0x02);flag=0;break;
case 3: jiangge=Read_EEPROM(0x03);flag=0;break;
case 4: jiangge=Read_EEPROM(0x04);flag=0;break;
}
}
if(S6count==3)
{
switch(modeset)
{
case 1: jiangge1=jiangge;Write_EEPROM(0x01,jiangge);break;
case 2: jiangge2=jiangge;Write_EEPROM(0x02,jiangge);break;
case 3: jiangge3=jiangge;Write_EEPROM(0x03,jiangge);break;
case 4: jiangge4=jiangge;Write_EEPROM(0x04,jiangge);break;
}
S6count=0;
}
if(1==SEG) { P2=0xC0;P0=0x01;P2=0xFF;P0=0xff;P0=tab[yi]; }
else if(SEG==2){ P2=0xC0;P0=0x02;P2=0xFF;P0=0xff;P0=tab[er]; }
else if(SEG==3){ P2=0xC0;P0=0x04;P2=0xFF;P0=0xff;P0=tab[san];}
else if(SEG==4){ P2=0xC0;P0=0x08;P2=0xFF;P0=0xff;P0=tab[si]; }
else if(SEG==5){ P2=0xC0;P0=0x10;P2=0xFF;P0=0xff;P0=tab[wu]; }
else if(SEG==6){ P2=0xC0;P0=0x20;P2=0xFF;P0=0xff;P0=tab[liu];}
else if(SEG==7){ P2=0xC0;P0=0x40;P2=0xFF;P0=0xff;P0=tab[qi]; }
else if(SEG==8){ P2=0xC0;P0=0x80;P2=0xFF;P0=0xff;P0=tab[ba]; }
else if(SEG==9){ P2=0xC0;P0=0x80;P2=0xFF;P0=0xff;P0=tab[11]; }
if(SEG==9)SEG=0;
}
IIC.c
#include "STC15F2K60S2.h"
#include "iic.h"
#include "intrins.h"
#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
//总线引脚定义
sbit SDA = P2^1; /* 数据线 */
sbit SCL = P2^0; /* 时钟线 */
//总线启动条件
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
somenop;
SDA = 0;
somenop;
SCL = 0;
}
//总线停止条件
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
somenop;
SDA = 1;
}
//等待应答
bit IIC_WaitAck(void)
{
SDA = 1;
somenop;
SCL = 1;
somenop;
if(SDA)
{
SCL = 0;
IIC_Stop();
return 0;
}
else
{
SCL = 0;
return 1;
}
}
//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0;i<8;i++)
{
if(byt&0x80)
{
SDA = 1;
}
else
{
SDA = 0;
}
somenop;
SCL = 1;
byt <<= 1;
somenop;
SCL = 0;
}
}
//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++)
{
SCL = 1;
somenop;
da <<= 1;
if(SDA)
da |= 0x01;
SCL = 0;
somenop;
}
return da;
}
void Write_EEPROM(unsigned char add,unsigned char dat)
{
IIC_Start();
IIC_SendByte(0xA0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
unsigned char Read_EEPROM(unsigned char add)
{
unsigned char temp;
IIC_Start();
IIC_SendByte(0xA0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0xA1);
IIC_WaitAck();
temp=IIC_RecByte();
IIC_Stop();
return temp;
}
unsigned char PCF8591(unsigned char add)
{
unsigned char temp;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
temp=IIC_RecByte();
IIC_Stop();
return temp*0.39;
}
IIC.h
#ifndef _IIC_H
#define _IIC_H
//函数声明
void IIC_Start(void);
void IIC_Stop(void);
void IIC_SendByte(unsigned char byt);
bit IIC_WaitAck(void);
unsigned char IIC_RecByte(void);
void Write_EEPROM(unsigned char add,unsigned char dat);
unsigned char Read_EEPROM(unsigned char add);
unsigned char PCF8591(unsigned char add);
#endif