CH563評估板測試2——外部中斷

? 春節(jié)前做了一個簡單的開箱測試,跑了個流水燈,大概了解了一下CH563的基本開發(fā)流程。假期間天天走親訪友、吃喝醉睡,板子扔在一邊整個假期居然一下也沒碰。昨天上班,剛開工,沒什么事干,又把板子拿起來測試了一下CH563的中斷系統(tǒng)。

? CH563的中斷模式與其它ARM芯片差不多,分為IRQ與FIQ,同時每種模式還分為查詢?nèi)肟谂c直跳入口中斷。第一篇測試文章里提到的IRQ_Handler(),F(xiàn)IQ_Handler()這兩個函數(shù)就是默認的查詢?nèi)肟谥袛嗵幚砗瘮?shù)。在使用查詢?nèi)肟谥袛鄷r,我們要把中斷處理相關(guān)內(nèi)容寫到這兩個函數(shù)里。由于在查詢方式下所有的中斷源發(fā)生中斷后都是跳向這兩個函數(shù),所以一般要在這兩個函數(shù)里先對中斷源進行判斷,再跳轉(zhuǎn)到相應(yīng)的處理程序里。顯然這種方式會多消耗一些處理器時間。

? 而相對的直跳入口與51單片機的中斷處理差不多,都是通過指定中斷向量,一旦某一特定中斷發(fā)生時,就直接跳轉(zhuǎn)到指定的中斷處理函數(shù)里去,從而節(jié)省了一點處理器時間。

? 為了了解CH563的中斷處理方式,俺設(shè)計了兩個小程序來分別測試查詢?nèi)肟谂c直跳入口。使用的都是PB管腳做為外中斷源,利用板上的三個LED燈來指示是否進入了中斷處理程序。

? 程序1為查詢?nèi)肟?,中斷源為PB6、PB7。PB6設(shè)定為上升沿觸發(fā),PB7設(shè)定為下降沿觸發(fā)。PB7是直接利用板上的按鈕S2來觸發(fā)中斷,從而控制三個LED依次單獨點亮。PB6則用了一根杜邦線通過與GND的接觸來觸發(fā)中斷,將三個LED的狀態(tài)反轉(zhuǎn)。

下面為程序1的代碼,具體寄存器的作用都作了注釋:

#include?"CH563BAS.H"
#include?"CH563SFR.H"
#include?"SYSFREQ.H"

#define?LED?0x38

CHAR?LEDMASK[]={0x30,0x28,0x18};
CHAR?IntTime;


__irq?void?IRQ_Handler()
{
	??if(R8_INT_STATUS_PB_0&0x80)			//是否為PB.7中斷
		{
		Delay_ms(30);???????????//在中斷處理程序里做延時消抖,就是這么任性:)
		if(!(R8_PB_PIN_0&0x80))					
		{
			if(IntTime<3)
			{
				R8_PB_CLR_0?|=LED;?//LED清零
				R8_PB_OUT_0?|=?LEDMASK[IntTime];
			}
			if(++IntTime>=3)?IntTime=0;
		}
		}
		if(R8_INT_STATUS_PB_0&0x40)	//是否為PB.6中斷
		{
			Delay_ms(30);
			if((R8_PB_PIN_0&0x40))
			{
			R8_PB_OUT_0?^=LED;?						??????????	}
		}
????R8_INT_STATUS_PB_0?=?0xff;?????????//?中斷標(biāo)志清零?
????
}
	
__irq?void?FIQ_Handler(){}
	
void?IRQ_InitPB_7_6(void)
{
	R8_PB_PU_0?|=?0xc0;	//設(shè)置PB.7.6為上拉
	R8_PB_DIR_0?&=?~0xc0;	//設(shè)置PB.7.6為輸入

	R8_INT_ENABLE_PB_0?|=?0xc0;	//打開兩IO外部中斷
	R8_INT_MODE_PB_0?|=0xc0;	//設(shè)置中斷觸發(fā)方式為邊沿觸發(fā)
	R8_INT_POLAR_PB_0?&=?0x7f;	//設(shè)置PB.7下降沿觸發(fā)
	R8_INT_POLAR_PB_0?|=?0x40;	//設(shè)置PB.6上升沿觸發(fā)
	R8_INT_STATUS_PB_0?=?0xff;
	
	R8_INT_EN_IRQ_1?|=?RB_IE_IRQ_PB;	//使能PB口IRQ中斷
	R8_INT_EN_IRQ_GLOB|=?RB_IE_IRQ_GLOB;???//使能全局IRQ中斷
}

void?Init_LED(void)
{
	
	R8_PB_DIR_0?|=?LED;		//PB.3.4.5為輸出
	R8_PB_OUT_0?|=	LED;																						
}
	

int?main()
{
	IRQ_InitPB_7_6(?);
	Init_LED();
	IntTime=0;
	while(1)
	{
		
	}
}




接一樓,下面為直跳入口中斷處理的例子代碼,其實與查詢?nèi)肟趨^(qū)別不大,主要是要指定相應(yīng)的中斷向量,具體的寄存器設(shè)置見下面的代碼。

? ? 為了與查詢?nèi)肟诘某绦蚬δ芟鄥^(qū)別,下面的程序里將中斷源設(shè)置為PB0,1,2,7四個管腳。PB7的功能與之前一樣,只是換了種寫法。PB0,1,2則分別控制一個LED,相互之間互不影響。代碼里同樣做了比較詳細的注釋供大家參考:

#include?"ch563sfr.h"
#include?"sysfreq.h"

#define?LED?1
CHAR?led_bit;

__irq?void?IRQ_Handler(void)
{
	
}


__irq?void?FIQ_Handler(void)
{
	
}



__irq?extern?void??PB_Handler(void)???//直跳中斷處理函數(shù)
{
	if(R8_INT_STATUS_PB_0&0x80)
	{
		Delay_ms(30);
		if(!(R8_PB_PIN_0&0x80))
		{
			if(led_bit<3)?led_bit=5;
			R8_PB_OUT_0?=~(LED<<led_bit);
			led_bit--;
		}
	}
	
	if(R8_INT_STATUS_PB_0&0x01)
	{
		Delay_ms(30);
		if(!(R8_PB_PIN_0&0x01))
		{
			R8_PB_OUT_0?^=??0x20;
		}
		
	}
	
	if(R8_INT_STATUS_PB_0&0x02)
	{
		Delay_ms(30);
		if(!(R8_PB_PIN_0&0x02))
		{
				R8_PB_OUT_0?^=?0x10;
		}
		
	}
	
	if(R8_INT_STATUS_PB_0&0x04)
	{
		Delay_ms(30);
		if(!(R8_PB_PIN_0&0x04))
		{
				R8_PB_OUT_0?^=?0x08;
		}
		
	}
	
	R8_INT_STATUS_PB_0?=0xff;
}

void?PB_INT_Init(void)			//中斷初始化函數(shù),將PB.0.1.2.7做為中斷源
{
	R8_PB_PU_0|=0x87;								
	R8_PB_DIR_0?&=~0x87;
		
	R8_INT_ENABLE_PB_0?|=?0x87;
	R8_INT_MODE_PB_0?|=?0x87;
	R8_INT_POLAR_PB_0?&=?~0x87;
	
	R8_SAFE_ACCESS_SIG?=?0x57?;??//?要實現(xiàn)直跳中斷入口必須執(zhí)行此步驟進入安全模式
????????R8_SAFE_ACCESS_SIG?=?0xA8?;
	R32_INT_VEC_PB?=?MAKE_INT_VEC_IRQ(?PB_Handler?);//設(shè)置PB端口直跳中斷向量寄存器
	R8_INT_VEC_IRQ?|=RB_IV_IRQ_PB;??//使能PB中斷直跳入口
	R8_SAFE_ACCESS_SIG?=?0x00?;
	
	R8_INT_STATUS_PB_0?=0xff;
	
	R8_INT_EN_IRQ_1?|=?RB_IE_IRQ_PB;
	R8_INT_EN_IRQ_GLOB?|=?RB_IE_IRQ_GLOB;
	
	
}

void?LED_IO_Init()
{
	
	R8_PB_DIR_0?|=?0x38;
	R8_PB_OUT_0?|=?0x38;
}

int?main()
{
	PB_INT_Init();
	LED_IO_Init();
	led_bit=5;
	
	while(1)
	{
	}
	
	
}

經(jīng)過這兩種程序的編寫與實際測試,對CH563的中斷處理有了一個基礎(chǔ)的認識與了解。這篇測試就寫到這了,后面我會將定時器中斷的測試進行整理,并發(fā)貼。


官方的例程是有點小問題吧


? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

官方的例程是有點小問題吧

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

官方?jīng)]有給外部中斷直跳入口的例程,ds里給了一點文字說明。中斷還算好的,其他的模塊說明更不好明白。我卡在pwm上了,能進中斷,但相應(yīng)的管腳就是沒輸出。



有技術(shù)疑問可聯(lián)系張工:025-52638371


PWM操作流程:

1、配置對應(yīng)引腳方向為輸出

2、配置PWM周期和占空比

3、配置對應(yīng)定時器的“模式控制寄存器”(R8_TMRx_CTRL_MOD位2和位3置1)

如果需要使用中斷,則配置對應(yīng)中斷即可。詳見EVT例子程序。

?


我就是這樣寫的,但PWM相應(yīng)的引腳測不到脈沖。是每次輸出都要配置一遍周期與占空比嗎?


? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

PWM操作流程:

1、配置對應(yīng)引腳方向為輸出

2、配置PWM周期和占空比

3、配置對應(yīng)定時器的“模式控制寄存器”(R8_TMRx_CTRL_MOD位2和位3置1)

如果需要使用中斷,則配置對應(yīng)中斷即可。詳見EVT例子程序。

?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

下面是我按手冊里對PWM的說明寫的一個簡單的測試程序,但我始終無法在PWM2上得到脈沖,通過在IRQ函數(shù)里添加調(diào)試標(biāo)志,發(fā)現(xiàn)RB_TMR_IE_DATA_ACT中斷始終沒有發(fā)生。我不知問題出在什么地方,請ZFL指導(dǎo)一下,謝謝。

#include?"CH563SFR.H"
#include?"sysfreq.h"

__irq?void?IRQ_Handler()
{
	
	if(R8_INT_FLAG_0&RB_IF_TMR0)
	{
		UINT8?i;
		i=R8_TMR0_INT_FLAG;
		if(i&RB_TMR_IF_DATA_ACT)
		{
		?????R8_TMR0_INT_FLAG?|=?RB_TMR_IF_DATA_ACT;??????????????????????????????????????????????????R8_INT_FLAG_0?|=?RB_IF_TMR0;?
		}
		
		if(i&RB_TMR_IF_CYC_END)
	????????{			
????????????????????R8_TMR0_INT_FLAG|=RB_TMR_IF_CYC_END;??
????????????????????R8_INT_FLAG_0?|=?RB_IF_TMR0;???
????????????????}
	}
		
	
}

__irq?void?FIQ_Handler()
{
	
}

void?PWM_Init()
{
	R8_PB_DIR_0|=PWM2;
	R32_TMR0_FIFO=100000000/2;
	R32_TMR0_CNT_END=100000000;
	R8_TMR0_CTRL_MOD&=~(RB_TMR_MODE_NRZI|RB_TMR_ALL_CLEAR|RB_TMR_MODE_IN);
	R8_TMR0_CTRL_MOD|=(RB_TMR_OUT_EN|RB_TMR_COUNT_EN)
	;
	R8_TMR0_INTER_EN?|=(RB_TMR_IE_CYC_END|RB_TMR_IE_DATA_ACT);
	
	R8_INT_EN_IRQ_0|=RB_IE_IRQ_TMR0;
	R8_INT_EN_IRQ_GLOB|=RB_IE_IRQ_GLOB;
}

int?main()
{
	PWM_Init();
	
	while(1)
	{}
}



只有登錄才能回復(fù),可以選擇微信賬號登錄

国产91精品新入口,国产成人综合网在线播放,九热这里只有精品,本道在线观看,美女视频a美女视频,韩国美女激情视频,日本美女pvp视频