找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 5835|回復(fù): 4
收起左側(cè)

藍(lán)橋杯單片機(jī)第七屆省賽 程序題解析(完美調(diào)試,清晰理解)

[復(fù)制鏈接]
ID:586435 發(fā)表于 2020-2-19 22:18 | 顯示全部樓層 |閱讀模式
大家好,首先呢介紹一下自己,鄙人現(xiàn)大二,接觸單片機(jī)才一年時(shí)間(大佬別笑話俺

寒假在準(zhǔn)備這個(gè)比賽,在最近幾天,寫(xiě)了一篇關(guān)于藍(lán)橋杯單片機(jī)組第七屆省賽的編程題,
想著發(fā)個(gè)帖子望大家指點(diǎn)一下,自己的也留個(gè)紀(jì)念。
也是第一次發(fā)帖子,哈哈 莫名有點(diǎn)激動(dòng)  哈哈
程序都是自己慢慢調(diào)試的,下了一番功夫,感覺(jué)受益匪淺,感觸頗多。





覺(jué)的受用的,大家互相學(xué)習(xí),覺(jué)的有不好的地方,還望能不吝賜教,嘻嘻嘻。
好了,言歸正傳,先看程序。
批注 2020-02-19 213335.jpg

         主程序  main.c


/**************************************************
代碼情況

【IRC頻率】11.0592Mhz
【杜邦線】 短接P34 和P07  通過(guò)        L8代替電機(jī) 觀察pwm脈沖信號(hào)

**************************************************/
#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();                        //按鍵檢測(cè)函數(shù)
void ConfigTime0();                    //配置定時(shí)函數(shù)--PWM脈沖                                                                                               
void SMGWorking();              //數(shù)碼管工作函數(shù)
void LedRunning();              //LED運(yùn)轉(zhuǎn)函數(shù)

uchar Wind = 1 ;               //風(fēng)速類(lèi)型狀態(tài):1-“睡眠風(fēng)”, 2-“自然風(fēng)”,3-“常風(fēng)”
uchar F_date = 0;             //時(shí)間數(shù)據(jù)
uchar T_date = 0;           //溫度數(shù)據(jù)
uchar cnt = 0;               //中斷次數(shù)變量
uint t = 0;                   //中斷定時(shí)1s變量
bit flag = 1;               //S7控制位



void main()
{
                CSH();         //關(guān)閉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;   //放在第一個(gè)判斷句
                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;
                                        }
                        }
}

/*********************************
【函數(shù)】   定時(shí)器初始化函數(shù)
【功能】   頻率為1Khz=1ms , 定時(shí)100us , AUXR--1T,不分頻
【返回值】 無(wú)
*********************************/
void ConfigTime0()   //100微秒@11.0592MHz
{
                AUXR |= 0x80;                  //定時(shí)器時(shí)鐘1T模式
                TMOD &= 0xF0;                 //設(shè)置定時(shí)器模式
                TL0 = 0xAE;                  //設(shè)置定時(shí)初值
                TH0 = 0xFB;                 //設(shè)置定時(shí)初值
                TF0 = 0;                  //清除TF0標(biāo)志
                TR0 = 1;                 //定時(shí)器0開(kāi)始計(jì)時(shí)
          ET0 = 1;    //定時(shí)器0中斷打開(kāi)
          EA = 1;    //打開(kāi)總中斷
}


/*********************************
【函數(shù)】   中斷函數(shù)
【功能】   進(jìn)入中斷10次為一個(gè)周期脈沖
【返回值】 無(wú)
*********************************/
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)  //定時(shí)1s
                         {
                                                t = 0;
                                                if(F_date > 0)        F_date --;
                         }
}




底層驅(qū)動(dòng)  ds18b20.c

/*

程序說(shuō)明: 單總線驅(qū)動(dòng)程序

軟件環(huán)境: Keil uVision 4.10

硬件環(huán)境: CT107單片機(jī)綜合實(shí)訓(xùn)平臺(tái)

日 期: 2011-8-9

*/
#include "ds18b20.h"


//單總線延時(shí)函數(shù)

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;

}

//通過(guò)單總線向DS18B20寫(xiě)一個(gè)字節(jié)

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讀取一個(gè)字節(jié)

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); //跳過(guò)ROM
        Write_DS18B20(0x44);//啟動(dòng)溫度轉(zhuǎn)換
        Delay_OneWire(200); //溫度轉(zhuǎn)換需要一定的時(shí)間
       
        Init_DS18B20();
        Write_DS18B20(0xCC);
        Write_DS18B20(0xBE);  //發(fā)送讀命令
       
        LS = Read_DS18B20();
        HS = Read_DS18B20();
       
        value = HS;       //0x00hs
        value <<= 8;     //0xhs00
        value |= LS;    //0x hs ls
  value >>= 4;   //0x 0h sl         //取整
       
        return value;
}


篇幅有限程序不全,有需求的朋友,請(qǐng)下載后觀看
第七屆.zip (75.05 KB, 下載次數(shù): 69)

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:586435 發(fā)表于 2020-2-19 22:34 | 顯示全部樓層
本帖最后由 黑夜的星光 于 2020-2-20 09:55 編輯

關(guān)于里面的一些細(xì)節(jié)代碼 由于時(shí)間問(wèn)題 沒(méi)有過(guò)多注釋?zhuān)绻信笥言谠u(píng)論區(qū)問(wèn)及的話 我在指出吧  望理解

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

使用道具 舉報(bào)

ID:586435 發(fā)表于 2020-2-20 09:48 | 顯示全部樓層

程序昨天本來(lái)加的 P0 = 0xFF; 可能被我無(wú)意刪除了
看的時(shí)候注意一下,兩段數(shù)碼管都要加的,不然led會(huì)有影響。

對(duì)LED影響的排除

對(duì)LED影響的排除

回復(fù)

使用道具 舉報(bào)

ID:207882 發(fā)表于 2020-2-20 15:21 | 顯示全部樓層
按鍵消抖用定時(shí)器去做,不要用死等,要養(yǎng)成好的編程習(xí)慣
回復(fù)

使用道具 舉報(bào)

ID:586435 發(fā)表于 2020-2-20 20:30 | 顯示全部樓層
2448289424 發(fā)表于 2020-2-20 15:21
按鍵消抖用定時(shí)器去做,不要用死等,要養(yǎng)成好的編程習(xí)慣

您說(shuō)的對(duì),工程量小的時(shí)候,我這樣用習(xí)慣了(哈哈);
您的建議,今后我慢慢嘗試使用,謝謝
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表