1.system.h
#ifndef __SYSTEM_H_
#define __SYSTEM_H_
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
#include <STC15F2K60S2.H>
#include <intrins.h>
#include <iic.h>
#endif
2.iic.h(iic总线比赛提供底层驱动)
#ifndef _IIC_H
#define _IIC_H
#include <system.h>
u8 ADC_read(u8 add);
void DAC_write(u8 dat);
#endif
3.iic.c(根据比赛提供的底层驱动,组装相关通信的函数,编写ADC,DAC函数)
#include "iic.h"
#define DELAY_TIME 5
sbit SDA = P2^1;
sbit SCL = P2^0;
//I2C总线内部延时函数
void IIC_Delay(unsigned char i)
{
do{_nop_();}
while(i--);
}
//I2C总线启动信号
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 0;
}
//I2C总线停止信号
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//发送应答或非应答信号
void IIC_SendAck(bit ackbit)
{
SCL = 0;
SDA = ackbit;
IIC_Delay(DELAY_TIME);
SCL = 1;
IIC_Delay(DELAY_TIME);
SCL = 0;
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//等待应答
bit IIC_WaitAck(void)
{
bit ackbit;
SCL = 1;
IIC_Delay(DELAY_TIME);
ackbit = SDA;
SCL = 0;
IIC_Delay(DELAY_TIME);
return ackbit;
}
//I2C总线发送一个字节数据
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++)
{
SCL = 0;
IIC_Delay(DELAY_TIME);
if(byt & 0x80) SDA = 1;
else SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 1;
byt <<= 1;
IIC_Delay(DELAY_TIME);
}
SCL = 0;
}
//I2C总线接收一个字节数据
unsigned char IIC_RecByte(void)
{
unsigned char i, da;
for(i=0; i<8; i++)
{
SCL = 1;
IIC_Delay(DELAY_TIME);
da <<= 1;
if(SDA) da |= 1;
SCL = 0;
IIC_Delay(DELAY_TIME);
}
return da;
}
//ADC
u8 ADC_read(u8 add)
{
u8 dat;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
dat=IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
return dat;
}
//DAC
void DAC_write(u8 dat)
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x40);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
4.main.c(主函数以及一些外设,系统,操作函数的编写,包括定时器2中断定时,计数器0对于NE555的频率计数等,详见注释)
#include <system.h>
u8 mode=1; //1.u 2.f
u8 dac_mode=1;
u8 led_mode=1;
u8 smg_mode=1;
//----库函数----//
//1.device
void device(u8 p2,u8 p0)
{
P2=p2;
P0=p0;
P2=0;
}
//2.独立按键
u8 trg,cont;
void btn_read()
{
u8 readdata=P3^0xff;
trg=readdata&(readdata^cont);
cont=readdata;
}
//3.数码管
u8 smg_code[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00};
u8 smg_buf[8];
void smg_show()
{
static u8 i;
device(0xc0,0);
device(0xe0,~smg_buf[i]);
device(0xc0,0x01<<i);
i=(i+1)%8;
}
//4.定时器
void timer2_init()
{
AUXR &= 0xFB; //定时器时钟12T模式
T2L = 0x18; //设置定时初始值
T2H = 0xFC; //设置定时初始值
AUXR |= 0x10; //定时器2开始计时
IE2|=0x04;
EA=1;
}
//5.NE555
void counter0_init()
{
TMOD|=0X05;
TL0=0;
TH0=0;
TR0=1;
}
//----操作函数----//
//1.ADC
u8 adc_cnt;
u16 adc;
void adc_pro()
{
if(adc_cnt>=100)
{
adc_cnt=0;
adc=ADC_read(0x43)*100/51;
}
}
//2.按键操作
u8 btn_cnt;
void btn_pro()
{
if(btn_cnt>=10)
{
btn_cnt=0;
btn_read();
if(trg==0x08) //s4
{
mode=mode%2+1;
}
if(trg==0x04) //s5
{
dac_mode=dac_mode%2+1;
}
if(trg==0x02) //s6
{
led_mode=led_mode%2+1;
}
if(trg==0x01) //s7
{
smg_mode=smg_mode%2+1;
}
}
}
//3.NE555操作
u16 ne555_cnt;
u16 f;
void ne555_pro()
{
if(ne555_cnt>=1000)
{
ne555_cnt=0;
f=(TH0<<8)|TL0;
TH0=0;
TL0=0;
}
}
//4.dac操作
u8 dac_cnt;
void dac_pro()
{
if(dac_cnt>=100)
{
dac_cnt=0;
if(dac_mode==1)
DAC_write(102);
if(dac_mode==2)
DAC_write(adc*51/100);
}
}
//5.数码管
void smg_pro()
{
if(smg_mode==1)
{
if(mode==1)
{
smg_buf[0]=0x3e;
smg_buf[1]=0;
smg_buf[2]=0;
smg_buf[3]=0;
smg_buf[4]=0;
smg_buf[5]=smg_code[adc/100]|0x80;
smg_buf[6]=smg_code[adc/10%10];
smg_buf[7]=smg_code[adc%10];
}
if(mode==2)
{
smg_buf[0]=0x71;
smg_buf[1]=0;
smg_buf[2]=0;
smg_buf[3]=smg_code[(f>=10000)?(f/10000):10];
smg_buf[4]=smg_code[(f>=1000)?(f/1000%10):10];
smg_buf[5]=smg_code[(f>=100)?(f/100%10):10];
smg_buf[6]=smg_code[(f>=10)?(f/10%10):10];
smg_buf[7]=smg_code[f%10];
}
}
if(smg_mode==2)
{
smg_buf[0]=0;
smg_buf[1]=0;
smg_buf[2]=0;
smg_buf[3]=0;
smg_buf[4]=0;
smg_buf[5]=0;
smg_buf[6]=0;
smg_buf[7]=0;
}
}
//6.led
u8 led=0xff;
void led_pro()
{
if(led_mode==1)
{
if(mode==1)
{
led|=0x08;
led&=~0x01;
led|=0x02;
if(adc<150||(adc>=250&&adc<350))
led|=0x04;
if((adc>=150&&adc<250)||adc>=350)
led&=~0x04;
}
if(mode==2)
{
led|=0x04;
led&=~0x02;
led|=0x01;
if((f<1000)||(f>=5000&&f<10000))
led|=0x08;
if((f>=1000&&f<5000)||f>=10000)
led&=~0x08;
}
if(dac_mode==1)
led|=0x10;
if(dac_mode==2)
led&=~0x10;
device(0x80,led);
}
else if(led_mode==2)
device(0x80,0xff);
}
void main()
{
device(0xa0,0);
timer2_init();
counter0_init();
while(1)
{
adc_pro();
dac_pro();
smg_pro();
}
}
void timer2() interrupt 12
{
btn_pro();
led_pro();
adc_cnt++;
dac_cnt++;
btn_cnt++;
ne555_cnt++;
ne555_pro();
smg_show();
}