欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

CT107D藍橋杯單片機編程筆記

  [復(fù)制鏈接]
ID:86860 發(fā)表于 2015-7-26 00:37 | 顯示全部樓層 |閱讀模式
一、              IO口編程

IO編程,該開發(fā)板使用了573鎖存器,通過P2口的5,6,7位連接3-8譯碼器,擴展出了8個口,其中4個口分別連接4個573鎖存器,這里以LED的鎖存器來舉例:
原理圖573:
分析代碼:
P2=((P2&0x1f)|0x80);
其中0x1f=0001 1111,P2與0x1f進行與運算,高三位清零,其余位保持原來狀態(tài),不改變,即把控制3-8譯碼器的高三位留出來:
接著再或上0x80;容易發(fā)現(xiàn)0x80=1000 0000;或運算,與1或結(jié)果為1,與0或結(jié)果不變,所以或上0x80只需看P2的高三位,則高三位為100,對應(yīng)3-8譯碼器的話,P2^7=1;P2^6=0;P2^5=0;
所以輸出Y4=0;Y4再經(jīng)過與非運算,看下圖示:
則輸出Y4C=1;即LED對應(yīng)的鎖存器的片選信號被選中,鎖存器打通,接下來就可以對P0口進行操作,操作完之后,
P2=P2&0x1f;P2高三位直接清零,此時Y4C=0,則把鎖存器鎖上了。
類似的方法,數(shù)碼管、蜂鳴器等都是如此操作,
選中鎖存器代碼:
P2=((P2&0x1f)|(這里填對應(yīng)鎖存器的位移號))。
二、              數(shù)碼管動態(tài)掃描和定時器
數(shù)碼管顯示分為段選和位選,
數(shù)碼管定義和顯示函數(shù):
code unsigned char tab[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned chardspbuf[]={10,10,10,10,10,10,10,10};
unsigned chardspcom=0;
void display()
{
//段選,消隱
P2=((P2&0x1f)|0xe0);
P0=0xff;
P2=P2&0x1f;
//位選
P2=((P2&0x1f)|0xc0);
P0=(1<<dspcom);
P2=P2&0x1f;
//段碼輸入
P2=((P2&0x1f)|0xe0);
P0=tab[dspbuf[dspcom]];
P2=P2&0x1f;
if(++dspcom==8)
       dspcom=0;
}注意:這里1左移dspcom位,剛開始dspcom=0,則1左移dspcom位依舊為1,接著dspcom每次自增1,1對應(yīng)二進制00000001,即把1每次向左移,每次都比上一次多移一位,直至8位移完,對應(yīng)8個數(shù)碼管。
定時器配置:
這里只需記住定時器的配置,知道怎么使用就可以了。首先有兩個定時器,T0和T1,(也有的單片機有T2),定時器有4種工作方式0,1,2,3;其中最常用的是方式1(16位),其次是方式2(8位自動重裝,串口通訊中斷會用到)。
定時器需要配置:TMOD |=0x01;配置成使用定時器0,工作方式為1;同理使用定時器1工作方式1:TMOD|=0x10;則同時使用兩個定時器且工作方式為1,那么可以:TMOD|=0x11;
定時器1配置成工作方式2:TMOD |=0x20;
接著配置(以定時器0舉例):
TH0=(65535-2000)/256;//配置初值
TL0=(65535-2000)%6;
ET0=1;
TR0=1;//定時0中斷
EA=1;//總中斷
定時器1也是同理的,只不過0要改成1.
接著定時中斷函數(shù)和優(yōu)先級:
定時器0
void isr_timer_0(void) interrupt1  //默認中斷優(yōu)先級1
{
    TH0= (65536-2000)/256;
    TL0= (65536-2000)%6;  //定時器重載
   display();
}
定時器1:
voidisr_timer_1(void)  interrupt 3 //默認中斷優(yōu)先級3
{
    TH0= (65536-2000)/256;
    TL0= (65536-2000)%6;  //定時器重載
   display();
}
注意:定時器0優(yōu)先級為1,定時器13,串口中斷優(yōu)先級為4,總共有5個中斷源,后面還會介紹外部中斷和串口中斷。

數(shù)碼管動態(tài)掃描,顯示函數(shù)放在定時中斷函數(shù)里面,2ms掃一次是最穩(wěn)定的!!

三、              矩陣鍵盤
矩陣鍵盤需要死記了!這里不再講獨立鍵盤。
第二種單片機鍵盤掃描代碼(沒有消抖):
sfrP4^4=0xC0;
//鍵盤定義
sbitr1=P3^0;  //4行
sbit r2=P3^1;
sbit r3=P3^2;
sbit r4=P3^3;
//4列
sbit c1=P4^4;
sbit c2=P4^2;
sbit c3=P3^5;
sbit c4=P3^4;
//讀取矩陣鍵盤鍵值
unsigned charkey_scan()
{
    unsigned char key_value;
    r1=0;
    r2=r3=r4=1;
    c1=c2=c3=c4=1;
    if(!c1) key_value=0;
    else if(!c2) key_value=1;
    else if(!c3) key_value=2;
    else if(!c4) key_value=3;
   r2=0;
    r1=r3=r4=1;
    c1=c2=c3=c4=1;
    if(!c1) key_value=4;
    else if(!c2) key_value=5;
    else if(!c3) key_value=6;
    else if(!c4) key_value=7;
    r3=0;
    r2=r1=r4=1;
    c1=c2=c3=c4=1;
    if(!c1) key_value=8;
    else if(!c2) key_value=9;
    else if(!c3) key_value=10;
    else if(!c4) key_value=11;
    r4=0;
    r2=r3=r1=1;
    c1=c2=c3=c4=1;
    if(!c1) key_value=12;
    else if(!c2) key_value=13;
    else if(!c3) key_value=14;
    else if(!c4) key_value=15;
    return key_value;
}
四、              串口通訊和串口中斷
串口中斷配置只需記住幾個寄存器就行了,
初始化:
  SCON =0x50; //串口配置成模式1
TMOD|=0x20;//定時器1,方式2,8位自動重裝
TH1=256-(unsigbedchar)(SYSTEMCLOK/BAUDRATE/384+0.5);//定時初值
        ES=1;        //串口中斷打開
        TR1=1;     //啟動定時器1
        EA=1;           //總中斷打開
這里必須使用定時器1,不能用定時器0.
下面是模塊化的函數(shù):
void Uart_Init()
{
SCON = 0x50;
TMOD |=0x20;
TH1=256-(SYSREMCLOCK/BAUDRATE/384+0.5);
ES=1;
TR1=1;
EA=1;
}
void UartSend(unsignedchar*pBuff,int length)
{
unsigned charc;
int i=0;
for(i=0;i
{
c=pBuff;
SBUF=c;
while(TI==0);
TI=0;
}
}
接收數(shù)據(jù)可以這樣寫:
定義全局變量:
unsigned charuart_buf[100];//串口緩沖區(qū)
unsignedint  uart_Count=0;//串口數(shù)據(jù)長度
void uart_inte()interrupt 4
{
     unsigned char c;
     if(RI)
     {
            RI=0;
            c=SBUF;
            uart_buf[uart_Count]=c;
            uart_Count++;
     }                          
}
如果可以指定的接收,可以這樣寫
//串口中斷服務(wù)函數(shù)
void isr_uart(void)interrupt 4{
   if(RI){
       RI = 0;  //清除接收標(biāo)志位
       rxbuf[rxcnt] = SBUF;
       if(rxbuf[rxcnt] == '\n'){
           rxcnt = 0;
           rx_over = 1;
           ES = 0;
//回車為接收結(jié)束標(biāo)志,檢測到回車符后,關(guān)閉串口中斷
       }     
            else{
                   rxcnt++;
            }
   }
}
當(dāng)接收完一幀數(shù)據(jù)時關(guān)閉串口中斷,設(shè)一個標(biāo)志位,處理完之后再打開。
#include"reg51.h"
#include"intrins.h"
typedef unsigned charBYTE;
typedef unsigned intWORD;
BYTEcode_tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};
char arry[10]="I CANPLAY";
unsigned charx;
#define FOSC11059200//12000000L         //系統(tǒng)頻率
#define BAUD115200            //串口波特率
#defineNONE_PARITY    0      //無校驗
#defineODD_PARITY     1      //奇校驗
#defineEVEN_PARITY    2      //偶校驗
#defineMARK_PARITY    3      //標(biāo)記校驗
#defineSPACE_PARITY   4      //空白校驗
#define PARITYBITNONE_PARITY  //定義校驗位
sfrAUXR  =0x8e;              //輔助寄存器
sfrP_SW1   =0xA2;            //外設(shè)功能切換寄存器1
#define S1_S00x40             //P_SW1.6
#define S1_S10x80             //P_SW1.7
sbit P22 =P2^2;
bit busy;
void SendData(BYTEdat);
void SendString(char*s);
void main()
{
    ACC= P_SW1;
    ACC&= ~(S1_S0 |S1_S1);   //S1_S0=0 S1_S1=0
   P_SW1 =ACC;               //(P3.0/RxD, P3.1/TxD)
   
//  ACC= P_SW1;
//  ACC&= ~(S1_S0 |S1_S1);   //S1_S0=1 S1_S1=0
//  ACC|=S1_S0;              //(P3.6/RxD_2, P3.7/TxD_2)
// P_SW1 = ACC;
//
//  ACC= P_SW1;
//  ACC&= ~(S1_S0 |S1_S1);   //S1_S0=0 S1_S1=1
//  ACC|=S1_S1;              //(P1.6/RxD_3, P1.7/TxD_3)
// P_SW1 = ACC;
//#if (PARITYBIT ==NONE_PARITY)
    SCON=0x50;               //8位可變波特率
//#elif (PARITYBIT ==ODD_PARITY) || (PARITYBIT == EVEN_PARITY) || (PARITYBIT ==MARK_PARITY)
//  SCON =0xda;               //9位可變波特率,校驗位初始為1
//#elif (PARITYBIT ==SPACE_PARITY)
//  SCON =0xd2;               //9位可變波特率,校驗位初始為0
//#endif
    AUXR=0x40;               //定時器1為1T模式
    TMOD=0x20;               //定時器1為模式2(8位自動重載)
    TL1= (256 - (FOSC/32/BAUD));  //設(shè)置波特率重裝值
    TH1= (256 - (FOSC/32/BAUD));
    TR1=1;                   //定時器1開始工作
    ES =1;                    //使能串口中斷
    EA =1;
   while(1)
     {
//  SendString(arry);
     SendString("I CAN PLAY~~\r\n");//上位機顯示接收文本模式
//  SendData(x);
     }
}
void Uart() interrupt 4using 1
{
    if(RI)//單片機接收數(shù)據(jù),發(fā)送數(shù)字0~9,可在數(shù)碼管上顯示,發(fā)送hex模式
   {
       RI =0;                //清除RI位
//       P0= SBUF;
            x=SBUF;//將緩存器的數(shù)據(jù)賦值給x
            P0=0xff;               //消隱
            P2|=0xe0;
            P2&=0x1f;
            
            P0=code_tab[x];               //段選
            P2|=0xe0;
            P2&=0x1f;
            
            P0=0x01;                          //位選第一位
            P2|=0xc0;
            P2&=0x3f;
   
   }
    if(TI)
   {
       TI =0;                //清除TI位
       busy =0;              //清忙標(biāo)志
   }
}
void SendData(BYTEdat)
{
   while(busy);              //等待前面的數(shù)據(jù)發(fā)送完成
    ACC=dat;                 //獲取校驗位P (PSW.0)
    if(P)                     //根據(jù)P來設(shè)置校驗位
   {
#if (PARITYBIT ==ODD_PARITY)
       TB8 =0;               //設(shè)置校驗位為0
#elif (PARITYBIT ==EVEN_PARITY)
       TB8 =1;               //設(shè)置校驗位為1
#endif
   }
   else
   {
#if (PARITYBIT ==ODD_PARITY)
       TB8 =1;               //設(shè)置校驗位為1
#elif (PARITYBIT ==EVEN_PARITY)
       TB8 =0;               //設(shè)置校驗位為0
#endif
   }
    busy= 1;
    SBUF=ACC;                //寫數(shù)據(jù)到UART數(shù)據(jù)寄存器
}
void SendString(char*s)
{
   while(*s)                 //檢測字符串結(jié)束標(biāo)志
   {
       SendData(*s++);        //發(fā)送當(dāng)前字符
   }
}
記不住可以看手冊!!
#include"reg51.h"
#include"intrins.h"
typedef unsigned charBYTE;
typedef unsignedint  WORD;
#define FOSC11059200L
#define BAUD115200
sfrAUXR=0x8e;   //輔助寄存器
sbit P22=P2^2;
bit busy;
void SendData(BYTEdat);
void SendString(char*s);
void main()
{
     SCON=0x50;
     AUXR=0x40; //設(shè)置定時器T1為1T,即一個機器周期模式
     TMOD=0x20;
     TL1=(256-(FOSC/32/BAUD));
     TH1=(256-(FOSC/32/BAUD));
     TR1=1;
     ES=1;
     EA=1;
     SendString("Hello");
     while(1);
}
void Uart() interrupt 4using 1
{
     if(RI)
     {
            RI=0;
            P0=SBUF;
     }
     if(TI)
     {
            TI=0;
            busy=0;
     }
}
void SendData(BYTEdat)
{
     while(busy);
     busy=1;
     SBUF=dat;
}
void SendString(char*s)
{
     while(*s)
     {
            SendData(*s++);
     }
}
五、              外部中斷的使用
#include
sbit L1=P0^0;
int main(){
IT0=1;//IT0=1,下降沿觸發(fā)外部中斷0,IT0=0邊沿觸發(fā)
EX0=1;//使用外部中斷0
EA=1;
while(1){
       }
}
void Ex_int0() interrupt 0 //外部中斷優(yōu)先級最高
{
P2=((P2&0x1f)|0x80);
L1=~L1;
P2=(P2&0x1f);
}     


其中,外部中斷的引腳控制是P3^2P3^3,即對應(yīng)獨立按鍵的S5S4

六、              實時時鐘DS1302的使用
藍橋杯提供函數(shù),解釋為:
里面的命令和寫入的數(shù)據(jù)可以看芯片手冊:
左側(cè)的READ、WRITE分別是讀寫的命令,BIT7-BIT0是要寫入的數(shù)據(jù),根據(jù)需要進行配置。DS1302只需記住這兩個函數(shù)即可:Write_Ds1302( , )與Read_Ds1302(x),配置看手冊。
重點:芯片表說明:第一行:秒->因為秒的范圍是0-59,所以6,5,4位表示秒的十位,3,2,1,0表示個位,十位最大是5,所以三位即可。
第二行:跟上面一樣;
第三行:7位:1為12小時制,0為24小時制;5位:12小時制時為0表示上午,1表示下午,24小時制時,和4位一起表示小時的十位;
其余的時間一樣的表示。
倒數(shù)第二行:只看7位:為1時禁止寫數(shù)據(jù),所以開始寫數(shù)據(jù)時必須置0;
讀數(shù)時:
!!需要加“寫操作這一行代碼”。
讀的話直接按照命令讀即可。
DS1302進階(BCD碼轉(zhuǎn)換):解決之前60秒不能進位的問題。
1)寫入初始值時,要把10十進制數(shù)轉(zhuǎn)換為BCD碼,
例:寫入時間->17:58:50
Ds1302_Single_Byte_Write(0x8e,0x00);//寫操作
Ds1302_Single_Byte_Write(0x85, ((17/10)<<4 |(17)));//寫時
   Ds1302_Single_Byte_Write(0x83, ((58/10)<<4 |(58)));//寫分
Ds1302_Single_Byte_Write(0x81, ((50/10)<<4 |(50)));//寫秒
Ds1302_Single_Byte_Write(0x8e,0x80);//寫保護
即轉(zhuǎn)換的公式是:((Value/10)<<4 | (Value)),可以寫一個settime()函數(shù)。
2 )讀數(shù):讀回來的數(shù)要進行轉(zhuǎn)換成十進制數(shù)
((ReadValue&0x70)>>4)*10 +(ReadValue&0x0F);
八進制轉(zhuǎn)十進制->
ReadValue=Ds1302_Single_Byte_Read(0x85);
         hour=((ReadValue&0x70)>>4)*10 +(ReadValue&0x0F);
   !!(這句一定不要省)     Ds1302_Single_Byte_Write(0x00, 0x00);//寫操作
         ReadValue=Ds1302_Single_Byte_Read(0x83);
         minute=((ReadValue&0x70)>>4)*10 +(ReadValue&0x0F);
         Ds1302_Single_Byte_Write(0x00, 0x00);//寫操作
         ReadValue=Ds1302_Single_Byte_Read(0x81);
         sec=((ReadValue&0x70)>>4)*10 +(ReadValue&0x0F);
         Ds1302_Single_Byte_Write(0x00, 0x00);//寫操作
顯示:
        dspbuf[0]=hour/10;
         dspbuf[1]=hour;
         dspbuf[2]=minute/10;
     dspbuf[3]=minute;
         dspbuf[4]=sec/10;
         dspbuf[5]=sec;
七、              PCF8591與IIC總線的使用
(1)   IIC總線的使用:
比賽提供了IIC的兩個庫文件,IIC.h;IIC.c,其中需要注意的函數(shù)是:
其中,該函數(shù)是初始化的,當(dāng)使用AD轉(zhuǎn)換的時候需要在main函數(shù)開始時調(diào)用,該函數(shù)內(nèi)部只需看這句代碼即可:i2c_sendbyte(0x03);//ADC通道3,板上有4個模擬輸入口,分別為0,1,2,3;設(shè)置哪一個模擬輸入口就是根據(jù)這句代碼,0x03表示通道3,這是根據(jù)芯片手冊配置的,如圖:
8位前6位不用管,都為0,最后兩位就是配置選擇哪一個通道的。
第二個函數(shù):
讀取AD轉(zhuǎn)換后的數(shù)值,這個函數(shù)直接調(diào)用就可以了,函數(shù)內(nèi)部如何實現(xiàn)不用管,但是需要注意的是:該函數(shù)掃描調(diào)用最好是100ms。
第三個函數(shù),上面的都是AD轉(zhuǎn)換,即模擬信號轉(zhuǎn)數(shù)字信號,下面這個函數(shù)是DA轉(zhuǎn)換,數(shù)字信號轉(zhuǎn)換成模擬信號,就是單片機輸出數(shù)字信號,用萬能表去量單片機引出的引腳,量一下電壓大小,這個估計比賽不會考,不過預(yù)防萬一:
該函數(shù)和上面兩個函數(shù)分離開來的,一、二函數(shù)是要在一起使用,初始化后之后才能調(diào)用,第三個加入頭文件,直接調(diào)用即可,比較簡單!!
上面說法有誤,A/D轉(zhuǎn)換的初始化函數(shù)和讀取轉(zhuǎn)換后的數(shù)值都需要自己寫。
這里了解一下PCF8591只需根據(jù)時序格式發(fā)送地址字節(jié)和控制字節(jié):,這是地址字節(jié),其中A2,A1,A0硬件已經(jīng)接地,故都為0,最低位表示的是你要從IIC總線上讀數(shù)還是寫數(shù)據(jù),1表示讀,0表示寫,即讀數(shù)據(jù)發(fā)的地址是:0x91;寫數(shù)據(jù)發(fā)的地址是0x90;
控制字節(jié):
由芯片資料知,控制字節(jié)有8位,有兩位固定是0,除了第0、1位需要自己設(shè)置,其他的我們都設(shè)為0,那些位都是一些具體的功能,我們暫時用不著,不用管先,第0、1位是模擬通道選擇,PCF8591上提供了4路模擬通道,根據(jù)需求進行選擇,如選擇通道3即發(fā)送控制字節(jié):0x03;
地址字節(jié)和控制字節(jié)都明白了,接下來根據(jù)時序要求進行配置,A/D轉(zhuǎn)換需要一個初始化函數(shù):Init_ADpcf8591();和一個獲得AD轉(zhuǎn)換后的數(shù)值的函數(shù):adc_pcf8591(); 其中初始化函數(shù)的作用是發(fā)送AD轉(zhuǎn)換的控制字節(jié);adc_pcf8591()發(fā)送讀取得地址并讀回數(shù)據(jù),先寫指令才能讀;格式如下:
這個是初始化的協(xié)議:分別是startIIC、(地址寫)發(fā)送0x90、等待應(yīng)答、發(fā)送控制字節(jié)(AD這里是選擇通道的指令,如選擇通道3,0x03)0x03、等待應(yīng)答、(達到目的,沒有后續(xù)的操作,直接停止總線)StopIIC.
初始化的函數(shù)就是如此寫;
adc_pcf8591的協(xié)議:
依次是:startIIc、發(fā)送讀地址0x91、等待應(yīng)答、讀回AD轉(zhuǎn)換后的數(shù)值、讀回后發(fā)送應(yīng)答給PCF8591,表示收到,并且不需要再返回應(yīng)答,要傳參數(shù)1,如圖紅圈示,即函數(shù)Ack(1);、最后stopIIC總線。
D/A轉(zhuǎn)換(其實挺麻煩,先前太自信了,哈):
所謂D/A轉(zhuǎn)換其實就是把數(shù)字信號轉(zhuǎn)換成模擬信號輸出,用單片機發(fā)數(shù)字通過D/A轉(zhuǎn)換成電壓輸出,檢測的方法可以用電壓表測量。
配置的方法跟A/D類似,先發(fā)地址字節(jié),再發(fā)控制字節(jié),然后把數(shù)字發(fā)出去(AD這里是接收模擬信號,是相反的機制)。
控制字節(jié):
如圖示,控制字節(jié)的第6位是1的話是模擬輸出模式,其余位全為0,發(fā)送格式跟AD一樣:
代碼如一開始圖示。

(2)   EEPROM的使用,AT24C02,可以掉電依舊保存上一次操作的數(shù)據(jù),下次上電后接著運行。
需要注意兩個函數(shù),一個是寫進EEPROM里面保存,再次上電再從里面讀回來:
其中寫函數(shù)需要指定AT24C02的地址以及需要寫入的數(shù)據(jù),讀函數(shù)要想取回寫進的數(shù)據(jù),需要從相同的地址里面讀:
其中AT24C02的存儲地址是0x00,可以是其他地址,如0x02,但是讀和寫的地址必須一致。
寫與讀的協(xié)議與AD或DA相同,
由芯片資料及原理圖知EEPROM(AT24C02)的寫地址為0xa0;讀地址為0xa1;注意:讀數(shù)的時候讀出一個數(shù)之后發(fā)送一個應(yīng)答信號,若ACK(0)表示還想繼續(xù)讀下一個字節(jié),若ACK(1);則不想再讀數(shù),讓EEPROM停止發(fā)送。
八、              DS18B20時鐘芯片的使用
比賽有提供代碼,只需記住這個函數(shù):
讀取溫度值,整數(shù)(其中,提示EA總中斷要打開、關(guān)閉,也可以不用)。
浮點數(shù)的表示。
注意,只有提供函數(shù),沒有提供讀取溫度的函數(shù),即上面的那個,只有下面:這幾個函數(shù)。
編寫讀取溫度的函數(shù)需要記住DS13B20的三條指令,0xCC,跳過ROM檢測;然后啟動溫度轉(zhuǎn)換:0x44;轉(zhuǎn)換需要時間,這里精確延時Delay_OneWire(200);然后再次初始化,再次執(zhí)行跳過,然后讀取溫度指令:0xBE.;注意讀出的溫度是低字節(jié)先,然后才是高字節(jié),分別用兩個變量保存還要通過公式轉(zhuǎn)換成我們需要的整數(shù)或浮點數(shù)。完整代碼如上圖示。
九、              超聲波傳感器的使用
#include"reg52.h"  //定義51單片機特殊功能寄存器
#include "intrins.h"
#include "absacc.h"
//12M用這個
//11.0592用這個
#define somenop{_nop_();_nop_();_nop_();_nop_();_nop_();
                _nop_();_nop_();}
sbit TX =P1^0;  //發(fā)射引腳
sbit RX =P1^1;  //接收引腳
code unsigned char tab[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,\
                            0xff};
unsigned char dspbuf[8] ={10,10,10,10,10,10,10,10};  //顯示緩沖區(qū)
unsigned char dspcom =0;
unsigned int intr =0;
bit s_flag;
unsigned int t = 0;
voidsend_wave(void);
void display(void);
void main(void)
{
   unsigned int distance;
    TMOD|= 0x11;  //配置定時器工作模式
    TH0= (65536-2000)/256;
    TL0= (65536-2000)%6;
    TH1= 0;
    TL1= 0;
    EA =1;
    ET0= 1;  //打開定時器0中斷
    TR0= 1;  //啟動定時器  
   while(1){
      
       if(s_flag)
       {
           s_flag = 0;
           
                     t = TH1;
                     t <<= 8;
                     t |= TL1;
                     distance = (unsigned int)(t*0.017); //計算距離                          
              }
              TH1 = 0;
              TL1 = 0;
       }
      
                    
       dspbuf[5] = distance/100;
       dspbuf[6] = distance0/10;
       dspbuf[7] =distance;      
   }
}
//定時器0中斷服務(wù)函數(shù)
voidisr_timer_0(void)  interrupt 1 //默認中斷優(yōu)先級 1
{
    TH0= (65536-2000)/256;
    TL0= (65536-2000)%6;  //定時器重載
   
display(); //2ms執(zhí)行一次
if(++intr == 200){
       s_flag = 1;
       intr = 0;
   }
}
//顯示函數(shù)
void display(void){
      XBYTE[0xE000] = 0xff;  //去除鬼影
      XBYTE[0xC000] = (1<<dspcom);
      XBYTE[0xE000] = tab[dspbuf[dspcom]];
if(++dspcom == 8){
             dspcom = 0;
}     
}
//TX引腳發(fā)送40KHz方波信號驅(qū)動超聲波發(fā)送探頭
void send_wave(void)
{
unsigned char i =8;  //發(fā)送8個脈沖
do
{
       TX = 1;
       somenop;
       TX = 0;
       somenop;
}
while(i--);
}
必要時還可以加個看門狗:   WDT_CONTR=0x34;
十、              步進電機與直流電機的使用
參考代碼如下:
#include
sbit A1=P1^4;//定義步進電機連接端口
sbit B1=P1^3;
sbit C1=P1^2;
sbit D1=P1^1;
void qudong1();
#define Dy_A1{A1=1;B1=0;C1=0;D1=0;}//A相通電,其他相斷電
#define Dy_B1{A1=0;B1=1;C1=0;D1=0;}//B相通電,其他相斷電
#define Dy_C1{A1=0;B1=0;C1=1;D1=0;}//C相通電,其他相斷電
#define Dy_D1{A1=0;B1=0;C1=0;D1=1;}//D相通電,其他相斷電    //采用1相勵磁
#define Dy_OFF{A1=0;B1=0;C1=0;D1=0;}//全部斷電
unsigned charSpeed,Speed1;
void DelayUs2x(unsigned chart)
{  
while(--t);
}
void DelayMs(unsigned chart)
{
   
while(t--)
{
    //大致延時1mS
    DelayUs2x(245);
   DelayUs2x(245);
}
}
main()
{
Dy_OFF;
for(;;)
{
   qudong1();
  }
}
void qudong1()
{
unsigned inti=470;//旋轉(zhuǎn)一周時間
Speed=5;
while(i--)  //正向
{        
    Dy_A1               
//遇到Coil_A1  用{A1=1;B1=0;C1=0;D1=0;}代替
    DelayMs(Speed);        
//改變這個參數(shù)可以調(diào)整電機轉(zhuǎn)速,
                            //數(shù)字越小,轉(zhuǎn)速越大,力矩越小
    Dy_B1                              //順序從A1--D1相通電如果為正轉(zhuǎn),那么順序從D1--A1相通電則為反轉(zhuǎn)
    DelayMs(Speed);
    Dy_C1
    DelayMs(Speed);
    Dy_D1
    DelayMs(Speed);
  }
Dy_OFF
i=512;
while(i--)//反向
  {
    Dy_D1               //遇到Coil_A1  用{A1=1;B1=0;C1=0;D1=0;}代替
    DelayMs(Speed);        //改變這個參數(shù)可以調(diào)整電機轉(zhuǎn)速,
                          //數(shù)字越小,轉(zhuǎn)速越大,力矩越小
    Dy_C1
    DelayMs(Speed);
    Dy_B1
    DelayMs(Speed);
    Dy_A1
    DelayMs(Speed);
}      
}
直流電機:
#include
#define uint unsigned int
voiddrive();
voiddelay(uint);
sbitdj1=P1^0; //電機,1引腳
uintset; //set為電機轉(zhuǎn)角標(biāo)志位
unsigned charangle,angle1;  //angle為電機PWM變化打角
voidTime0_Init()      //中斷初始化
{
TMOD=0X01;
IE=0X82;
TH0=(65536-58)/256;           
TL0=(65536-58)%6;
TR0=1;
}
voidmain()        //主函數(shù)
{
set=0;
angle=62;  // 改變angle的值可以改變電機的占空比
Time0_Init();
  for(;;)
   {
   }   
}
voidT0_time()interrupt 1
{
TH0=(65536-58)/256;           
TL0=(65536-58)%6;
  if(set
   dj1=1;
else
  dj1=0;
set++;
if(set>165)set=0;   //電機占空比
}
十一、    擴展:宏定義編程方法(推薦)
常用的可以宏定義,省時,下面以數(shù)碼管為例:
#define rst573P2&=0x1f
#define Y6CP2=  ((P2&0x1f)|0xc0)
#define Y7CP2=  ((P2&0x1f)|0xe0)
code unsigned char tab[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char dspbuf[8] ={10,10,10,10,10,10,10,10};  //顯示緩沖區(qū)
unsigned chardspcom;
unsigned char flag;
void display()
{
Y7C;
P0=0xff;
rst573;
Y6C;
P0=1<<dspcom;
rst573;
Y7C;
P0=tab[dspbuf[dspcom]];
rst573;
if(++dspcom==8)
       dspcom=0;
}

評分

參與人數(shù) 3黑幣 +20 收起 理由
SE555D + 5 很給力!
蘆葦劫 + 10 絕世好帖!
sky日耀 + 5 共享資料的黑幣獎勵!

查看全部評分

回復(fù)

使用道具 舉報

ID:86461 發(fā)表于 2015-12-5 10:56 | 顯示全部樓層
好東西,感謝樓主分享
回復(fù)

使用道具 舉報

ID:91159 發(fā)表于 2016-2-5 09:52 | 顯示全部樓層
謝謝你,我想問一下,我可不可以理解為,藍橋杯單片機組對程序的要求是,除了時序程序,都要求自己寫
回復(fù)

使用道具 舉報

ID:105191 發(fā)表于 2016-2-8 19:43 | 顯示全部樓層
感謝樓主分享的好東西!
回復(fù)

使用道具 舉報

ID:107035 發(fā)表于 2016-3-2 19:57 | 顯示全部樓層
蟹蟹樓主O(∩_∩)O
回復(fù)

使用道具 舉報

ID:109424 發(fā)表于 2016-3-17 22:25 來自觸屏版 | 顯示全部樓層
謝樓主分享
回復(fù)

使用道具 舉報

ID:119181 發(fā)表于 2016-5-7 23:42 來自觸屏版 | 顯示全部樓層
樓主,在嗎,我有點問題想請教你,527334445我qq,我比較急
回復(fù)

使用道具 舉報

ID:119181 發(fā)表于 2016-5-7 23:43 來自觸屏版 | 顯示全部樓層
看到回復(fù)一下吧
回復(fù)

使用道具 舉報

ID:153765 發(fā)表于 2016-12-16 17:24 | 顯示全部樓層
15454555
回復(fù)

使用道具 舉報

ID:156157 發(fā)表于 2016-12-20 10:21 | 顯示全部樓層
感謝樓主
回復(fù)

使用道具 舉報

ID:161530 發(fā)表于 2017-1-14 13:10 | 顯示全部樓層
樓主,想問個問題,keil uVision4  怎么建CT107D的工程?找不到 芯片類型
回復(fù)

使用道具 舉報

ID:253249 發(fā)表于 2018-1-9 12:05 來自觸屏版 | 顯示全部樓層
可以認識樓主一下嗎?
回復(fù)

使用道具 舉報

ID:279179 發(fā)表于 2018-1-24 17:26 | 顯示全部樓層
請問為什么看不見圖呢?
回復(fù)

使用道具 舉報

ID:279179 發(fā)表于 2018-1-24 17:31 | 顯示全部樓層
樓主你好,上線后可以回復(fù)一下嗎?謝謝你,有些問題不太清楚想向你學(xué)習(xí)一下
回復(fù)

使用道具 舉報

ID:272080 發(fā)表于 2018-1-25 10:07 | 顯示全部樓層
這個可能只有參加比賽的才能看得懂啊哈哈
回復(fù)

使用道具 舉報

ID:281313 發(fā)表于 2018-2-1 00:08 | 顯示全部樓層
樓主前面說錯了,應(yīng)該是或非門
回復(fù)

使用道具 舉報

ID:361383 發(fā)表于 2019-3-1 16:36 | 顯示全部樓層
好東西!
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

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

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

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