1题目:
主函数while循环里检测温度,按键驱动,显示界面。
中断里实现按键扫描,led灯闪烁,开关继电器。
2代码:
main.c
******************************************************************************
* 文件名:简易温度采集与控制装置
* 描 述:
* 作 者:思索与猫
* 日 期: 19/3/14
* 备 注:
*
******************************************************************************
#include<stc15f2k60s2.h>
#include<onewire.h>
#define Esc 0x99
#define Set 0x88
typedef unsigned char uchar;
typedef unsigned int uint;
sbit Key_Out_1 = P3^0; //横
sbit Key_Out_2 = P3^1;
sbit Key_Out_3 = P3^2;
sbit Key_Out_4 = P3^3;
sbit Key_In_1 = P4^4; //竖
sbit Key_In_2 = P4^2;
sbit Key_In_3 = P3^5;
sbit Key_In_4 = P3^4;
uchar KeySta[4][4] = { {1,1,1,1},
{1,1,1,1},
{1,1,1,1},
{1,1,1,1} };
uchar KeyCodeMap[4][4] = { {'1','2','3',' '}, //10Set ,11Esc
{'4','5','6',' '},
{'7','8','9',' '},
{'0',Set,Esc,' '} };
uchar code duan[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,0x040}; //10black,11-
uchar dispbuff[8];
uchar temp,real_temp,temp_low = 20, temp_high = 30;
bit view = 0,temp_flag = 1,flag_right, flag_led; //flag_right正确标志位
uchar mode,led_dat;
uchar temp_range[] = {3, 0, 2, 0};
uint time ; //时间长度大于256,选择无符号整型
//function
void CloseFucker();
void Timer0Init();
void Display();
void KeyScan();
void KeyDriver();
void KeyAction(uchar temp);
void ShowTable();
void DetectTemp();
void ShowLed(uchar temp);
void main()
{
Timer0Init();
CloseFucker();
while(1)
{
DetectTemp(); //检测温度
KeyDriver();
ShowTable();
}
}
void T0_time() interrupt 1
{
static uint count = 0, temp_count = 0;
TL0 = 0x20;
TH0 = 0xD1;
Display();
KeyScan();
count++;
if(++temp_count == 200) //温度每隔200ms扫描一次
{
temp_flag = 1;
temp_count = 0;
}
if(mode == 0)
{
P2 = P2&0x1f|0xa0;
P0 = 0x00;
P2 = P2&0x1f;
}
else if(mode == 1)
{
P2 = P2&0x1f|0xa0;
P0 = 0x00;
P2 = P2&0x1f;
}
else if(mode == 2)
{
P2 = P2&0x1f|0xa0;
P0 = 0x10; //开继电器
P2 = P2&0x1f;
}
if(count >= time)
{
count = 0;
flag_led = ~flag_led;
if(flag_led ==1)
{
led_dat = 0xff; //全灭
}
else
{
led_dat = 0xfe; //L1亮
}
}
if(flag_right == 0) //温度设置正确,L1闪烁
{
ShowLed(led_dat);
}
else if(flag_right == 1) //温度设置错误,L2常亮
{
ShowLed(0xfd);
}
}
void ShowLed(uchar temp) //显示LED灯
{
P2 = P2&0x1f|0x80;
P0 = temp;
P2 = P2&0x1f;
}
void DetectTemp()
{
if(temp_flag == 1)
{
temp = ReadTemp(); //读取温度
if((temp>0)&&(temp<75))
{
real_temp = temp; //读取真实温度,有跳变!
}
temp_flag = 0;
if(real_temp < temp_low) //判断区间
{
mode = 0;
time = 800;
}
else if(temp_high < real_temp)
{
mode = 2;
time = 200;
}
else if(temp >= real_temp&&real_temp <= temp_high)
{
mode = 1;
time = 400;
}
}
}
void ShowTable()
{
if(view == 0) //温度显示界面
{
dispbuff[0] = 11;
dispbuff[1] = mode;
dispbuff[2] = 11;
dispbuff[3] = 10;
dispbuff[4] = 10;
dispbuff[5] = 10;
dispbuff[6] = real_temp/10;
dispbuff[7] = real_temp%10;
}
else //区间设置界面
{
dispbuff[0] = 11;
dispbuff[1] = temp_range[0];
dispbuff[2] = temp_range[1] ;
dispbuff[3] = 10;
dispbuff[4] = 10;
dispbuff[5] = 11;
dispbuff[6] = temp_range[2];
dispbuff[7] = temp_range[3];
}
}
void KeyAction(uchar temp)
{
static i = 0;
if(temp == Set) //按下设置界面
{
view = ~view;
temp_high = temp_range[0]*10+temp_range[1];
temp_low = temp_range[2]*10+temp_range[3];
if(temp_low > temp_high) //判断设置是否正确
{
flag_right = 1;
}
else
{
flag_right = 0;
}
}
if((view == 1)&&('0' <= temp)&&(temp <= '9')) //设置数字
{
temp_range[i] = temp-'0';
i++;
i &= 0x03;
}
if((view == 1)&&(temp == Esc)) //清除位
{
if(i == 0) i=3;
else i--;
temp_range[i] = 0;
}
}
void KeyDriver() //矩阵键盘
{
uchar i, j;
static uchar keyback[4][4] = { {1,1,1,1},
{1,1,1,1},
{1,1,1,1},
{1,1,1,1} };
for(i=0 ;i<4 ;i++)
{
for(j=0 ;j<4 ;j++)
{
if(KeySta[i][j] != keyback[i][j])
{
if(KeySta[i][j] != 0)
{
KeyAction(KeyCodeMap[i][j]);
}
keyback[i][j] = KeySta[i][j] ;
}
}
}
}
void KeyScan()
{
uchar i = 0;
static uchar keyout = 0;
static uchar keybuff[4][4] = {{0xff,0xff,0xff,0xff},
{0xff,0xff,0xff,0xff},
{0xff,0xff,0xff,0xff},
{0xff,0xff,0xff,0xff} };
switch(keyout)
{
case 0:Key_Out_1 = 0;Key_Out_4 = 1;break;
case 1:Key_Out_2 = 0;Key_Out_1 = 1;break;
case 2:Key_Out_3 = 0;Key_Out_2 = 1;break;
case 3:Key_Out_4 = 0;Key_Out_3 = 1;break;
}
keybuff[keyout][0] = (keybuff[keyout][0]<<1)|Key_In_1;
keybuff[keyout][1] = (keybuff[keyout][1]<<1)|Key_In_2;
keybuff[keyout][2] = (keybuff[keyout][2]<<1)|Key_In_3;
keybuff[keyout][3] = (keybuff[keyout][3]<<1)|Key_In_4;
for(i=0 ;i<4 ;i++)
{
if((keybuff[keyout][i]&0x0f) == 0x00)
{
KeySta[keyout][i] = 0;
}
else if((keybuff[keyout][i]&0x0f) == 0x0f)
{
KeySta[keyout][i] = 1;
}
}
keyout++;
keyout &= 0x03;
}
void Display()
{
static uchar index = 0;
P2 = P2&0x1f|0xe0;
P0 = 0xff;
P2 = P2&0x1f;
P2 = P2&0x1f|0xc0;
P0 = 1<<index;
P2 = P2&0x1f;
P2 = P2&0x1f|0xe0;
P0 = ~duan[dispbuff[index]];
P2 = P2&0x1f;
index++;
index &= 0x07;
}
void Timer0Init() //1ms 12.000MHz
{
AUXR |= 0x80;
TMOD &= 0xF0;
TL0 = 0x20;
TH0 = 0xD1;
TF0 = 0;
TR0 = 1;
ET0 = 1;
EA = 1;
}
void CloseFucker()
{
P2 = P2&0x1f|0xa0;
P0 = 0xaf;
P2 = P2&0x1f;
}
onewire.h
#ifndef _ONEWIRE_H
#define _ONEWIRE_H
#include "stc15f2k60s2.h"
#define OW_SKIP_ROM 0xcc
#define DS18B20_CONVERT 0x44
#define DS18B20_READ 0xbe
sbit DQ = P1^4;
void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
bit Init_DS18B20(void);
unsigned char Read_DS18B20(void);
unsigned char ReadTemp();
#endif
onewire.c
#include "onewire.h"
void Delay_OneWire(unsigned int t)
{
t*=12;
while(t--);
}
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;
}
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;
}
unsigned char ReadTemp()
{
unsigned char temp;
unsigned char low,high;
Init_DS18B20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Delay_OneWire(200);
Init_DS18B20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
Delay_OneWire(200);
low = Read_DS18B20();
high = Read_DS18B20();
temp = high<<4;
temp |= (low&0xf0)>>4;
return temp;
}