#include <STC15F2K60S2.H>
#include "intrins.h"
#include "delay.h"
#include "inithc138.h"
#include "onewire.h"
#include "iic.h"
#include "stdio.h"
#include "string.h"
#define de 5
code unsigned char Seg_Table[17] =
{
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0x88, //A
0x83, //b
0xc6, //C
0xa1, //d
0x86, //E
0x8e, //F
0xbf
};
bit show = 0;//显示功能切换
unsigned char shuju = 0;//数据界面显示切换
bit canshu = 0;//参数界面切换
bit ce = 1;
unsigned int temp = 0;//温度
unsigned int time = 0;//超声波传播时间
unsigned int distance = 0;//测距距离
unsigned int cishu = 0;//参数变更次数
char tempcan = 30;//温度参数
char tempcancertain = 30;//温度参数确定值
char discan = 35;//距离参数
char discancertain = 35;//距离参数确定值
bit keystat = 0;
unsigned char keycount = 0;//长按计时
bit DACoutput = 1;//DAC输出功能模式
unsigned char zifushu = 0;//命令字符数
unsigned char command[10] = {0};//命令
unsigned char ledstat = 0xff;//LED状态
bit disflag = 0;
//***************************************测温模块
void cewen(){
unsigned char MSB,LSB;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
if(ce){
ce = 0;
Delay(550);
}
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
LSB = Read_DS18B20();
MSB = Read_DS18B20();
init_ds18b20();
temp = ((MSB << 8) | LSB) * 6.25;
}
//***************************************
//***************************************测距模块
sbit TX = P1^0;
sbit RX = P1^1;
void Delay12us(void) //@12.000MHz
{
unsigned char data i;
_nop_();
_nop_();
i = 33;
while (--i);
}
void fangbo(){
unsigned char i;
for(i = 0;i < 8;i++){
TX = 1;
Delay12us();
TX = 0;
Delay12us();
}
}
void initpca(){
CMOD = 0x01;
CCON = 0X00;
}
void ceju(){
CH = 0x00;
CL = 0x00;
CF = 0;
CR = 0;
fangbo();
CR = 1;
while((RX == 1) && (CH < 0x17));
CR = 0;
if(RX == 0){
RX = 1;
disflag = 1;
time = (CH << 8) | CL;
distance = time * 0.017;
}else{
disflag = 0;
}
}
//***************************************
//***************************************显示功能
void wendushuju(){//温度数据显示
showsmg(1,Seg_Table[12]);
showsmg(5,Seg_Table[temp / 1000]);
showsmg(6,Seg_Table[temp / 100 % 10] & 0x7f);
showsmg(7,Seg_Table[temp / 10 % 10]);
showsmg(8,Seg_Table[temp % 10]);
}
void julishuju(){//距离数据
showsmg(1,0xc7);
showsmg(7,Seg_Table[distance / 10]);
showsmg(8,Seg_Table[distance % 10]);
}
void cishubiangeng(){//次数变更
showsmg(1,0xc8);
showsmg(8,Seg_Table[cishu % 10]);
if(cishu > 9){
showsmg(7,Seg_Table[cishu / 10 % 10]);
}
if(cishu > 99){
showsmg(6,Seg_Table[cishu / 100 % 10]);
}
if(cishu > 999){
showsmg(5,Seg_Table[cishu / 1000 % 10]);
}
if(cishu > 9999){
showsmg(4,Seg_Table[cishu / 10000 % 10]);
}
}
void shujujiemian(){//数据界面模式选择
switch(shuju){
case 0:wendushuju();break;
case 1:julishuju();break;
case 2:cishubiangeng();break;
}
}
void wenducanshu(){//温度参数
showsmg(1,0x8c);
if(canshu == 0){
showsmg(4,Seg_Table[1]);
showsmg(7,Seg_Table[tempcan / 10]);
showsmg(8,Seg_Table[tempcan % 10]);
}else{
showsmg(4,Seg_Table[2]);
showsmg(7,Seg_Table[discan / 10]);
showsmg(8,Seg_Table[discan % 10]);
}
}
//***************************************
void showselect(){
if(show == 0){
shujujiemian();
}else{
wenducanshu();
}
}
//***************************************
//***************************************长短按检测
void Timer0_Isr(void) interrupt 1
{
if(keystat){
keycount++;
}
}
void Timer0_Init(void) //50毫秒@12.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xB0; //设置定时初始值
TH0 = 0x3C; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
EA = 1;
}
//***************************************
//***************************************按键扫描
void shujugaibian(){//判断数据是否发生改变
if((discancertain != discan) || (tempcancertain != tempcan)){
cishu++;
discancertain = discan;
tempcancertain = tempcan;
eepromwrite(cishu);
Delay(1);
}else{
discan = discancertain;
tempcan = tempcancertain;
}
}
void scankey(){
P33 = 0;P32 = 1;P35 = 1;P34 = 1;
if(P35 == 0){Delay(de);while(P35 == 0){//S12
keystat = 1;
showselect();
}
keystat = 0;
if(keycount < 20){//短按
if(show == 0){
shuju++;
shuju %= 3;
}
if(show == 1){
canshu = ~canshu;
}
}else if(keycount >= 20){//长按
cishu = 0;
eepromwrite(cishu);
Delay(1);
}
keycount = 0;
}
if(P34 == 0){Delay(de);while(P34 == 0){//S16
showselect();
}
if((show == 1) && (canshu == 0)){//温度参数界面
tempcan -= 2;
if(tempcan < 0){tempcan = 0;}
}
if((show == 1) && (canshu == 1)){
discan -= 5;
if(discan < 0){discan = 0;}
}
}
P33 = 1;P32 = 0;P35 = 1;P34 = 1;
if(P35 == 0){Delay(de);while(P35 == 0){//S13
keystat = 1;
showselect();
}
keystat = 0;
if(keycount < 20){//短按
if(show == 1){
shujugaibian();//判断数据是否发生改变
}
show = ~show;canshu = 0;shuju = 0;
}else if(keycount >= 20){//长按
DACoutput = ~DACoutput;
}
keycount = 0;
}
if(P34 == 0){Delay(de);while(P34 == 0){//S17
showselect();
}
if((show == 1) && (canshu == 0)){//温度参数界面
tempcan += 2;
if(tempcan > 99){tempcan = 99;}
}
if((show == 1) && (canshu == 1)){
discan += 5;
if(discan > 99){discan = 99;}
}
}
}
//***************************************串口通讯
void Uart1_Isr(void) interrupt 4
{
if (RI) //检测串口1接收中断
{
command[zifushu] = SBUF;
zifushu++;
RI = 0; //清除串口1接收中断请求位
}
}
void Uart1_Init(void) //4800bps@12.000MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x01; //串口1选择定时器2为波特率发生器
AUXR |= 0x04; //定时器时钟1T模式
T2L = 0x8F; //设置定时初始值
T2H = 0xFD; //设置定时初始值
AUXR |= 0x10; //定时器2开始计时
ES = 1; //使能串口1中断
}
void sendbyte(unsigned char dat){//串口发送单字节
SBUF = dat;
while(TI == 0);
TI = 0;
}
void minglingshibie(){//命令识别
unsigned char i;
if(command[zifushu - 1] == '\n'){
if((command[0] == 'S') && (command[1] == 'T') && (command[2] == '\r') && (command[3] == '\n')){
printf("$%d,%d.%d",(int)(distance),(int)(temp / 100),(int)(temp % 100));
}else if((command[0] == 'P') && (command[1] == 'A') && (command[2] == 'R') && (command[3] == 'A')){
printf("#%d,%d\r\n",(int)(tempcancertain),(int)(discancertain));
}else{
printf("ERROR\r\n");
}
zifushu = 0;
for(i = 0;i < 10;i++){
command[i] = 0;
}
}
}
char putchar(char ch){//重定向
sendbyte(ch);
return ch;
}
//***************************************
//***************************************DAC输出模块与LED灯
void DACshuchu(){
if(DACoutput){
if(distance <= discancertain){
DAC(102);
}else if(distance > discancertain){
DAC(204);
}
}else{
DAC(21);
}
}
void led(){
if(temp > (tempcancertain * 100)){
ledstat = ledstat & ~0x01;
}else{
ledstat = ledstat | 0x01;
}
if((distance < discancertain) && (disflag)){
ledstat = ledstat & ~0x02;
}else{
ledstat = ledstat | 0x02;
}
if(DACoutput){
ledstat = ledstat & ~0x04;
}else{
ledstat = ledstat | 0x04;
}
outputp0(4,ledstat);
}
//***************************************
//***************************************
void main(){
initsys();
initpca();
cewen();
Uart1_Init();
Timer0_Init();
cishu = eepromread();
while(1){
ceju();
showselect();
cewen();
showselect();
scankey();
showselect();
minglingshibie();
DACshuchu();
led();
}
}