2020-10-31 51微控制器學習

weixin_46246297發表於2020-11-01

51微控制器學習日誌——2020.10.26~11.1

(其實就是學習筆記)

(1)中斷系統

在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
中斷源
在這裡插入圖片描述
在這裡插入圖片描述
使用中斷:
(1)需要使用哪個中斷,選擇相應的符號
(2)觸發條件
(3)中斷函式中,想要實現什麼

需要以下程式碼(以外部中斷0為例):
EA1=1;//開啟總中斷開關
EXO=1;、、開啟外部中斷0
ITO=0/1;設定外部中斷的觸發方式
void int0 () interrupt 0
{
do anything that you want
}
在這裡插入圖片描述
在這裡插入圖片描述
(原理圖)

外部中斷0:p32口;外部中斷1:p33口

{
//設定 INT0
IT0=1;//跳變沿出發方式(下降沿)
EX0=1;//開啟 INT0 的中斷允許。
EA=1;//開啟總中斷
}
void main()
{
Int0Init(); // 設定外部中斷 0
while(1);
}
void Int0() interrupt 0 //外部中斷 0 的中斷函式
{
delay(1000); //延時消抖
if(k3==0)
{
led=~led;
}

(2)定時器和計數器

在這裡插入圖片描述
定時器/計數器與微控制器CPU相互獨立,工作不需要CPU參與。
51微控制器的定時器/計數器(T0/T1)是根據機器內部時鐘或者是外部的脈衝訊號對暫存器中的資料加1.
在這裡插入圖片描述
TMOD是工作方式暫存器,用於設定定時、計數器的工作方式,低四位用於T0,高四位用於T1
在這裡插入圖片描述

GATE是門控位,GATE=0時,用於控制定時器啟動是否受外部中斷影響,TCON中TR1或TR0=1即可;GATE=1時,要TR0或TR1=1,且外部中斷引腳INT0/1也為高電平才能啟動定時器。
C/T為定時/計數模式選擇位。c/t=0時 定時模式;c/t=1時 計數模式。
M1M2:工作方式設定位,共4種。
(計數模式時,計數脈衝是T0引腳上的外部脈衝)
方式1:計數位是16位,由TL0作為低8位,TH0作為高8位,組成了16位加1計數器
方式2:自動重灌初值的8位計數方式
方式3:只適用於定時、計數器T0,此時T1相當於TR1=0,計數停止。

步驟在這裡插入圖片描述

在這裡插入圖片描述
(1秒鐘對應1000個毫秒,就是計1000個數,初值為FC18)
在這裡插入圖片描述

void Timer0Init()
{
	TMOD|=0X01;//選擇為定時器0模式,工作方式1,僅用TR0開啟啟動。

	TH0=0XFC;	//給定時器賦初值,定時1ms
	TL0=0X18;	
	ET0=1;//開啟定時器0中斷允許
	EA=1;//開啟總中斷
	TR0=1;//開啟定時器			
}
void Timer0() interrupt 1
{
	static u16 i;
	TH0=0XFC;	//給定時器賦初值,定時1ms
	TL0=0X18;
	i++;
	if(i==1000)
	{
		i=0;
		led=~led;	
	}	
}

(3)串列埠通訊

在這裡插入圖片描述
(傳輸距離與波特率成反比)
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述

SCON,PCON,TMOD三個暫存器

(1)串列埠工作方式暫存器SCON
在這裡插入圖片描述

RI:接收中斷標誌位,資料接收結束時,標誌位會自動置1,需要通過程式將其置0

TI:傳送中斷標誌位,資料傳送結束時,標誌位會自動置1,需要通過程式將其置0

RB8:存放傳送資料的第9位

TB8:存放接收資料的第9位

REN:序列接收允許位,0允許序列接收,1禁止序列接收

SM2:多機控制位

SM1,SM0:序列工作方式(共有4種工作方式)

在這裡插入圖片描述
(2)定時器工作方式暫存器TMOD
在這裡插入圖片描述
高四位為定時計數器1的設定,低四位是定時計數器0設定,串列埠通訊波特率設定佔用定時計數器1,這裡主要說串列埠通訊,不過多說定時計數器,只需要設定定時計數器1的工作方式即可

振盪週期:也稱時鐘週期(頻率的倒數),微控制器提供時鐘訊號的振盪源週期,頻率一般有11.0592MHz,12MHz等

狀態週期:是時鐘週期的2倍,

機器週期:是包含6個狀態週期,機器週期=1/微控制器時脈頻率

微控制器時脈頻率:是外部時鐘的12分頻,如果是12MHz的晶振,機器週期=1/微控制器時脈頻率=1/(12MHz/12)=12/12M=1us

這裡一個機器週期為1us,若定時時間為1ms,則需要1000個機器週期,計算出初值;如果機器週期為2us,則只需要500個機器週期。

定時器初值計算:初值=(65536-機器週期數量)(65536-1000+1=64536 為FC18)
(3)波特率計算:
在這裡插入圖片描述

當串列埠工作在工作方式0和2是,波特率固定,方式0時fosc/12;方式2時fosc/32或fosc/64(根據SMOD判斷)。

當串列埠工作在方式1時,波特率=(2^SMOD/32)*(微控制器時脈頻率/(256-X)),X是初值

C/T:定時器和計數器選擇位,0為定時器,1為計數器
在這裡插入圖片描述
在這裡插入圖片描述

(4)AD數模轉換

在這裡插入圖片描述

在這裡插入圖片描述
電位器:
在這裡插入圖片描述

/****************************************************************************
*函式名:Read_AD_Data
*輸  入:cmd:讀取的X或者Y
*輸  出:endValue:最終訊號處理後返回的值
*功  能:讀取觸控資料
****************************************************************************/
uint Read_AD_Data(uchar cmd)
{
	uchar i;
	uint AD_Value;
	CLK = 0;
	CS  = 0;
	SPI_Write(cmd);
	for(i=6; i>0; i--); 	//延時等待轉換結果
	CLK = 1;	  //傳送一個時鐘週期,清除BUSY
	_nop_();
	_nop_();
	CLK = 0;
	_nop_();
	_nop_();
	AD_Value=SPI_Read();
	CS = 1;
	return AD_Value;	
}

void SPI_Write(uchar dat)//寫入資料
{
	uchar i;
	CLK = 0;
	for(i=0; i<8; i++)
	{
		DIN = dat >> 7;  	//放置最高位
		dat <<= 1;
		CLK = 0;			//上升沿放置資料

		CLK = 1;

	}
}
uint SPI_Read(void)//讀取資料
{
	uint i, dat=0;
	CLK = 0;
	for(i=0; i<12; i++)		//接收12位資料
	{
		dat <<= 1;

		CLK = 1;
		CLK = 0;

		dat |= DOUT;

	}
	return dat;	
}

(5)DA轉換

在這裡插入圖片描述

在這裡插入圖片描述
(pwm調整佔空比實現LED呼吸燈)
步驟:
初始化定時器1

void Timer1Init()
{
	TMOD|=0X10;//選擇為定時器1模式,工作方式1,僅用TR1開啟啟動。

	TH1 = 0xFF; 
	TL1 = 0xff;   //1us
		
	ET1=1;//開啟定時器1中斷允許
	EA=1;//開啟總中斷
	TR1=1;//開啟定時器			
}

調整佔空比

	Timer1Init();  //定時器1初始化
	while(1)
	{
		if(count>100)			//定義count,調整佔空比				
		{  
			count=0;
			if(DIR==1)					   //DIR控制增加或減小(方向)
			{
			  value++;
			}			
			if(DIR==0)
			{
			  value--;
			}
				
		}

		if(value==1000)
		{
		  DIR=0;
		}
		if(value==0)
		{
		  DIR=1;
		}	
				
		if(timer1>1000)  //PWM週期為1000*1us
		{
			timer1=0;
		}
		if(timer1 <value)	
		{
			PWM=1;
		}
		else
		{
			PWM=0;
		}		
	}		

定時器1中斷

void Time1(void) interrupt 3    //3 為定時器1的中斷號  1 定時器0的中斷號 0 外部中斷1 2 外部中斷2  4 串列埠中斷
{
	TH1 = 0xFF; 
	TL1 = 0xff;   //1us
	timer1++; 
    count++;
	
}

相關文章