之前没有关注这个模拟赛,现在发现了顺手练习以下,还有2天就要开始比赛了,希望大家好好发挥
main函数以及各种定义
#include "reg52.h"
#include "stdio.h"
#include "intrins.h"
typedef unsigned char u8;
typedef unsigned int u16;
#define U ~0x3e
#define DELAY_TIME 20 //iic延时
#define SlaveAddrW 0x90 //pcf8591 写读地址
#define SlaveAddrR 0x91
sbit led1=P0^0; //led蜂鸣器继电器引脚声明
sbit led2=P0^1;
sbit led3=P0^2;
sbit beep=P0^6;
sbit relay=P0^4;
sbit DQ = P1^4; //单总线接口
//总线引脚定义
sbit SDA = P2^1; /* 数据线 */
sbit SCL = P2^0; /* 时钟线 */
void dis_page(); //页面显示函数
void sys_init(); //系统初始化函数
void led_kz(); //led控制函数
void relay_beep_kz(); //继电器蜂鸣器控制函数
void send_string(u8 *x); //串口发送字符串函数
void key_set(); //按键改变状态函数
void UartInit(void); //串口初始化,波特率9600
void send_char(u8 x); //串口发送字符
float get_tmp(); //ds18b20获取温度
float ad_read_rb2(u8 addr); //读取ad值
//u8 putchar(u8 x);
const u8 smg_code[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0x7f};
u16 tmp_dis=275; //显示的温度变量
u16 ad_dis=135; //显示的ad变量
u8 key_flag=0; //按键松开标志,松开为0按下不松开为1
u8 page=0; //页面号
u8 led3_flag=0; //led3闪烁标志,没写
u8 flag=0; //按键锁定标志,s4按下为1,s5按下为0
u8 read_buff; //串口读取的数据
void main()
{
sys_init(); //系统初始化
UartInit(); //串口初始化
while(1)
{
ad_dis=ad_read_rb2(0x03)*100; //读取ad值
tmp_dis=get_tmp()*10; //读取温度值
key_set(); //按键扫描改变
dis_page(); //显示页面
led_kz(); //led控制
relay_beep_kz(); //蜂鸣器继电器控制
}
}
系统初始化以及数码管显示函数
void h138(u8 x)
{
switch(x)
{
case 1:{P2=P2&0X1F|0X80;break;} //LED
case 2:{P2=P2&0X1F|0Xa0;break;} //RELAY
case 3:{P2=P2&0X1F|0XC0;break;} //SMG_W
case 4:{P2=P2&0X1F|0XE0;break;} //SMG_D
}
}
void sys_init()
{
h138(1);
P0=0XFF;
h138(2);
relay=0;
beep=0;
}
void delay(u16 x)
{
while(x--);
}
void smg_dis_one(u8 x,u8 dat)
{
h138(3);
P0=0x01<<x;
delay(5);
h138(4);
P0=dat;
delay(200);
P0=0XFF;
}
void smg_dis_all(u8 d0,u8 d1,u8 d2,u8 d3,u8 d4,u8 d5,u8 d6,u8 d7)
{
smg_dis_one(0,d0);
smg_dis_one(1,d1);
smg_dis_one(2,d2);
smg_dis_one(3,d3);
smg_dis_one(4,d4);
smg_dis_one(5,d5);
smg_dis_one(6,d6);
smg_dis_one(7,d7);
}
void dis_page()
{
if(page==0)
{
smg_dis_all(U,smg_code[1],0xff,0xff,0xff,smg_code[tmp_dis/100],smg_code[tmp_dis%100/10]&0x7f,smg_code[tmp_dis%10]);
}
if(page==1)
{
smg_dis_all(U,smg_code[2],0xff,0xff,0xff,smg_code[ad_dis/100]&0x7f,smg_code[ad_dis%100/10],smg_code[ad_dis%10]);
}
}
按键扫描函数和按键控制函数
u8 key_scan()
{
u8 key,h,l;
P44=1;P42=1;P3=0XF0;
if(P44==0||P42==0||P3!=0XF0&&key_flag==0)
{
if(P44==0) l=1;
if(P42==0) l=2;
if(P35==0) l=3;
if(P34==0) l=4;
}
P44=0;P42=0;P3=0X0F;
if(P3!=0X0F&&key_flag==0)
{
key_flag=1;
if(P30==0) h=4;
if(P31==0) h=3;
if(P32==0) h=2;
if(P33==0) h=1;
}
key = l*4+h-1;
while(P3!=0X0F)
{
return key;
}
key_flag=0;
return 0;
}
void key_set()
{
u8 key;
key=key_scan();
if(key==4) flag=1;
if(flag==1){
if(key==5) flag=0;
}
if(key==12){
if(page==0) printf("TEMP:%.1fC\n",tmp_dis/10.0);
if(page==1) printf("Voltage:%.2fV\n",ad_dis/100.0);
}
}
继电器蜂鸣器和led控制函数
void led_kz()
{
h138(1);
if(page==0) led1=0;
else led1=1;
if(page==1) led2=0;
else led2=1;
if(flag) led3=0;
else led3=1;
}
void relay_beep_kz()
{
h138(2);
if(tmp_dis>=280) relay=1;
else relay=0;
if(ad_dis>360) beep=1;
else beep=0;
}
串口配置使用
void UartInit(void) //9600bps@12.000MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器时钟1T模式
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设置定时器模式
TL1 = 0xC7; //设置定时初始值
TH1 = 0xFE; //设置定时初始值
ET1 = 0; //禁止定时器中断
TR1 = 1; //定时器1开始计时
EA=1;
ES=1;
REN=1;
}
void uart() interrupt 4 using 1
{
if(RI)
{
read_buff=SBUF;
RI=0;
if(flag==0){
if(read_buff=='A') page=0;
if(read_buff=='B') page=1;
}
}
}
void send_char(u8 x)
{
SBUF=x;
while(!TI);
TI=0;
}
//void send_string(u8 *x)
//{
// u8 i=0;
// while(*(x+i)!='\0')
// {
// send_char(*(x+i));
// i++;
// }
//}
/*
**重写printf调用的putchar函数,重定向到串口输出
**需要引入头文件<stdio.h>
*****/
char putchar(char c){
//输出重定向到串口
send_char(c);
return c; //返回给函数的调用者printf
}
还有两个模块获取数据这里就不贴出了,祝大家都能取得好成绩。