大家好,首先呢介绍一下自己,鄙人现大二,接触单片机才一年时间(大佬别笑话俺)
寒假在准备这个比赛,在最近几天,写了一篇关于蓝桥杯单片机组第七届省赛的编程题,
想着发个帖子望大家指点一下,自己的也留个纪念。
也是第一次发帖子,哈哈 莫名有点激动 哈哈
程序都是自己慢慢调试的,下了一番功夫,感觉受益匪浅,感触颇多。
觉的受用的,大家互相学习,觉的有不好的地方,还望能不吝赐教,嘻嘻嘻。
好了,言归正传,先看程序。
主程序 main.c
/**************************************************
代码情况
【IRC频率】11.0592Mhz
【杜邦线】 短接P34 和P07 通过 L8代替电机 观察pwm脉冲信号
**************************************************/
#include <STC15F2K60S2.H>
#include"smg.h"
#include"ds18b20.h"
sbit S7 = P3^0;
sbit S6 = P3^1;
sbit S5 = P3^2;
sbit S4 = P3^3;
sbit PWM = P3^4;
void Keyscan(); //按键检测函数
void ConfigTime0(); //配置定时函数--PWM脉冲
void SMGWorking(); //数码管工作函数
void LedRunning(); //LED运转函数
uchar Wind = 1 ; //风速类型状态:1-“睡眠风”, 2-“自然风”,3-“常风”
uchar F_date = 0; //时间数据
uchar T_date = 0; //温度数据
uchar cnt = 0; //中断次数变量
uint t = 0; //中断定时1s变量
bit flag = 1; //S7控制位
void main()
{
CSH(); //关闭led 蜂鸣器 继电器
ConfigTime0();
while(1)
{
Keyscan();
SMGWorking();
LedRunning();
}
}
void SMGWorking()
{
if(flag == 0)
{
T_date = R_ds18b20();
display18B20_SMG(4 , T_date);
}
if(flag == 1)
{
displaySMG(Wind , F_date);
}
}
void LedRunning()
{
Select573(4);
if(F_date ==0) P0 = 0xFF; //放在第一个判断句
else if(Wind == 1)
{
if(F_date>0) P0 = 0xFE;
}
else if(Wind == 2) P0 = 0xFD;
else if(Wind == 3) P0 = 0xFB;
Select573(0);
P0 = 0xFF;
}
void Keyscan()
{
if(S7 == 0)
{
delay(10);
if(S7 == 0)
{
while(!S7)
{
SMGWorking();
}
flag = ~flag;
}
}
if(S6 == 0)
{
delay(10);
if(S6 == 0)
{
while(!S6)
{
SMGWorking();
}
F_date = 0;
}
}
if(S5 == 0)
{
delay(10);
if(S5 == 0)
{
while(!S5)
{
SMGWorking();
}
if(F_date == 0) F_date = 60;
else if(F_date < 60) F_date = 120;
else if(F_date < 120) F_date = 0;
}
}
if(S4 == 0)
{
delay(10);
if(S4 == 0)
{
while(!S4)
{
SMGWorking();
}
if(Wind == 1) Wind = 2;
else if(Wind == 2) Wind = 3;
else if(Wind == 3) Wind = 1;
}
}
}
/*********************************
【函数】 定时器初始化函数
【功能】 频率为1Khz=1ms , 定时100us , AUXR--1T,不分频
【返回值】 无
*********************************/
void ConfigTime0() //100微秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xAE; //设置定时初值
TH0 = 0xFB; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //定时器0中断打开
EA = 1; //打开总中断
}
/*********************************
【函数】 中断函数
【功能】 进入中断10次为一个周期脉冲
【返回值】 无
*********************************/
void Time0() interrupt 1
{
cnt ++; t++;
if(cnt == 11) cnt = 1;
if(F_date > 0)
{
if(Wind == 1)
{
if(cnt < 3) PWM = 1;
else PWM = 0;
}
else if(Wind == 2)
{
if(cnt < 4) PWM = 1;
else PWM = 0;
}
else if(Wind == 3)
{
if(cnt < 8) PWM = 1;
else PWM = 0;
}
}
if(t == 10000) //定时1s
{
t = 0;
if(F_date > 0) F_date --;
}
}
底层驱动 ds18b20.c
/*
程序说明: 单总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台
日 期: 2011-8-9
*/
#include "ds18b20.h"
//单总线延时函数
void Delay_OneWire(unsigned int t)
{
t = t*12;
while(t--);
}
//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;
}
//通过单总线向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;
}
unsigned char R_ds18b20()
{
unsigned char HS,LS;
unsigned int value = 0 ;
Init_DS18B20();
Write_DS18B20(0xCC); //跳过ROM
Write_DS18B20(0x44);//启动温度转换
Delay_OneWire(200); //温度转换需要一定的时间
Init_DS18B20();
Write_DS18B20(0xCC);
Write_DS18B20(0xBE); //发送读命令
LS = Read_DS18B20();
HS = Read_DS18B20();
value = HS; //0x00hs
value <<= 8; //0xhs00
value |= LS; //0x hs ls
value >>= 4; //0x 0h sl //取整
return value;
}
篇幅有限程序不全,有需求的朋友,请下载后观看
第七届.zip
(75.05 KB, 下载次数: 69)
|