一、初始化系统
首先将系统初始化,关闭蜂鸣器继电器
#include "STC15.h"
#define uchar unsigned char
#define uint unsigned int
void InitHC138(uchar n)
{
switch(n)
{
case 4:P2 = (P2 & 0x1f) | 0x80;break;//LED
case 5:P2 = (P2 & 0x1f) | 0xa0;break;//蜂鸣器、继电器
case 6:P2 = (P2 & 0x1f) | 0xc0;break;//位选
case 7:P2 = (P2 & 0x1f) | 0xe0;break;//段选
}
}
void InitSystem()
{
InitHC138(5);
P0 = 0x00;//关闭蜂鸣器、继电器
InitHC138(4);
P0 = 0xff;//关灯
}
头文件
#ifndef _INITSYSTEM_H
#define _INITSYSTEM_H
#include "STC15.h"
#define uchar unsigned char
#define uint unsigned int
extern void InitHC138(uchar n);
extern void InitSystem();
#endif
二、配置中断
配置中断的时候会有许多参数,这些参数在后面也会用到,最好要自己记住,不能混。
配置寄存器的时候要这样:
TMOD = (TMOD & 0x0f) | 0x10;
不能直接或等于
同时要记得配置AUXR,蓝桥杯板子的寄存器
#include "STC15.h"
#include "InitSystem.h"
#include "onewire.h"
//sfr AUXR = 0x8e;
uchar count = 0;
uchar T_s = 120;//数码管显示的秒数
uchar PWM_duty = 0;//脉宽调试的参数
uchar num = 0;
sbit S = P3^4;
void InitTimer1()
{
TMOD = (TMOD & 0x0f) | 0x10;
TH1 = (65535-50000)/256;
TL1 = (65535-50000)%256;
AUXR = 0xC0;
TF1 = 0;
EA = 1;
ET1 = 1;
TR1 = 1;
}
void Timer1()interrupt 3
{
TH1 = (65535-50000)/256;
TL1 = (65535-50000)%256;
count++;
if(count == 20)
{
T_s--;
}
if(T_s == 0)
{
EA = 0;
InitHC138(4);
P0 = 0x00;
}
}
void InitTimer0() //控制风速
{
TMOD = (TMOD & 0xf0) | 0x01;
TH0 = (65535-100)/256;
TL0 = (65535-100)%256;
// AUXR |= 0x80;
TF0 = 0;
ET0 = 1;
EA = 1;
TR0 = 1;
}
void Timer0()interrupt 1
{
TH0 = (65535-100)/256;
TL0 = (65535-100)%256;
num++;
if(num == PWM_duty)
{
S = 0;
}
if(num == 100)
{
S = 1;
num = 0;
}
}
头文件
#ifndef _INTERRUPT_H
#define _INTERRUPT_H
#include "STC15.h"
#include "InitSystem.h"
#include "onewire.h"
extern uchar count;
extern uchar T_s;
extern uchar PWM_duty;
extern uchar num;
sbit S = P3^4;
extern void InitTimer1();
//extern void Timer1()interrupt 3;
extern void InitTimer0();
//extern void Timer0()interrupt 1;
#endif
中断服务函数写一遍就行了(第一次这样写)
三、按键扫描
按键扫描会用到上一步中断中的参数,一定不要用错
按键扫描重要还是按照功能写,我觉得吧,按键里面还是不要有中断里的寄存器了,因为按键改bug改了好久,教程里把中断中的寄存器写在按键里了,参考别人的代码,没有写在里面。先这么写,以后继续看。
#include "STC15.h"
#include "InitSystem.h"
#include "onewire.h"
#include "Interrupt.h"
#include "SMG.h"
uchar K = 1;//风扇功能号
uchar Flag_K = 0;
uchar Flag_time = 0;//时间标志位
sbit S4 = P3^3;//风扇风速控制
sbit S5 = P3^2;//控制定时时长
sbit S6 = P3^1;//停止按键,按下按键时间清零,风扇不转
sbit S7 = P3^0;//室温按键
void ScanKey()
{
if(S4 == 0)
{
delay(10);
while(!S4)
{
display_SMG();
switch(K)
{
case 1:
S = 1;
PWM_duty = 20;
K = 2;
break;
case 2:
PWM_duty = 50;
K = 3;
break;
case 3:
PWM_duty = 70;
K = 1;
break;
}
while(S4 == 0)
{
display_SMG();
}
}
}
if(S5 == 0)
{
delay(10);
while(!S5)
{
display_SMG();
switch(Flag_time)
{
case 0:T_s = 60;Flag_time = 1;break;
case 1:T_s = 120;Flag_time = 2;break;
case 2:T_s = 0;Flag_time = 0;break;
}
while(S5 == 0)
{
display_SMG();
}
}
}
if(S6 == 0)
{
delay(10);
while(!S6)
{
display_SMG();
count = 0;
Flag_time = 0;
T_s = 0;
EA = 0;
while(S6 == 0)
{
display_SMG();
}
}
}
if(S7 == 0)
{
delay(10);
while(!S7)
{
display_SMG();
//K = 4;
if(Flag_K == 0)
{
Flag_K = 1;
Read_Temperature();
display_SMG();
}
else
{
Flag_K = 0;
}
while(S7 == 0)
{
display_SMG();
}
}
}
}
头文件
#define _KEY_H
#include "STC15.h"
#include "InitSystem.h"
#include "onewire.h"
#include "Interrupt.h"
#include "SMG.h"
extern uchar K;
extern uchar Flag_K;
extern void ScanKey();
#endif
这里面还用了DS18B20,要用onewire收发数据,蓝桥杯的赛点资源包里面已经有相关代码了
*
程序说明: 单总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台(外部晶振12MHz) STC89C52RC单片机
日 期: 2011-8-9
*/
#include "STC15.h"
sbit DQ = P1^4; //单总线接口
unsigned int T_dat;
//单总线延时函数
void Delay_OneWire(unsigned int t) //STC89C52RC
{
t = t*7;
while(t--);
}
void delay(unsigned int time)
{
while(time--);
}
//通过单总线向DS18B20写一个字节
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);
}
//从DS18B20读取一个字节
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;
}
void Read_Temperature()
{
unsigned int LSB,MSB;
Init_DS18B20();
Write_DS18B20(0xCC);//跳过ROM指令
Write_DS18B20(0x44);//开始温度转换
delay(1000);
Init_DS18B20();
Write_DS18B20(0xCC);//跳过ROM指令
Write_DS18B20(0xbe);//写入读取高速暂存器
LSB = Read_DS18B20();
MSB = Read_DS18B20();
Init_DS18B20();
T_dat = 0x0000;
T_dat = MSB;
T_dat = T_dat << 8;
T_dat = T_dat | LSB;
T_dat = T_dat >> 4;
}
但还是需要修改,延时函数需要修改
void Delay_OneWire(unsigned int t) //STC89C52RC
{
t = t*7;//修改部分
while(t--);
}
另外除了官方给的代码,还有加几个函数,这个题我就加了一个读温度数据并转换十进制,精确到个位
void Read_Temperature()
{
unsigned int LSB,MSB;
Init_DS18B20();
Write_DS18B20(0xCC);//跳过ROM指令
Write_DS18B20(0x44);//开始温度转换
delay(1000);
Init_DS18B20();
Write_DS18B20(0xCC);//跳过ROM指令
Write_DS18B20(0xbe);//写入读取高速暂存器
LSB = Read_DS18B20();
MSB = Read_DS18B20();
Init_DS18B20();
T_dat = 0x0000;
T_dat = MSB;
T_dat = T_dat << 8;
T_dat = T_dat | LSB;
T_dat = T_dat >> 4;
}
微处理器读取单个DS18B20的温度数据,可参考以下步骤:
【1】DS18B20复位。
【2】写入字节0xCC,跳过ROM指令。
【3】写入字节0x44,开始温度转换。
【4】延时700~900ms。
【5】DS18B20复位。
【6】写入字节0xCC,跳过ROM指令。
【7】写入字节0xBE,读取高速暂存器。
【8】读取暂存器的第0字节,即温度数据的LSB。
【9】读取暂存器的第1字节,即温度数据的MSB。
【10】 DS18B20复位。,表示读取数据结束。
【11】将LSB和MSB整合成为一个16位数据。
【12】判断读取结果的符号,进行正负温度的数据处理。
onewire的头文件
#ifndef __ONEWIRE_H
#define __ONEWIRE_H
unsigned char rd_temperature(void); //; ;
#include "STC15.h"
extern unsigned int T_dat;
sbit DQ = P1^4;
extern void Delay_OneWire(unsigned int t);
extern void delay(unsigned int time);
extern void Write_DS18B20(unsigned char dat);
extern unsigned char Read_DS18B20(void);
extern bit Init_DS18B20(void);
extern void Read_Temperature();
#endif
四、数码管
数码管感觉不是太难,但是还是有问题,数码管显示不太亮,,,
#include "STC15.h"
#include "InitSystem.h"
#include "onewire.h"
#include "Key.h"
#define uchar unsigned char
#define uint unsigned int
unsigned char code SMG_duan[18] = {
0xc0,0xf9,0xa4,
0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x80,0xc6,
0xc0,0x86,0x8e,0xbf,0x7f};
void display(uchar wei,uchar duan)
{
InitHC138(7);
P0 = 0xff;
InitHC138(6);//位选
P0 = 0x01 << wei;
InitHC138(7);//段选
P0 = duan;
}
void display_all(uchar vaule)
{
InitHC138(7);
P0 = vaule;
InitHC138(6);
P0 = 0xff;
}
void display_SMG()
{
if(Flag_K == 0)
{
display(0,SMG_duan[16]);
delay(100);
display(1,SMG_duan[K]);
delay(100);
display(2,SMG_duan[16]);
delay(100);
display(7,SMG_duan[T_s%10]);
delay(100);
display(6,SMG_duan[(T_s/10)%10]);
delay(100);
display(5,SMG_duan[T_s/100]);
delay(100);
display(4,SMG_duan[0]);
delay(100);
display_all(0xff);
}
else
{
display(0,SMG_duan[16]);
delay(100);
display(1,SMG_duan[4]);
delay(100);
display(2,SMG_duan[16]);
delay(100);
display(7,SMG_duan[12]);
delay(100);
display(6,SMG_duan[T_dat%10]);
delay(100);
display(5,SMG_duan[T_dat/10]);
delay(100);
display_all(0xff);
}
}
头文件
#ifndef _SMG_H
#define _SMG_H
#include "STC15.h"
#include "InitSystem.h"
#include "onewire.h"
//extern unsigned char code SMG_duan[18] = {0xc0,0xf9,0xa4,
// 0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x80,0xc6,
// 0xc0,0x86,0x8e,0xbf,0x7f};
extern void display(uchar wei,uchar duan);
extern void display_all(uchar vaule);
extern void display_SMG();
#endif
五,主函数
最后统筹规划一下
#include "STC15.h"
#include "InitSystem.h"
#include "onewire.h"
#include "Key.h"
#include "SMG.h"
#include "Interrupt.h"
void LEDScan()
{
if(K == 1)
{
InitHC138(4);
P0 = 0xfe;
}
else if(K == 2)
{
InitHC138(4);
P0 = 0xfd;
}
else if(K == 3)
{
InitHC138(4);
P0 = 0xfb;
}
}
void main()
{
InitSystem();
while(1)
{
if(T_s>0)
{
InitTimer1();
InitTimer0();
}
Read_Temperature();
LEDScan();
display_SMG();
ScanKey();
}
}
第一次打这样的比赛程序,虽然不太难,但是我还是打的不好。模块之间的联系还是有点大吧,模块之间用到的参数有点多,有的bug就是参数用错了。。。还是练的太少,,,emmmmmmmmmm。。。bug不好改呀。