





main.c程式
#include<stc15f2k60s2.h>
#include "iic.h"
#define uchar unsigned char //定義無符號字符型別uchar
#define uint unsigned int //定義無符號整型型別uint
uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};//數字0~9,“-”,“關”
uchar yi,er,san,si,wu,liu,qi,ba; //定義字符型變數yi,er,san,si,wu,liu,qi,ba,當作數碼管顯示控制變數
uchar mode3[]={0x7e,0xbd,0xdb,0xe7};
uchar mode4[]={0xe7,0xdb,0xbd,0x7e};
uchar AD,mode,i=0,shezhi=0,qidong=0,Dj=0,dengji,LEDtime;
uint jiange,tt=0,shezhi_tt=0,LED_TT=0;
bit s4=0;
void delayms(int ms); //延時函式
void allinit(); //初始化函式
void keyscan16(); //矩陣按鍵函式
void keyscan(); //獨立按鍵函式
void display1(uchar yi,uchar er); //第一、二段數碼管函式
void display2(uchar san,uchar si); //第三、四段數碼管函式
void display3(uchar wu,uchar liu); //第五、六段數碼管函式
void display4(uchar qi,uchar ba); //第七、八段數碼管函式
void Timer0Init(void); //1毫秒@12.000MHz
void main()
{
allinit();
Timer0Init();
yi=11;er=11;san=11;si=11;wu=11;liu=11;qi=11;ba=11;
// EEPROM_write(0x00,40);delayms(2);EEPROM_write(0x01,1);delayms(2);
jiange=EEPROM_read(0x00)*10;
mode=EEPROM_read(0x01);
while(1)
{
AD=AD_read(0x03); //呼叫IIC驅動里的AD_read函式,利用RB2模擬電壓值
if(AD<64){dengji=1;LEDtime=2;} //判斷AD的值是否小于64,即小于1.25V,亮度等級位1級,PWM占空比設定為10%左右
else if((AD>=64)&&(AD<128)){dengji=2;LEDtime=5;} //判斷AD的值是否大于等于64且小于128,即大于等于1.25V小于2.5V,亮度等級位2級,PWM占空比設定為25%左右
else if((AD>=128)&&(AD<192)){dengji=3;LEDtime=10;} //判斷AD的值是否大于等于128且小于192,即大于等于2.5V小于3.75V,亮度等級位3級,PWM占空比設定為50%左右
else if(AD>=192){dengji=4;LEDtime=19;} //判斷AD的值是否大于等與192,即大于等于3.75V,亮度等級位4級,PWM占空比設定為100%左右
if(shezhi==0)
{
yi=11;er=11;san=11;si=11;wu=11;liu=11;qi=11;ba=11;//數碼管全滅
}
else if(shezhi==1) //設定模式編號界面
{
if(jiange>=1000) //判斷流轉間隔時間是否大于1000,目的是讓流轉間隔時間不足4位的讓最高位數碼管熄滅,
{
if(shezhi_tt<=800){yi=10;er=mode;san=10;si=11;wu=jiange/1000;liu=jiange%1000/100;qi=jiange%100/10;ba=jiange%10;}
else {yi=10;er=11;san=10;si=11;wu=jiange/1000;liu=jiange%1000/100;qi=jiange%100/10;ba=jiange%10;}
}
else
{
if(shezhi_tt<=800){yi=10;er=mode;san=10;si=11;wu=11;liu=jiange/100;qi=jiange%100/10;ba=jiange%10;}
else {yi=10;er=11;san=10;si=11;wu=11;liu=jiange/100;qi=jiange%100/10;ba=jiange%10;}
}
}
else if(shezhi==2) //設定流轉間隔界面
{
if(jiange>=1000) //判斷流轉間隔時間是否大于1000,目的是讓流轉間隔時間不足4位的讓最高位數碼管熄滅,
{
if(shezhi_tt<=800){yi=10;er=mode;san=10;si=11;wu=jiange/1000;liu=jiange%1000/100;qi=jiange%100/10;ba=jiange%10;}
else {yi=10;er=mode;san=10;si=11;wu=11;liu=11;qi=11;ba=11;}
}
else
{
if(shezhi_tt<=800){yi=10;er=mode;san=10;si=11;wu=11;liu=jiange/100;qi=jiange%100/10;ba=jiange%10;}
else {yi=10;er=mode;san=10;si=11;wu=11;liu=11;qi=11;ba=11;}
}
}
if(Dj==1) //亮度等級顯示頁面
{
yi=11;er=11;san=11;si=11;wu=11;liu=11;qi=10;ba=dengji;
}
keyscan(); //獨立按鍵函式
display1(yi,er); //第一、二段數碼管函式
display2(san,si); //第三、四段數碼管函式
display3(wu,liu); //第五、六段數碼管函式
display4(qi,ba); //第七、八段數碼管函式
}
}
void keyscan()//獨立按鍵函式
{
if(P30==0) //判斷P30是否等于0
{
delayms(5); //延時5ms
if(P30==0) //再次判斷P30是否等于0
{
if(qidong==0)qidong=1; //判斷是否為未啟動狀態,是的話按鍵按下后啟動
else if(qidong==1)qidong=0;//判斷是否為啟動狀態,是的話按鍵按下后停止
}
while(!P30); //如果按鍵不松開,則一直回圈
}
else if(P31==0) //判斷P31是否等于0
{
delayms(5); //延時5ms
if(P31==0) //再次判斷P31是否等于0
{
if(shezhi==0)shezhi=1; //判斷是否在非設定頁面,是的話按鍵按下后進入到設定模式頁面
else if(shezhi==1)shezhi=2; //判斷是否在設定模式頁面,是的話按鍵按下后進入到設定流轉間隔頁面
else if(shezhi==2)
{
shezhi=0;
EEPROM_write(0x00,jiange/10);delayms(2);
EEPROM_write(0x01,mode);delayms(2);
}//判斷是否在設定流轉間隔頁面,是的話按鍵按下后進入到非設定頁面,保存模式和流轉間隔到EEPROM中
}
while(!P31); //如果按鍵不松開,則一直回圈
}
else if(P32==0) //判斷P32是否等于0
{
delayms(5); //延時5ms
if(P32==0) //再次判斷P32是否等于0
{
if(shezhi==1) //設定模式頁面下按鍵
{
if(mode==4)mode=4;//判斷模式是否等于4,是的話模式還等于4
else mode=mode+1; //不是的話模式+1
}
else if(shezhi==2) //設定流轉間隔頁面下按鍵
{
if(jiange==1200)jiange=1200;//判斷流轉間隔是否等于1200,是的話模式還等于1200
else jiange=jiange+100; //不是的話流轉間隔+100
}
}
while(!P32); //如果按鍵不松開,則一直回圈
}
else if(P33==0) //判斷P33是否等于0
{
delayms(5); //延時5ms
if(P33==0) //再次判斷P33是否等于0
{
s4=1; //s4標志位置1
if(shezhi==0)Dj=1;//非設定狀態下,按鍵按下進入到等級顯示頁面
}
}
else if((s4==1)&&(P30==1))
{
s4=0;Dj=0; //s4標志位清零,Dj標志位清零
if(shezhi==1) //設定模式頁面下按鍵
{
if(mode==1)mode=1;//判斷模式是否等于1,是的話模式還等于1
else mode=mode-1; //不是的話模式-1
}
else if(shezhi==2) //設定流轉間隔頁面下按鍵
{
if(jiange==400)jiange=400;//判斷流轉間隔是否等于400,是的話模式還等于400
else jiange=jiange-100; //不是的話流轉間隔-100
}
}
}
void Timer0Init(void) //1毫秒@12.000MHz
{
AUXR |= 0x80; //定時器時鐘1T模式
TMOD &= 0xF0; //設定定時器模式
TL0 = 0x20; //設定定時初值
TH0 = 0xD1; //設定定時初值
TF0 = 0; //清除TF0標志
TR0 = 1; //定時器0開始計時
EA=1;ET0=1;
}
void time0() interrupt 1
{
if(qidong==1) //啟動狀態下
{
if(++tt==1) //tt等于1時流水燈亮,但不開始流水
{
if(mode==1){P2=0X00;P0=0XFF;P2=0X80;P0=~(0x01<<i);P2=0X00;} //模式一
else if(mode==2){P2=0X00;P0=0XFF;P2=0X80;P0=~(0x80>>i);P2=0X00;} //模式二
else if(mode==3){P2=0X00;P0=0XFF;P2=0X80;P0=mode3[i];P2=0X00;} //模式三
else if(mode==4){P2=0X00;P0=0XFF;P2=0X80;P0=mode4[i];P2=0X00;} //模式四
}
else if(tt==LEDtime) //到達LEDtime時流水燈熄滅
{
P2=0X00;P0=0XFF;P2=0X80;P0=0XFF;P2=0X00;
}
else if(tt==20) //20ms一個周期
{
tt=0;LED_TT++; //tt清零,LED_TT++;
if(LED_TT*20>=jiange) //因為20ms一個周期,所以LED_TT要乘以20到達流轉間隔時間,LED燈開始流水
{
LED_TT=0; //LED_TT清零
if(mode==1){i++;if(i>=8)i=0;} //模式一開始流水
else if(mode==2){i++;if(i>=8)i=0;} //模式二開始流水
else if(mode==3){i++;if(i>=4)i=0;} //模式三開始流水
else if(mode==4){i++;if(i>=4)i=0;} //模式四開始流水
}
}
}
if(++shezhi_tt==1600) //定義一個以1600ms為周期的時間,為了實作設定狀態下數碼管閃爍
{
shezhi_tt=0; //shezhi_tt清零
}
}
void delayms(int ms)//延時函式
{
uint i,j;
for(i=ms;i>0;i--)
for(j=845;j>0;j--);
}
void allinit()//初始化函式
{
P2=0XA0;P0=0X00; //關閉蜂鳴器繼電器
P2=0X80;P0=0XFF; //關閉所有LED燈
P2=0XC0;P0=0XFF; //選中所有數碼管段選
P2=0XFF;P0=0XFF; //關閉所有數碼管
}
void display1(uchar yi,uchar er)//第一、二段數碼管函式
{
P2=0XC0;P0=0X01; //選中第一個數碼管位選
P2=0XFF;P0=tab[yi]; //讓第一個數碼管顯示yi指向的值
delayms(1); //延時1ms
P2=0XC0;P0=0X02; //選中第二個數碼管位選
P2=0XFF;P0=tab[er]; //讓第一個數碼管顯示er指向的值
delayms(1); //延時1ms
}
void display2(uchar san,uchar si)//第三、四段數碼管函式
{
P2=0XC0;P0=0X04; //選中第s三個數碼管位選
P2=0XFF;P0=tab[san]; //讓第一個數碼管顯示san指向的值
delayms(1); //延時1ms
P2=0XC0;P0=0X08; //選中第四個數碼管位選
P2=0XFF;P0=tab[si]; //讓第一個數碼管顯示si指向的值
delayms(1); //延時1ms
}
void display3(uchar wu,uchar liu)//第五、六段數碼管函式
{
P2=0XC0;P0=0X10; //選中第五個數碼管位選
P2=0XFF;P0=tab[wu]; //讓第一個數碼管顯示wu指向的值
delayms(1); //延時1ms
P2=0XC0;P0=0X20; //選中第六個數碼管位選
P2=0XFF;P0=tab[liu]; //讓第一個數碼管顯示liu指向的值
delayms(1); //延時1ms
}
void display4(uchar qi,uchar ba)//第七、八段數碼管函式
{
P2=0XC0;P0=0X40; //選中第七個數碼管位選
P2=0XFF;P0=tab[qi]; //讓第一個數碼管顯示qi指向的值
delayms(1); //延時1ms
P2=0XC0;P0=0X80; //選中第八個數碼管位選
P2=0XFF;P0=tab[ba]; //讓第一個數碼管顯示ba指向的值
delayms(1); //延時1ms
P2=0XC0;P0=0X80; //選中第八個數碼管位選
P2=0XFF;P0=0XFF; //讓第八個數碼管熄滅
}
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;
}
unsigned char AD_read(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;
}
unsigned char EEPROM_read(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;
}
void EEPROM_write(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();
}
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);
unsigned char AD_read(unsigned char add);
unsigned char EEPROM_read(unsigned char add);
void EEPROM_write(unsigned char add,unsigned char dat);
#endif

第九屆藍橋杯單片機作品演示
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/282734.html
標籤:其他
