第十二届蓝桥杯单片机组省赛试题

该程序展示了使用STC15F2K60S2单片机进行温度监测(DS18B20传感器)、DAC输出控制(PCA模块)以及数码管显示和按键交互的功能。主要功能包括读取温度、根据设定阈值调整DAC输出、显示温度和DAC电压值,并通过按键切换显示模式。
摘要由CSDN通过智能技术生成

第十二届蓝桥杯单片机组省赛
模块函数用的是我之前那篇文章的,有需要的可以去看一下。

模块一. DAC

void pcf_dac(unsigned char dac)
{
	IIC_Start();

	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x43);
	IIC_WaitAck();
	IIC_SendByte(dac);
	IIC_WaitAck();

	IIC_Stop();
}

模块二. DS18B20

float ds18_read(void)
{
	float temp_f;
	unsigned char temp_u,low,high;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	Delay_OneWire(200);
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	
	low = Read_DS18B20();
	high = Read_DS18B20();
	
	temp_u = (high << 4)|(low >> 4);
	temp_f = temp_u + (low&0x0f)*0.0625;
	
	return temp_f;
}

其他模块

other.c

#include <other.h>

void Delay2ms(void)		//@11.0592MHz
{
	unsigned char i, j;

	i = 22;
	j = 128;
	do
	{
		while (--j);
	} while (--i);
}

unsigned char seg_tran(int num)
{
	unsigned char date;
	
	switch(num)
    {
        case	0	:	date = 	0xc0	;	break;
		case	1	:	date = 	0xf9	;	break;
		case	2	:	date = 	0xa4	;	break;
		case	3	:	date = 	0xb0	;	break;
		case	4	:	date = 	0x99	;	break;
		case	5	:	date = 	0x92	;	break;
		case	6	:	date = 	0x82	;	break;
		case	7	:	date = 	0xf8	;	break;
		case	8	:	date = 	0x80	;	break;
		case	9	:	date = 	0x90	;	break;
		case	10	:	date = 	0xbf	;	break;//-
		case	11	:	date = 	0xc6	;	break;//c
		case	12	:	date = 	0x8c	;	break;//p
		case	13	:	date = 	0x86	;	break;//e
		case	14	:	date = 	0xc7	;	break;//L
		case 	15	:	date = 	0xc8	;	break;//a
    }
	
	return date;
}

void seg_disp(int adr,int num)
{
	unsigned char seg_adr[8] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
	
	P2 = P2&0x1f|0xe0;
	P2 = P2&0x1f;
	P0 = seg_adr[adr];
	
	P2 = P2&0x1f|0xc0;
	P2 = P2&0x1f;
	P0 = seg_tran(num);
	
	P2 = P2&0x1f|0xe0;
	P2 = P2&0x1f;
}

void seg_disp1(int adr,int num)
{
	unsigned char seg_adr[8] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
	
	P2 = P2&0x1f|0xe0;
	P2 = P2&0x1f;
	P0 = seg_adr[adr];
	
	P2 = P2&0x1f|0xc0;
	P2 = P2&0x1f;
	P0 = seg_tran(num)&0x7f;
	
	P2 = P2&0x1f|0xe0;
	P2 = P2&0x1f;
}

int key_scan(void)
{
	int key,key_mark;
	
	P3 = 0x0f;
	
	P44 = 0;P42 = 1;P35 = 1;P34 = 1;
	key = P3;
	P44 = 1;P42 = 0;
	key = (key<<4)|(P3&0x0f);
	P42 = 1;P35 = 0;
	key = (key<<4)|(P3&0x0f);
	P35 = 1;P34 = 0;
	key = (key<<4)|(P3&0x0f);
	
	switch(~key)
	{
		case 0x8000: key_mark = 4;break; 
		case 0x4000: key_mark = 5;break; 
		case 0x2000: key_mark = 6;break; 
		case 0x1000: key_mark = 7;break; 
		case 0x0800: key_mark = 8;break; 
		case 0x0400: key_mark = 9;break; 
		case 0x0200: key_mark = 10;break; 
		case 0x0100: key_mark = 11;break; 
		case 0x0080: key_mark = 12;break; 
		case 0x0040: key_mark = 13;break; 
		case 0x0020: key_mark = 14;break; 
		case 0x0010: key_mark = 15;break; 
		case 0x0008: key_mark = 16;break; 
		case 0x0004: key_mark = 17;break; 
		case 0x0002: key_mark = 18;break; 
		case 0x0001: key_mark = 19;break; 
		default    : key_mark = 0 ;break;//这句很重要,必须有!
	}
	return key_mark;
}

void close_perl(void)
{
	P0 = 0xff;
	P2 = P2&0x1f|0x80;
	P2 = P2&0x1f;
	
	P0 = 0x00;
	P2 = P2&0x1f|0xa0;
	P2 = P2&0x1f;
}

other.h

#ifndef __OTHER_H_
#define __OTHER_H_

#include <stc15f2k60s2.h>

void Delay2ms(void);
unsigned char seg_tran(int num);
void seg_disp(int adr,int num);
void seg_disp1(int adr,int num);
int key_scan(void);
void close_perl(void);

#endif 

main.c文件

#include <other.h>
#include <onewire.h>
#include <iic.h>

int temp_100;
float temp_f;
unsigned char temp_can = 25;
	
unsigned char key_old;

char seg_mode;
char dac_mode;

unsigned char dac;
float dac_vol_f;
unsigned int dac_vol_100;

void key_pro(void)
{
	unsigned char key_val,key_down;
	
	key_val = key_scan();
	key_down = key_val&(key_val^key_old);
	key_old = key_val;
	
	switch(key_down)
	{
		case 4:
			seg_mode ++;
			if(seg_mode == 3)	seg_mode = 0;	 
		break;
		
		case 5:
			dac_mode ++;
			if(dac_mode == 2)	dac_mode = 0;
		break;
		
		case 8:
			if(seg_mode == 1)	temp_can--;
		break;
		
		case 9:
			if(seg_mode == 1)	temp_can++;
		break;
	}
}

void seg_pro(void)
{
	temp_f = ds18_read();
	temp_100 = temp_f*100;
	
	dac_vol_f = (float)dac/255*5;
	dac_vol_100 = dac_vol_f*100;
	
	pcf_dac(dac);
	switch(dac_mode)
	{
		case 0:	
			if(temp_f < temp_can)	dac =  0;
			else dac = 255;
		break;
		
		case 1:
			if(temp_f < 20.00)	dac = 51;
			else if(temp_f > 40.00)	dac = 204;
			else dac = 7.65*temp_f-102;
		break;
	}
	
	switch(seg_mode)
	{
		case 0:
			seg_disp(0,11);Delay2ms();		
			seg_disp(4,temp_100/1000);Delay2ms();			
			seg_disp1(5,temp_100%1000/100);Delay2ms();
			seg_disp(6,temp_100%100/10);Delay2ms();
			seg_disp(7,temp_100%10);Delay2ms();
		break;
		
		case 1:
			seg_disp(0,12);Delay2ms();
			seg_disp(6,temp_can/10);Delay2ms();
			seg_disp(7,temp_can%10);Delay2ms();
		break;
		
		case 2:
			seg_disp(0,15);Delay2ms();
			seg_disp1(5,dac_vol_100/100);Delay2ms();
			seg_disp(6,dac_vol_100%100/10);Delay2ms();
			seg_disp(7,dac_vol_100%10);Delay2ms();
		break;
	}
}

void led_pro(void)
{
	P0 = 0xff;
	
	if(dac_mode == 0)	P0 = P0&(~0x01);	else	P0 = P0|0x01;
	if(seg_mode == 0)	P0 = P0&(~0x02);	else	P0 = P0|0x02;
	if(seg_mode == 1)	P0 = P0&(~0x04);	else	P0 = P0|0x04;
	if(seg_mode == 2)	P0 = P0&(~0x08);	else	P0 = P0|0x08;
	
	P2 = P2&0x1f|0x80;
	P2 = P2&0x1f;
}

void main(void)
{
	close_perl();
	while(1)
	{
		seg_pro();
		key_pro();
		led_pro();
	}
}

效果基本实现,如有问题,感谢大佬指出!!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值