******完整代码****
#include <STC15F2K60S2.H>
#include <stdio.H>
#include <IIC.H>
#define u8 unsigned char
#define u16 unsigned int
u8 Nodat[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
u8 Isdat[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
u8 smg_i,tab[8];
u16 smg_db,parm=65;
u16 cont2;
u8 R_I;
u8 keyval;
u8 stbuf[6];
u8 L1=0;L2=0;L8=0;
bit smg_mode;
bit flag10ms,flag100ms,flag200ms;
//======== ==================初始化函数=========================
void initsystem()
{
P0=0; P2=0xa0; P2=0;
P0=0xff; P2=0x80; P2=0;
}
//======== T0定时(串口接收字符串)
void Timer0Init(void) //10毫秒@12.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0xE0; //设置定时初始值
TH0 = 0xB1; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
//======== T1串口
void UartInit(void) //[email protected]
{
SCON = 0x50; //8位数据,可变波特率
AUXR &= 0xBF; //定时器1时钟为Fosc/12,即12T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设定定时器1为16位自动重装方式
TL1 = 0xE6; //设定定时初值
TH1 = 0xFF; //设定定时初值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
EA=1; ES=1;
}
//======== T2定时
void Timer2Init(void) //1毫秒@12.000MHz
{
AUXR &= 0xFB; //定时器时钟12T模式
T2L = 0x18; //设置定时初值
T2H = 0xFC; //设置定时初值
AUXR |= 0x10; //定时器2开始计时
IE2 |= 0x04;
EA=1;
}
//======== =================数据读取函数=========================
//======== AD数据读取
float read_ADC()
{
float val;
EA=0;
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x03);
I2CWaitAck();
I2CStop();
I2CStart();
I2CSendByte(0x91);
I2CWaitAck();
val=(5.00/255)*I2CReceiveByte();
I2CSendAck(1);
I2CStop();
EA=1;
return val;
}
//======== 串口打印T1
void Uart_Ist() interrupt 4
{
if(RI)
{ RI=0;
stbuf[R_I++]=SBUF;
}
}
void sendbyte(u8 udat)
{
SBUF=udat;
while(TI==0);
TI=0;
}
char putchar(char c)
{
sendbyte(c);
return c;
}
void uart_mange()
{
u8 i;
if(TF0)
{
TF0=0;
if(R_I!=6)
{ for(i=0;i<7;i++)
{ stbuf[i++]=0; }
}
else
{ stbuf[R_I]='\0';
if((stbuf[0]=='R')&&(stbuf[1]=='e')&&(stbuf[2]=='t')&&(stbuf[3]=='u')&&(stbuf[4]=='r')&&(stbuf[5]=='n'))
printf("Noises:%.1fdB",(float)smg_db/10);
}
R_I=0;
}
}
//======== =================数码管显示=========================
void setsmg()
{
if(smg_mode==0)
{
tab[0]=0xc1;
tab[1]=Nodat[1];
tab[2]=0xff;
tab[3]=0xff;
tab[4]=0xff;
if(smg_db>99)
tab[5]=Nodat[smg_db/100];
else tab[5]=0xff;
tab[6]=Isdat[smg_db/10%10];
tab[7]=Nodat[smg_db%10];
L1=1; L2=0;
}
if(smg_mode==1)
{
tab[0]=0xc1;
tab[1]=Nodat[2];
tab[2]=0xff;
tab[3]=0xff;
tab[4]=0xff;
tab[5]=0xff;
if(parm>9)
tab[6]=Nodat[parm/10];
else tab[6]=0xff;
tab[7]=Nodat[parm%10];
L2=1; L1=0;
}
}
//======== =================按键扫描========================
u8 read_key()
{
u8 val=0,x=0,y=0;
TR1=0;
P3=0x0f; P42=0; P44=0;
if(!P30) x=3;
else if(!P31) x=2;
else if(!P32) x=1;
else if(!P33) x=0;
P3=0xf0; P42=1; P44=1;
if(!P34) y=4;
else if(!P35) y=3;
else if(!P42) y=2;
else if(!P44) y=1;
val=x+4*y;
TR1=1; P3=0xff;
return val;
}
void scankey()
{
u8 up,down,temp;
static u8 old=0;
temp=read_key();
down=temp&(temp^old);
up=~temp&(temp^old);
old=temp;
if(up) keyval=up;
}
//======== =================定时轮询========================
void t2int() interrupt 12 //中断入口
{
cont2++;
if(cont2==1000)
cont2=0;
if(cont2%2==0)
{ P0=~(L1+2*L2+128*L8); P2=0x80; P2=0;
P0=0; P2=0xc0; P2=0;
P0=tab[smg_i]; P2=0xe0; P2=0;
P0=(1<<smg_i); P2=0xc0; P2=0;
smg_i++; smg_i&=0x07;
if(cont2%10==0)
{ flag10ms=1;
if(cont2%100==0)
{ flag100ms=1;
if(cont2%200==0)
{
flag200ms=1;
}}}
}
}
//======== =================主函数========================
void main()
{
initsystem();
Timer0Init();
UartInit();
Timer2Init();
while(1)
{
switch(keyval)
{
case 12 : smg_mode=!smg_mode; break;
case 16 : if(smg_mode) if(parm>=90) parm=90; else parm+=5; break;
case 17 : if(smg_mode) if(parm<=0) parm=0; else parm-=5; break;
}
keyval=0;
if(flag10ms)
{ flag10ms=0;
scankey();
if(flag100ms)
{ flag100ms=0;
uart_mange();
if(smg_db>parm*10)
L8=!L8;
else L8=0;
if(flag200ms)
{ flag200ms=0;
smg_db=read_ADC()*18*10;;
if(smg_db>=900)
smg_db=900;
}
}
}
setsmg();
}
}
驱动程序
#ifndef __IIC_H_
#define __IIC_H_
void I2CStart(void);
void I2CStop(void);
void I2CSendByte(unsigned char byt);
unsigned char I2CReceiveByte(void);
unsigned char I2CWaitAck(void);
void I2CSendAck(unsigned char ackbit);
#endif
/* # I2C代码片段说明
1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include <reg52.H>
#include <intrins.H>
sbit scl=P2^0;
sbit sda=P2^1;
#define DELAY_TIME 5
//
static void I2C_Delay(unsigned char n)
{
do
{
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
}
while(n--);
}
//
void I2CStart(void)
{
sda = 1;
scl = 1;
I2C_Delay(DELAY_TIME);
sda = 0;
I2C_Delay(DELAY_TIME);
scl = 0;
}
//
void I2CStop(void)
{
sda = 0;
scl = 1;
I2C_Delay(DELAY_TIME);
sda = 1;
I2C_Delay(DELAY_TIME);
}
//
void I2CSendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++){
scl = 0;
I2C_Delay(DELAY_TIME);
if(byt & 0x80){
sda = 1;
}
else{
sda = 0;
}
I2C_Delay(DELAY_TIME);
scl = 1;
byt <<= 1;
I2C_Delay(DELAY_TIME);
}
scl = 0;
}
//
unsigned char I2CReceiveByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++){
scl = 1;
I2C_Delay(DELAY_TIME);
da <<= 1;
if(sda)
da |= 0x01;
scl = 0;
I2C_Delay(DELAY_TIME);
}
return da;
}
//
unsigned char I2CWaitAck(void)
{
unsigned char ackbit;
scl = 1;
I2C_Delay(DELAY_TIME);
ackbit = sda;
scl = 0;
I2C_Delay(DELAY_TIME);
return ackbit;
}
//
void I2CSendAck(unsigned char ackbit)
{
scl = 0;
sda = ackbit;
I2C_Delay(DELAY_TIME);
scl = 1;
I2C_Delay(DELAY_TIME);
scl = 0;
sda = 1;
I2C_Delay(DELAY_TIME);
}