本文是写第十二届的蓝桥杯省赛代码,如果是新手的话,欢迎去观看我专门为新手写的一篇。也欢迎收录该专栏。
蓝桥杯单片机STC15F2K60S2第十三届省赛代码详细讲解(附完整代码)
专栏:
接下来直接上正文。
试题
main.c
#include <STC15F2K60S2.H>
#include "display.h"
#include "ds1302.h"
#include "onewire.h"
#include "iic.h"
void Key_Board(void);
void Show_Switch(void);
void LED(void);
ds1302 Date ={55,59,23};
int Temp;
int Val;
unsigned char Switching=1;
unsigned char Tempara=25;
unsigned char ParaFlag=0;
unsigned char Mode=0;
unsigned char ValFlag=1;
void main()
{
System_Init();
while(1)
{
Temp=Read_Temp();
Key_Board();
Show_Switch();
LED();
}
}
void Key_Board(void)
{
unsigned char Key;
P44=0;P42=1;P3 |= 0x0f;
Key=P3;Key &=0x0c;
if(Key != 0x0c)
{
Delayms(5);
if(Key != 0x0c)
{
switch(Key)
{
case 0x04: Switching++; if(Switching>3)Switching=1;
break; //S4
case 0x08: Mode = !Mode;
break; //S5
}
}
}
while(Key !=0x0c)
{
Key=P3;Key &=0x0c;
Show_Switch();
}
P42=0;P44=1;P3 |= 0x0f;
Key=P3;Key &=0x0c;
if(Key != 0x0c)
{
Delayms(5);
if(Key != 0x0c)
{
if(ParaFlag==1)
{
switch(Key)
{
case 0x04: Tempara--;break; //S8
case 0x08: Tempara++;break; //S9
}
}
}
}
while(Key !=0x0c)
{
Key=P3;Key &=0x0c;
Show_Switch();
}
}
void Show_Switch(void)
{
switch(Switching)
{
case 1:
ParaFlag=0;
ShowNumber(1,12);ShowNumber(5,Temp/1000);ShowFNumber(6,Temp/100%10);
ShowNumber(7,Temp/10%10);ShowNumber(8,Temp%10);
break;
case 2:
ParaFlag=1;
ShowNumber(1,11);ShowNumber(7,Tempara/10);ShowNumber(8,Tempara%10);
break;
case 3:
ParaFlag=0;
if(!ValFlag)
{
ShowNumber(1,13);ShowFNumber(6,(unsigned char)Val/100);ShowNumber(7,(unsigned char)Val/10%10);
ShowNumber(8,(unsigned char)Val%10);
}
else
{
ShowNumber(1,13);ShowNumber(8,Val);
}
break;
}
if(Mode == 0)
{
ValFlag=1;
Show_LED(1,ON);
if(Temp/100 < Tempara)
{
Val=0;
}
else
{
Val=5;
}
Read_DAC(Val);
}
else
{
Show_LED(1,OFF);
ValFlag=0;
Val = Temp*3/20 -2;
Read_DAC((Val/100)+(((Val/10)%10)/10)+((Val%10)/10));
}
}
void LED(void)
{
if(Switching ==1) Show_LED(2,ON);
else Show_LED(2,OFF);
if(Switching ==2) Show_LED(3,ON);
else Show_LED(3,OFF);
if(Switching ==3) Show_LED(4,ON);
else Show_LED(4,OFF);
}
onewire.c
/* # 单总线代码片段说明
1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include "onewire.h"
//
void Delay_OneWire(unsigned int t)
{
unsigned char i;
while(t--){
for(i=0;i<12;i++);
}
}
//
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat&0x01;
Delay_OneWire(5);
DQ = 1;
dat >>= 1;
}
Delay_OneWire(5);
}
//
unsigned char Read_DS18B20(void)
{
unsigned char i;
unsigned char dat;
for(i=0;i<8;i++)
{
DQ = 0;
dat >>= 1;
DQ = 1;
Delay_OneWire(1);
if(DQ)
{
dat |= 0x80;
}
Delay_OneWire(5);
}
return dat;
}
//
bit init_ds18b20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(12);
DQ = 0;
Delay_OneWire(80);
DQ = 1;
Delay_OneWire(10);
initflag = DQ;
Delay_OneWire(5);
return initflag;
}
//double Read_Temp(void)
//{
// unsigned char temp;
// double Temp;
// unsigned char Th,Tl;
//
// init_ds18b20();
// Write_DS18B20(0xcc);
// Write_DS18B20(0x44);
// init_ds18b20();
// Write_DS18B20(0xcc);
// Write_DS18B20(0xbe);
//
//
// Tl=Read_DS18B20();
// Th=Read_DS18B20();
//
// temp=Th<<8;
// temp |=Tl;
// Temp = (int)(temp*0.625);
// return Temp;
//}
int Read_Temp(void)
{
unsigned char th,tl;
int temp;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
tl=Read_DS18B20();
th= Read_DS18B20();
temp = (th*256 + tl)*6.25;//0.0625
return temp;
}
onewire.h
#ifndef __ONEWIRE_H__
#define __ONEWIRE_H__
#include <STC15F2K60S2.H>
//float Read_Temp(void);
int Read_Temp(void);
#define DQ P14
#endif
iic.c
/* # I2C代码片段说明
1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include "iic.h"
#include "intrins.h"
#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);
}
void Read_DAC(double Data)
{
// double temp;
// temp = Data/100+Data/10%10/10+Data%10/10;
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x40); //通道0x40是发送AD信号
I2CWaitAck();
I2CSendByte(Data);
I2CWaitAck();
I2CStop();
}
iic.h
#ifndef __IIC_H__
#define __IIC_H__
#include <stc15.h>
#define sda P21
#define scl P20
//unsigned char Read_ADC(unsigned char channel);
void Read_DAC(double Data);
#endif
display.c
#include <STC15F2K60S2.H>
#include "display.h"
code unsigned char Show_Number[] = {
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90, //0~9
0xBF, //- 10
0x88, //A 11
0xC6, //C 12
0x8C //P 13
};
code unsigned char Show_FNumber[] ={
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10
};
void Select_HC573(unsigned char Number)
{
switch(Number)
{
case 4: P2=(P2 &0x1f)|0x80;break;
case 5: P2=(P2 &0x1f)|0xA0;break;
case 6: P2=(P2 &0x1f)|0xC0;break;
case 7: P2=(P2 &0x1f)|0xE0;break;
}
P2=(P2 &0x1f)|0x00;
}
void Delayms(int ms) //@12.000MHz
{
unsigned char data i, j;
int k;
for(k=0;k<ms;k++)
{
i = 12;
j = 169;
do
{
while (--j);
} while (--i);
}
}
void System_Init(void)
{
P0 =0x00;
Select_HC573(5);
Select_HC573(6);
P0 =0xFF;
Select_HC573(4);
}
void ShowNumber(unsigned char Pos,unsigned char Data)
{
P0 = 0x01<<Pos -1;
Select_HC573(6);
P0=Show_Number[Data];
Select_HC573(7);
Delayms(1);
P0 = 0x01<<Pos -1;
Select_HC573(6);
P0=0xff;
Select_HC573(7);
}
void ShowFNumber(unsigned char Pos,unsigned char Data)
{
P0 = 0x01<<Pos -1;
Select_HC573(6);
P0=Show_FNumber[Data];
Select_HC573(7);
Delayms(1);
P0 = 0x01<<Pos -1;
Select_HC573(6);
P0=0xff;
Select_HC573(7);
}
void Show_LED(unsigned char Number,unsigned char state)
{
static unsigned char temp=0xff;
if(state)
{
switch(Number)
{
case 1:temp &=0xfe;break;
case 2:temp &=0xfd;break;
case 3:temp &=0xfb;break;
case 4:temp &=0xf7;break;
}
}
else
{
switch(Number)
{
case 1:temp |=0x01;break;
case 2:temp |=0x02;break;
case 3:temp |=0x04;break;
case 4:temp |=0x08;break;
}
}
P0 =temp;
Select_HC573(4);
}
display.h
#ifndef __DISPLAY_H__
#define __DISPLAY_H__
#define ON 1
#define OFF 0
void System_Init(void);
void ShowNumber(unsigned char Pos,unsigned char Data);
void ShowFNumber(unsigned char Pos,unsigned char Data);
void Show_LED(unsigned char Number,unsigned char state);
void Delayms(int ms); //@12.000MHz
#endif
ds1302.c
/* # DS1302代码片段说明
1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include "ds1302.h"
#include <STC15F2K60S2.H>
sbit SCK = P1^7;
sbit SDA = P2^3;
sbit RST = P1^3;
//
void Write_Ds1302(unsigned char temp)
{
unsigned char i;
for (i=0;i<8;i++)
{
SCK = 0;
SDA = temp&0x01;
temp>>=1;
SCK=1;
}
}
//
void Write_Ds1302_Byte( unsigned char address,unsigned char dat )
{
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
Write_Ds1302(dat);
RST=0;
}
//
unsigned char Read_Ds1302_Byte ( unsigned char address )
{
unsigned char i,temp=0x00;
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
for (i=0;i<8;i++)
{
SCK=0;
temp>>=1;
if(SDA)
temp|=0x80;
SCK=1;
}
RST=0; _nop_();
SCK=0; _nop_();
SCK=1; _nop_();
SDA=0; _nop_();
SDA=1; _nop_();
return (temp);
}
#define WP 0x8e
#define W_Sec 0x80
#define R_Sec 0x81
#define W_Min 0x82
#define R_Min 0x83
#define W_Hour 0x84
#define R_Hour 0x85
void Write_Time(ds1302 *Date)
{
unsigned char Sec,Min,Hour;
Hour = Date -> Hour/10*16 + Date->Hour%10;
Min = Date->Min/10*16+Date->Min%10;
Sec = Date->Sec/10*16+Date->Sec%10;
Write_Ds1302_Byte(WP,0x00);
Write_Ds1302_Byte(W_Sec,Sec);
Write_Ds1302_Byte(W_Min,Min);
Write_Ds1302_Byte(W_Hour,Hour);
Write_Ds1302_Byte(WP,0x00);
}
ds1302 Read_Time(void)
{
unsigned char Hour,Min,Sec;
ds1302 Date;
Hour = Read_Ds1302_Byte(R_Hour);
Min = Read_Ds1302_Byte(R_Min);
Sec = Read_Ds1302_Byte(R_Sec);
Date.Hour=Hour/16*10+Hour%16;
Date.Min=Min/16*10+Min%16;
Date.Sec=Sec/16*10+Sec%16;
return Date;
}
ds1302.h
#ifndef __DS1302_H__
#define __DS1302_H__
#include <STC15F2K60S2.H>
#include "intrins.h"
typedef struct {
unsigned char Sec;
unsigned char Min;
unsigned char Hour;
}ds1302;
void Write_Time(ds1302 *Date);
ds1302 Read_Time(void);
#endif