找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5046|回复: 4
收起左侧

蓝桥杯单片机第七届省赛 程序题解析(完美调试,清晰理解)

[复制链接]
ID:586435 发表于 2020-2-19 22:18 | 显示全部楼层 |阅读模式
大家好,首先呢介绍一下自己,鄙人现大二,接触单片机才一年时间(大佬别笑话俺

寒假在准备这个比赛,在最近几天,写了一篇关于蓝桥杯单片机组第七届省赛的编程题,
想着发个帖子望大家指点一下,自己的也留个纪念。
也是第一次发帖子,哈哈 莫名有点激动  哈哈
程序都是自己慢慢调试的,下了一番功夫,感觉受益匪浅,感触颇多。





觉的受用的,大家互相学习,觉的有不好的地方,还望能不吝赐教,嘻嘻嘻。
好了,言归正传,先看程序。
批注 2020-02-19 213335.jpg

         主程序  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)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:586435 发表于 2020-2-19 22:34 | 显示全部楼层
本帖最后由 黑夜的星光 于 2020-2-20 09:55 编辑

关于里面的一些细节代码 由于时间问题 没有过多注释,如果有朋友在评论区问及的话 我在指出吧  望理解

smg.c中  需要在 最后加上 P0 = 0xFF
批注 2020-02-20 094254.jpg
回复

使用道具 举报

ID:586435 发表于 2020-2-20 09:48 | 显示全部楼层

程序昨天本来加的 P0 = 0xFF; 可能被我无意删除了
看的时候注意一下,两段数码管都要加的,不然led会有影响。

对LED影响的排除

对LED影响的排除

回复

使用道具 举报

ID:207882 发表于 2020-2-20 15:21 | 显示全部楼层
按键消抖用定时器去做,不要用死等,要养成好的编程习惯
回复

使用道具 举报

ID:586435 发表于 2020-2-20 20:30 | 显示全部楼层
2448289424 发表于 2020-2-20 15:21
按键消抖用定时器去做,不要用死等,要养成好的编程习惯

您说的对,工程量小的时候,我这样用习惯了(哈哈);
您的建议,今后我慢慢尝试使用,谢谢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表