因为蓝桥杯比赛时,底层驱动代码没有头文件,以下代码直接复制到main.c即可运行。
频率显示前把P34与SINGHAl连起来。
数码管前六位为频率,后三位为温度。
#include <STC15F2K60S2.H>
#include <intrins.h>
typedef unsigned char u8;
typedef unsigned int u16;
u8 code smg_code[] = { 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
u8 smg_buf[8];
typedef struct {
u8 b0 : 1;
u8 b1 : 1;
u8 b2 : 1;
u8 b3 : 1;
u8 b4 : 1;
u8 b5 : 1;
u8 b6 : 1;
u8 b7 : 1;
}bits;
typedef union {
bits b;
u8 hex;
} hexandb;
hexandb led_ctrl;
// 系统初始化
void vSystem_ctrl (u8 P2data, u8 P0data)
{
P0 = P0data;
P2 = ( P2 & 0x1f) | P2data;
P2 = P2 & 0x1f;
}
void vSystem_init ()
{
led_ctrl.hex = 0xff;
vSystem_ctrl (0x80, led_ctrl.hex);
vSystem_ctrl (0xa0,0);
}
// 温度读取
sbit DQ = P1^4;
//单总线内部延时函数
void Delay_OneWire(unsigned int t)
{
t = t * 12 ;
while(t--);
}
//单总线写操作
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;
if(DQ)
{
dat |= 0x80;
}
Delay_OneWire(5);
}
return dat;
}
//DS18B20初始化
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;
}
//***温度操作函数
float fDS18B20_temp_read ()
{
u8 low, high;
float temp_val;
init_ds18b20 ();
Write_DS18B20 (0xcc);
Write_DS18B20 (0x44);
init_ds18b20 ();
Write_DS18B20 (0xcc);
Write_DS18B20 (0xbe);
low = Read_DS18B20 ();
high = Read_DS18B20 ();
temp_val = (( high << 8 ) | low ) * 0.0625;
return temp_val;
}
u8 temp_count;
u16 temp_display;
float temp_val;
void vDS18B20_temp_process ()
{
if (temp_count >= 50)
{
temp_count = 0;
temp_val = fDS18B20_temp_read ();
temp_display = (u16)( temp_val * 10);}
}
u16 squr_count;
u16 squr;
void vCounter0_init ()
{
TMOD |= 0x05;
TL0 = 0;
TH0 = 0;
TR0 = 1;
}
void vSqur_process ()
{
if (squr_count == 1000 )
{
squr_count = 0;
squr = ( TH0 << 8 ) | TL0;
TL0 = 0;
TH0 = 0;
}
}
//数码管的相关函数
void vSMG_process ()
{
smg_buf[0] = smg_code[squr/10000]; // 频率
smg_buf[1] = smg_code[squr%10000/1000];
smg_buf[2] = smg_code[squr%1000/100];
smg_buf[3] = smg_code[squr%100/10];
smg_buf[4] = smg_code[squr%10];
smg_buf[5] = smg_code[temp_display / 100]; // 温度
smg_buf[6] = smg_code[temp_display % 100 / 10]| 0x80;
smg_buf[7] = smg_code[temp_display % 10];
}
void vSMG_display ()
{
static u8 i;
vSystem_ctrl (0xc0, 0);
vSystem_ctrl (0xe0, ~smg_buf[i]);
vSystem_ctrl (0xc0, 0x01 << i);
i = ( i + 1 ) %8;
}
void vTimer2_init(void) //1毫秒@12.000MHz
{
AUXR |= 0x04; //定时器时钟1T模式
T2L = 0x20; //设置定时初值
T2H = 0xD1; //设置定时初值
AUXR |= 0x10; //定时器2开始计时
EA = 1;
IE2 |= 0x04;
}
void main ()
{
vTimer2_init();
vSystem_init ();
vCounter0_init();
while (1)
{
vDS18B20_temp_process ();
vSMG_process ();
vSqur_process ();
}
}
void vTimer2_serve (void) interrupt 12
{
temp_count++;
vSMG_display ();
squr_count++;
}