關于lm3s811代碼全解析_第1頁
關于lm3s811代碼全解析_第2頁
關于lm3s811代碼全解析_第3頁
關于lm3s811代碼全解析_第4頁
關于lm3s811代碼全解析_第5頁
已閱讀5頁,還剩112頁未讀, 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

*注:未指明返回值的函數為無返回值,資源來自周立功單片機網站

一:GPIO函數

1:voidGPIODirModeSet(unsignedlongulPort,unsignedcharucPins,

unsignedlongulPinlO)

設置所選GPIO端口指定管腳的方向和模式

如GPIODirModeSe(GPIO_PORTA_BASE,GPIO_PIN_2,GPIO_DIR_MODE_IN)函

數設置PA2為輸入,但第三個參數為KGPIO_DIR_MODE_HW//硬件控制”時指此

管腳啟用第二功能;

2:unsignedlongGPIODirModeGet(unsignedlongulPort,unsignedchar

ucPin)

獲取所選GPIO端口指定管腳的方向和模式

如unsignedlongSetValue=GPIODirModeGet(GPIO_PORTA_BASE,GPIO_PIN_2);

返回PA2腳的方向和模式,返回的值為上一個函數第三個參數的取值,分別為

GPIO-DIR_MODE_IN//輸入方向

GPI0-DIR-M0DE_0UT//輸出方向

GPI0_DIR_M0DE_HW//硬件控制

3:voidGPIOPadConfigSet(unsignedlongulPort,

unsignedcharucPins,

unsignedlongulStrength,

unsignedlongulPadType)

設置所選GPIO端口指定管腳的驅動強度和類型

如GPIOPadConfigSet(GPIO_PORTA_BASE,GPIO-PIN.2,

GPIO-STRENGTH_4MA,GPIO-PIN_TYPE_STD)設置PA2腳的驅動強度為4MA的推

挽輸出;

ulStrength:指定輸出驅動強度,應當取下列值之一:

GPI0-STRENGTH_2MA//2mA驅動強度

GPI0.STRENGTH_4MA//4mA驅動強度

GP10_STRENGTH_8MA//8mA驅動強度

GPI0_STRENGTH_8MA_SC//帶轉換速率(SlewRate)控制的8mA驅動

ulPadType:指定管腳類型。應當取下列值之一:

GPTO-PIN_TYPE_STD//推挽

GPIO-PIN-TYPE-STD-WPU//帶弱上拉的推挽

GPIO_PIN_TYPE_STD_WPD//帶弱下拉的推挽

GPIO_PIN_TYPE_OD//開漏

GPIO-PIN-TYPE-OD-WPU//帶弱上拉的開漏

GPIO_PIN-TYPE-OD_WPD//帶弱下拉的開漏

GP1O_PIN_TYPE_ANALOG//模擬比較器

4:voidGPIOPadConfigGet(unsignedlongulPort,

unsignedcharucPin,

unsignedlong*pulStrength,

unsignedlong*pulPadType)

獲取所選GPIO端口指定管腳的配置信息

如GPIOPadConfigGet(GPIO-PORTA-BASE,GPIO-PIN_2,pulStrength,

pulPadType);輸出驅動強度信息保存到pulStrength指向的地址中,輸出驅動

類型信息保存到pulPadType指向的地址中,返回的值為上一個函數設置的內容。

5:voidGPIOPinTypeGPIOInput(unsignedlongulPort,unsignedchar

ucPins)

設置所選GPIO端口指定的管腳為高阻輸入模式

如GPIOPinTypeGPIOInput(GPIO-PORTA.BASE,GPIO-PIN.2);設置PA2腳為

高阻輸入模式

6:voidGPIOPinTypeGPIOOutput(unsignedlongulPort,unsignedchar

ucPins)

設置所選GPIO端口指定的管腳為推挽輸出模式

如GPIOPinTypeGPIOOutput(GP1O_PORTA_BASE,GP1O_PIN_2)設置PA2腳為

推挽輸出模式

7:voidGPIOPinTypeGPIOOutputOD(unsignedlongulPort,unsignedchar

ucPins)

設置所選GPIO端口指定的管腳為開漏輸出模式

如GPIOPinTypeGPIOOutputOD(GPIO_PORTA_BASE,GPIO_PIN_2)設置PA2為

開漏輸出模式

但由于函數5,6,7函數名太長一般做如下簡化:

#defineGPIOPinTypelnGPIOPinTypeGPIOInput

#defineGPIOPinTypeOutGPIOPinTypeGPIOOutput

#defineGPIOPinTypeODGPIOPinTypeGPIOOutputOD

8:voidGPIOPinTypeADC(unsignedlongulPort,unsignedcharucPins)

設置所選GPIO端口指定的管腳為ADC功能

這個函數只對有adc功能復用的管腳有用如LM3s811的1,2,3,4腳。。

9:voidGPIOPinTypeCAN(unsignedlongulPort,unsignedcharucPins)

設置所選GPIO端口指定的管腳為CAN功能

10:voidGPIOPinTypeComparator(unsignedlongulPort,unsignedchar

ucPins)

設置所選GPIO端口指定的管腳為CAN功能

11:voidGPIOPinTypeComparator(unsignedlongulPort,unsignedchar

ucPins)

設置所選GPIO端口指定的管腳為模擬比較器功能

12:voidGPIOPinTypeI2C(unsignedlongulPort,unsignedcharucPins)

設置所選GPIO端口指定的管腳為12c功能

13:voidGPIOPinTypePWM(unsignedlongulPort,unsignedcharucPins)

設置所選GPIO端口指定的管腳為PWM功能

14:voidGPIOPinTypeQEI(unsignedlongulPort,unsignedcharucPins)

設置所選GPIO端口指定的管腳為QEI功能

15:voidGPIOPinTypeSSI(unsignedlongulPort,unsignedcharucPins)

設置所選GPIO端口指定的管腳為SSI功能

16:voidGPIOPinTypeTimer(unsignedlongulPort,unsignedcharucPins)

設置所選GPIO端口指定的管腳為Timer的CCP功能

17:voidGPIOPinTypeUART(unsignedlongulPort,unsignedcharucPins)

設置所選GPIO端口指定的管腳為UART功能

18:voidGPIOPinTypeUSBDigital(unsignedlongulPort,unsignedchar

ucPins)

設置所選GPIO端口指定的管腳為USB數字功能

對GPIO管腳的讀寫操作是通過函數GPIOPinWrite()和GPIOPinRead()

實現的,這是兩個非常重要而且很常用的庫函數。

19:voidGPIOPinWrite(unsignedlongulPort,unsignedcharucPins,

unsignedcharucVa1);

向所選GPIO端口的指定管腳寫入一個值,以更新管腳狀態,ucVal:寫入

指定管腳的值

注:ucPins指定的管腳對應的ucVal當中的位如果是1,則置位相應的管

腳,如果是0,則清零相應的管腳;ucPins未指定的管腳不受影響。

如GPIOPinWrite(GPIO-PORTA_BASE,GPIO-PIN.3,0x00);//清除PA3

GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_5,OxFF);//置位PB5

GPIOPinWrite(GPIO_PORTD_BASE,GPIO-PIN-2|GPIO-PIN_6,OxFF);//同

時置位PD2、PD6

GPTOPinWrite(GPIO-PORTA_BASE,OxFF,ucData);//變量ucData輸出到

PA0-PA7

20:longGPIOPinRead(unsignedlongulPort,unsignedcharucPins)

讀取所選GPIO端口指定管腳的值,返回1個位組合的字節。該字節提供了

由ucPins指定管腳的狀態,對應的位值表示GPIO管腳的高低狀態。ucPins未

指定的管腳位值是0。返回值已強制轉換為long型,因此位31:8應該忽略。這

個函數應該在相應管腳已經設置為輸出狀態的情況下,由于GPIO得管腳結構我

們知道在輸出模式下,不管是開漏還是推挽用此函數讀回來的值都是管腳的輸出

鎖存值,

如//讀取PA4,返回值保存在ucData里,可能的值是0x00或0x10

ucData=GPIOPinRead(GPIO_PORTA_BASE,GPI0_PIN_4);

//同時讀取PB1、PB2和PB6,返回PBLPB2和PB6的位組合保存在ucData

ucData=GPIOPinRead(GPIO-PORTB.BASE,GPIO-PIN.l|GPIO-PTN.2I

GPIO-PIN-6);

//讀取整個PF端口

ucData=GPIOPinRead(GPIO-PORTF.BASE,OxFF);

在Stellaris系列ARM里,每個GPIO管腳都可以作為外部中斷輸入。中

斷的觸發類型分為邊沿觸發和電平觸發兩大類,共5種,用起來非常靈活。配

置GPIO管腳的中斷觸發方式可以通過調用函數GPIOIntTypeSet()來實現,函

數GPIOlntTypeGet()用來獲取配置情況。函數GPIOPinlntEnable()和

GPIOPinIntDisable()用來使能和禁止GPIO管腳中斷。函數

GPIOPinIntStatus()用來獲取GPIO管腳的中斷狀態.在同一個GPIO端口上,

8個GPIO管腳的中斷向量都是共用的。如果同時配置了同一端口上的多個管腳

中斷,則可以先利用函數GPIOPinIntStatus()讀取中斷狀態,再進一步確認

具體是哪個管腳產生的中斷請求。函數GPIOPinIntClear()用來及時清除GPIO

管腳的中斷狀態。函GPIOPortIntRegister()用來注冊一個GPIO端口中斷服務

函數,而注銷的方法是調用函數GPlOPortlntUnregister()。

2012CSDN網站六大類職位火熱招聘中!點擊了解英特爾云計算2012年1月當

選微軟MVP的CSDN會員名單揭曉!

Im3s811學習筆記(四)[gpio]

分類:cortexm32011-08-0315:24295人閱讀評論(0)收藏舉報

今天主要是熟悉下gpio的一些應用。最簡單的就是LED燈的控制。

下面的例子就拿L5來說明吧。

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);//enablegpiob

GPIOPinTypeGPIOOutput(GPIO-PORTB-BASE,GPIO-PIN-O);//setPBOoutput

還有一種模式設置的方法GPIODirModeSet(GPIO_PORTB_BASE,GPIO_PIN_0,

GPIO_DIR_MODE_OUT);//這個方案可以設置多個引腳,參數2為位引腳的或

控制LED燈地亮滅,就是往引腳寫入值

ledstatus=GPIOPinRead(GPIO_PORTD_BASE,GPIO_PIN_0);

GPIOPinWrite(GPIO-PORTD.BASE,GPIO-PIN_0,GPIO-PIN_0&Cledstatus));

上面的程序是讀取L5對應管腳的值,然后使燈地狀態進行翻轉。

這里說下GPIOPinWriteO該函數的用法。

GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_1,GPIO_PIN_1);

GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_1,_GPIO_PIN_1);

例程上常用上面的方法。主要也就是你要讓哪個管腳置一,參數3的值中管腳對

應的位必須置一。

如下各條指令都能點亮響應端口(假設已經都定義成輸出了)。

GPIOPinWrite(GPIO-PORTD-BASE,GPIO-PIN-O,1);

GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_1,2);

GPIOPinWrite(GPIO-PORTD.BASE,GPIO-PIN.2,4);

GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_3,8);

GPIOPinWrite(GPIO-PORTD.BASE,GPIO-PIN.4,0x10);

GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_5,0x20);

GPIOPinWrite(GPIO-PORTD.BASE,GPIO-PIN.6,0x40);

GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_7,0x80);

下面我主要講述下鍵控LED的流程,其實就是利用按鍵中斷控制燈的亮滅。

首先是配置KEY。

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);//EnableGPIOC

GPIOPinIntEnable(GPIO-PORTC-BASE,GPIO-PIN.4);//EnableGPIOCpin4

GPIOPinTypeGPIOInput(GPIO_PORTC_BASE,GPI0_PIN_4);//setthepinmodeis

input

GPIOIntTypeSet(GPIO-PORTC-BASE,GPIO_PIN_4,GPIO_LOW_LEVEL);//set

interrupttypeislowFallingedge

IntEnable(INT-GPIOC);//enableGPIOCinterrupt

下面是按鍵中斷的處理函數

voiduserkey-handler(void)

(

unsignedcharucVal;

unsignedlongulStatus;

ulStatus=GPIOPinlntStatus(GPIO_PORTC_BASE,true);//getgpioc

interruptstatus

GPIOPinlntClear(GPIO_PORTC_BASE,ulStatus);//clearinterruptstatus

if(ulStatus&GPIO-PIN_4)//如果KEY的中斷狀態有效

ucVal=GPIOPinRead(GPIO-PORTD_BASE,GPIO_PIN_0);//翻轉LED

GPIOPinWrite(GPIO-PORTD_BASE,GPIO-PIN-O,~ucVal);

SysCtlDelay(10*(SysCtIClockGet0/3000));//延時約)0ms,消除按鍵

抖動

while(GPIOPinRead(GPIO-PORTC.BASE,GPIO_PIN_4)==0x00);//等待KEY

抬起

SysCtlDelay(10*(SysCtIClockGet0/3000));//延時約10ms,消除松鍵

抖動

)

)

既然用到了SysCtlDelayO函數。在這里也順道分析下。

#ifdefined(ewarm)||defined(DOXYGEN)〃iar環境下

void

SysCt1Delay(unsignedlongulCount)

(

__asm("subsrO,#l\nH

"bne.nSysCtlDelay\nn

"bxlrH);

)

#endif

#ifdefined(codered)IIdefined(gcc)IIdefined(sourcerygxx)//codered.

gcc、sourcerygcc環境下

void--.attribute--((naked))

SysCt1Delay(unsignedlongulCount)

(

__asm("subsrO,#l\nH

"bneSysCtlDelay\nn

"bxlrH);

)

#endif

#ifdefined(rvmdk)|Idefined(--ARMCC_VERSION)//kei1MDK環境下

一asmvoid

SysCt1Delay(unsignedlongulCount)

(

subsrO,#1;

bneSysCtIDelay;

bxIr;

)

#endif

#ifdefined(ccs)//ccs

volatileunsignedlongg_ulIniineCCSWorkaround;

void

SysCtIDelay(unsignedlongulCount)

(

--asm("delay?:subsrO,#l\n"

"bne.ndelay?\n"

"bxlr\nn);

//

//ThisisneededtokeepTIcompilerfromoptimizingawaythiscode.

//

g_ulIniineCCSWorkaround+=ulCount;

)

#endif

SysCtlDelayO執行了3個匯編語句,運行時間3個始終周期。函數說明上:The

looptakes3cycles/loop.

1、在主晶振6MHz的情況下

SysCtIDelay(2);delaytime=2*3*(1/6000000)=lus

SysCtIDelay(10*(TheSysClock/3000));delaytime=10*(6000000/3000)

*3*(1/6000000)=10ms

2、在主晶振8MHz的情況下

SysCtIDelay(2);delaytime=2*3*(1/8000000)=0.75us

SysCtlDelay(10*(TheSysClock/3000));delaytime=10*(8000000/3000)

*3*(1/8000000)=10ms

由此可以看出無論是多大的晶振,都是除以3000。SysCtlDelayClO*

(TheSysClock/3000));這種寫法也方便移植

Im3s811點亮LED或流水燈程序1急求?。。。?/p>

2010-8-617:41

提問者:luxiahua427511懸賞分:5瀏覽次數:525次

謝謝了?。傞_始學ARM又沒有實際的程序!謝謝幫忙了

210239343luxiahua427511luxiahua427511Im3s811點亮LED0

15I

推薦答案

2010-8-1512:34

#include"systemlnit.h"

//定義LED

#defineLED-PERIPHSYSCTL_PERIPH_GPTOA

#defineLED.PORTGPIO_PORTA_BASE

#defineLED-PINGPIO-PIN.2

//主函數(程序入口)

intmain(void)

(

jtagWait();//防止

"AG失效,重要!

clocklnit();//時鐘

初始化:晶振,6MHz

SysCtlPeriEnable(LED-PERIPH);//使能

LED所在的GPIO端口

GPIOPinTypeOut(LED.PORT,LED-PIN);//設置

LED所在管腳為輸出

for(;;)

(

GPIOPinWrite(LED_PORT,LED-PIN,0x00);//點亮LED

//SysCtlDelay(1000000);//延時

SysCtlDelayClOOO*(SysCtIClockGet()/36000));//延時

1000ms

GPIOPinWrite(LED_PORT,LED-PIN,OxFF);//熄滅LED

//SysCtlDelay(lOOOOOO);//延時

SysCtlDelayClOOO*(SysCtIClockGet()/3000));//延時

1000ms

)

最基本的一個例程,已調試通過(systemlnit.C的口該一下,8n沒G口的)。

你可以去zig網站上去找找資料,那里的例程很多,很適合新手。我也才剛剛開

始學,一起努力了。

0

評論

回復:青風和大家一起學Stellaris系列ARM——九.ADC轉換。

程序演示:

分別完成三種ADC變化:程序一:內部溫度測試;程序二:單端采樣;程序三:

差分采樣;

內部溫度測試:

在Stellaris系列的ADC模塊里,附帶了一個內置的溫度傳感器,能夠隨時檢

測芯片的溫度。該溫度傳感器可以有以下用途:

1測試用:在單獨測試ADC模塊的功能時,而不必提供外部的模擬信號源

2測量芯片自身溫度,防止可能出現的過溫(高溫應用場合必備)

3估算環境溫度:芯片溫度總是比環境溫度略高,如果通過實驗找到這個差值,

則可以進行軟件修正

4在隨機算法里可以提供隨機數種子

內部溫度傳感器提供了模擬溫度讀取操作和參考電壓。輸出終端SENSO的電壓

通過以下等式計算得到:

SENSO=2.7-(T+55)/75

ADC溫度傳感器溫度-電壓關系

一個實用的ADC溫度轉換公式。假設溫度電壓SENSO對應的ADC采樣值為N,

2.7V對應Nl,(T+55)/75對應N2。

已知:

N1x(3/1024)=2.7

N2x(3/1024)=(T+55)/75

由此得到:

N=Nl-N2=2.7/(3/1024)-((T+55)/75)/(3/1024)

解得:

T=(151040-225xN)/1024

結論:ADC配置為溫度傳感器模式后,只要得到10位采樣值N,就能推算出攝

氏溫度T。

程序標注:

#include"inc/hw_memmap.h"

#include"inc/hw-types.h"

#include"driver1ib/adc.h"

#include"driver1ib/gpio.h"

#include"driverlib/sysctl.h"

#include"utiIs/uartstdio.h"

void

InitConsole(void)

(

//

//初始化GPIO外設

//

SysCtlPeripheralEnable(SYSCTL.PERIPH-GPIOA);

//

//配置化串口外設

//

GPIOPinConfigure(GPIO-PAO.UORX);

GPIOPinConfigure(GPIO_PAl_UOTX);

//

//配置串口管腳

//

GPIOPinTypeUART(GPIO_PORTA_BASE,GPIO_PIN_OIGPIO_PIN_1);

//

//初始化串口

//

UARTStdioInit(O);

}

int

main(void)

(

//

//T設置數組讀取ADCFIFO

//

unsignedlongulADCO-Value[1];

//

//設置溫度轉換變量

//unsignedlongulTemp-ValueC;

unsignedlongulTemp-ValueF;

//

//設置PLL,ADC的時鐘必須要16MHz

//

SysCtlClockSet(SYSCTL_SYSDIV_10ISYSCTL_USE_PLLISYSCTL-OSC-MAIN

SYSCTL_XTAL_16MHZ);

//

//初始化開發板端口

//

InitConsole();

//

//串口顯示

//

UARTprintf("ADC->\n");

UARTprintf("Type:InternalTemperatureSensor\n");

UARTprintf("Samples:One\n");

UARTprintf("UpdateRate:250ms\n");

UARTprintf("InputPin:Internaltemperaturesensor\n\n");

//

//ADCO外設初始化

//

SysCtlPeripheralEnable(SYSCTL-PERIPH-ADCO);

//

//配置ADCO,采樣序列3,ADC處理器觸發,優先級為0

//

ADCSequenceConfigure(ADCO_BASE,3,ADJTRIGGER.PROCESSOR,0);

//

//溫度傳感,中斷使能,對列結束選擇,無ADC通道

//

ADCSequenceStepConfigure(ADCO-BASE,3,0,ADC-CTL-TSI/\DC_CTL_IE

ADC-CTL.END);//

//

//使能ADC采樣

//

ADCSequenceEnable(ADCO-BASE,3);/

//

////ADC中斷清除

//

ADCIntClear(ADCO-BASE,3);

//

〃設置溫度顯示

//

while(1)

(

//

//ADC處理器觸發

//

ADCProcessorTrigger(ADCO-BASE,3);

//

//獲取中斷狀態

//

while(!ADCIntStatus(ADCO-BASE,3,false))

//

//獲取ADC采樣數據

//

ADCSequenceDataGet(ADCO-BASE,3,ulADCO-Value);

//

//計算溫度C

//

ulTemp.ValueC=((1475*1023)-(2250*ulADCO.Value[0]))/10230;

//

//計算溫度F

//

ulTemp-ValueF=((ulTemp-ValueC*9)+160)/5;

//

//串口顯示

//

UARTprintf("Temperature=%3d*Cor%3d*F\r",ulTemp-ValueC,

ulTemp-ValueF);

//

//時鐘延遲

//

SysCtlDelayCSysCtlClockGet()/12);

)

}

運行結果:

LM3s811防止Jtag失效的源代碼

(2011-05-2114:20:16)

轉載▼

標簽:分類:LM3

Im3s811

雜談

voidJtagWait(void)

unsignedlongi;

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);//使能KEY、LED所在的PC

端口

GPIOPinTypeGPIOInput(GPIO-PORTC.BASE,GPIO-PIN-4);//設置KEY所在管腳

PC4為輸入

GPIOPinTypeGPIOOutput(GPIO_PORTC_BASE,GPIO_PIN_5);//設置LED所在管

腳PC5為輸出

if(GPIOPinRead(GPIO-PORTC.BASE,GPI0_PIN_4)==0x00)//若復位或上電

時按下KEY,則進入

(

while(l)//死循環,以等待JTAG連接,LED閃爍

{

for(i=0;i<200000;i++);

GPIOPinWrite(GPIO_PORTC_BASE,GPIO_PIN_5,GPIO_PIN_5);〃點亮LED

for(i=0;i<200000;i++);

GPIOPinWrite(GPIO-PORTC-BASE,GPIO_PIN_5,_GPIO_PIN_5);〃熄滅LED

}

)

SysCtlPeripheralDisable(SYSCTL_PERIPH_GPIOC);//禁止KEY所在的GPIO

端口

}

模數轉換器(ADC)外設用于將連續的模擬電壓轉換成離散的數字量。

Stellaris系列ARM集成有一個分辨率為10位的ADC模塊,支持4/16個輸入通

道,以及一個內部溫度傳感器。Lm3s811支持4個輸入通道,Im3s9b96支持16

個輸入通道。每個ADC模塊包含4個可編程的序列發生器。每個采樣序列均對完

全可配置的輸入源、觸發事件、中斷的產生和序列優先級提供靈活的編程。

Stellaris系列ARM的ADC通過使用一種基于序列(sequence-based)的可編

程方法來收集采樣數據,取代了傳統ADC模塊使用的單次采樣或雙采樣的方法。

每個采樣序列均為一系列程序化的連續(back-to-back)采樣,使得ADC可以從

多個輸入源中收集數據,而無需控制器對其進行重新配置或處理。

對本下811和9B96的結構圖:

811ADC結構圖

9B96ADC結構圖

對比2個系列的ADC結構圖,大家可以發現:基本相差不大,觸發條件完全相同:

具有:比較器,定時器,GPIO,PWM的觸發條件。

同時具有4個可編程序列發生器,相對應的SS中斷。不同的是9B96的ADC可以

產生相應的PWM觸發信號。811不支持外部參考電壓,因此硬件方面:

811用于ADC方面的只有4個管腳了。分別代表4個輸入通道。

您好!jtagwait是用于防止JTAG失效鎖定,其作用主要是針對48腳和64

腳的系列芯片,而現在的100腳的系列芯片已經支持JTAG解鎖,所以可以不使

用jtagwait來檢測。

而jtagwait是防止用戶對JTAG調試接口的相關引腳進行誤操作,使軟件不能利

用JTAC調試功能,而微控制器在上電后,先執行jtagwait檢測程序,來檢測某

引腳電平,并進入WHILE⑴;循環,從而使得LMFLASHPROGRAMMER軟件可以通

過JTAG連接上微控制器,進而將用戶程序擦除,恢復其正常的JTAG調試功能。

LM3S系列JTAG口當10用的解鎖

LM3S系列ARM的JTAG口原本是跟10口復用的,當GPIO用時跟一般GPIO沒什

么不同。一般只在CPIO口不夠用或者做產品不希望用戶隨意更新固件時,會把

JTAG口當GPIO口來用。如果將JTAG那5根線用作CPIO功能,芯片就會被鎖住,

不過要注意,鎖住后JTAG就再也不起作用了。解決被鎖的辦法有兩個:

一是下載程序時留有恢復措施,只需啟用即可恢復。

如果沒有加預防鎖死的代碼,就只能用Luminary的LMLINK來解鎖。很遺憾的

是Sandstorm系列(LM3Sxxx)只支持部分類型,解鎖功能也不是很穩定,LM3Sxxxx

才能很好解鎖,不過可以試試看。如果有高人看得懂它的時序再寫出上位機應該

ULINK也解得了。實在打不開只能找流明諾瑞或更換芯片了。

下面是一段lordor兄使用LM3SXXXSmartBoard演示板恢復JTAG的演示代碼:

voidInit-cpu(void)

〃初始化系統時鐘設置

SysCtlClockSet(SYSCTL_USE_OSCISYSCTL-OSC-MAINISYSCTL_XTAL_6MHZ);

/******************************GPI0B初始化

〃使能GPIOB模塊

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);

////////////////////////////////////////////////////

/〃〃〃〃〃鎖定演示:如果設置為GPIO,則JTAG不起作用了

〃按鍵檢測

if(GPIOPinRead(KEYPORT,KD)//如果為高電平

GPIODirModeSet(PH5.PORT,PH5,GPIO-DIR_MODE_IN);//JTAG

if(GPIOPinRead(KEYPORT,K2))//如果為高電平

GPIODirModeSet(PH6.PORT,PH6,GPIO-DIR_MODE_IN);

GPIODirModeSet(PH7.PORT,PH7,GPIO-DIR_MODE_IN);

GPIODirModeSet(PH8-PORT,PH8,GPIO-DIR_MODE_IN);

GPIODirModeSet(PH9.PORT,PH9,GPIO-DIR_MODE_IN);

}

//設置GPIOB口的B4為輸出引腳

GPIODirModeSet(LED.PORT,LED1,GPIO-DIR_MODE_OUT);

〃設置連接LED1的引腳為高電平

GPIOPinWrite(LED_PORT,LED1,LED1);

)

說明:下載后,可以發現用JTAG無法通信了。要取消,同時按住K1及K2健,

重開機就可以取消鎖定功能了。--bylordor

最后,貼上用Luminary的LMLINK來解鎖LM3Sxxxx的方法。

網站六大類職位火熱招聘中!點擊了解英特爾云計算2012年1月當選微軟MVP

的CSDN會員名單揭曉!

LM3SAPI函數解讀范例

2010-03-0309:01784人閱讀評論⑶收藏舉報

jtagWait()函數解讀

1.通常在主函數的開始都要調用jtagWait。函數,如工程模版的主函數,

intmain(void)

(

jtagWaitO;//防止JTAG失效,重要!

clocklnit0;//時鐘初始化:晶振,6MHz

for(;;)

)

2.關于函數的解釋,先要找到函數的定義,可以在函數的調用處指向函數名后

右鍵選擇"Gotodefinitionof…”。

函數jtagWait0在systemlnit.c文件中,其功能是防止JTAG接口失效。

函數定義:

voidjtagWait(void)

(

SysCtIPeriEnable(KEY.PERIPH);//使能KEY所在的GPIO端口

GPIOPinTypeln(KEY-PORT,KEY-PIN);//設置KEY所在管腳為輸入

if(GPIOPinRead(KEY-PORT,KEY.PIN)==0x00)//若復位時按下KEY,則進

(

for//死循環,以等待JTAG連接

)

SysCtlPeriDisable(KEY.PERIPH);//禁止KEY所在的GPIO端口

)

/////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////

1111

①第一個函數SysCtlPeriEnableO的功能是使能外圍設備,原名是

SysCtlPeripheralEnable(),用#define替換是為了使用的方便,該函數在

sysctl.c文件中,可以先加入該文件以便使用"Gotodefinitionof…”找

到其定義。其定義為:

VoidSysCtlPeripheralEnable(unsignedlongulPeripheral)

ASSERT(SysCt1PeripheralVaiid(ulPeripheral));//Checkthearguments.

HWREG(g_pulRCGCRegs[SYSCTL_PERIPH_INDEX(ulPeripheral)])|=

SYSCTL-PERIPH-MASK(ulPeriphera1);//Enablethisperipheral.

)

該函數中的ASSERT。是一個宏,其定義在debug,h中,其作用是計算括號

中的表達式,為0則程序報告錯誤并終止執行,非0則繼續向下執行。函數

SysCtlPeripheralValidO用于判斷傳入參數的有效性,即判斷是否為該函數可

以處理的外圍設備,是則返回真,否則返回假,在調用中傳入參數KEY_PERIPH,

其實為SYSCTL_PERIPH_GPIOG,其值為0x20000040,該值不是寄存器的地址,暫

時不清楚該值的意義。

HWREGO又是定義的一個宏,在文件hw-types,h中,其定義為:

#defineHWREG(x)(*((volatileunsignedlong*)(x)))

其中(volatileunsignedlong*)(x)是將x強制轉換為無符號長整型的指針,

*((volatileunsignedlong*)(x))是引用該指針所指向的存儲單元,例如

HWREG(0x20000000)=1;就是向地址為0x20000000的存儲單元寫入L

傳入HWREG()的參數為

g_pulRCGCRegs[SYSCTL-PERIPH.INDEX(u1Peripheral)].

首先看g-PulRCGCRegs口,這是一個靜態只讀的無符號長整型數組,其定義

為:

staticconstunsignedlongg-pulSCGCRegs[]=

(

SYSCTL.SCGCO,//0x400FE110

SYSCTL.SCGCl,//0x400FE114

SYSCTL-SCGC2//0x400FE118

);

這其實是三個睡眠模式時鐘選通控制寄存器,每個位控制一個給定接口、功能、

或單元的時鐘使能,如果置位,則對應的單元接收時鐘并運行,否則,對應的單

元不使用時鐘并禁止(節能),這些位的復位狀態都為。(不使用時鐘),即所有

功能單元都禁止,應用所需的端口需通過軟件來使能。分了三個寄存器來管理所

有接口、功能、或單元的時鐘。SYSCTL_SCGC0=0x400FE110表示寄存器的地址。

再看SYSCTL_PERIPH_INDEX(ulPeriphera1),此處的

ulPeripheral=KEY_PERIPH=SYSCTL_PERIPH_GPIOG=0x20000040。

SYSCTL_PERIPH_INDEX()的定義為:

#defineSYSCTL_PERIPH_INDEX(a)(((a)?28)&Oxf),此處計算結果

SYSCTL_PERIPH_INDEX(0x20000040)=2,而g_pulSCGCRegs[2]正好是睡眠模式時

鐘選通控制寄存器2(SCGC2),正好是控制GPIOA—GPIOH的時鐘使能。因此不

難猜想SYSCTL_PERIPH」NDEX(a)是為了選擇寄存器SCGCO,SCGC1,SCGC2中的

一個。

因此HWREG(g_pulRCGCRegs[SYSCTL_PERIPH_INDEX(ulPeripheral)])意思就是

選中寄存器SCGC2,整句的意思是要改寫該寄存器的值。于是繼續看后半句

SYSCTL_PERIPH_MASK(ulPeripheral),當然1=是復合賦值a|=b相當于a=aIb。

#defineSYSCTL-PERIPH-MASK(a)(((a)&Oxffff)?(((a)&OxOOlfOOOO)?

16)),該句比較復雜,暫時不知道為什么要這樣寫,但此處計算結果

SYSCTL_PERIPH_MASK(0x20000040)=0x0040,因此

HWREG(g_pulRCGCRegs[SYSCTL_PERIPH_INDEX(ulPeripheral)])|=

SYSCTL_PERIPH_MASK(ulPeriphera1);

一句的目的是將寄存器SCGC2的第6位GPIOG置1而使能GPIOG端口。另外,再

看一下SCGC2的定義如下:

76543210

GPIOHGPIOGGPIOFGPIOEGPIODGPIOCGPIOBGPIOA

這就不難理解為什么有如下定義

#defineSYSCTL.PERIPH.GPIOA0x20000001//GPIOA

#defineSYSCTL_PERIPH_GPIOB0x20000002//GPIOB

#defineSYSCTL_PERIPH_GPIOC0x20000004//GPIOC

#defineSYSCTL_PERIPH_GPIOD0x20000008//GPIOD

#defineSYSCTL_PERIPH_GPIOE0x20000010//GPIOE

#defineSYSCTL.PERIPH_GPIOF0x20000020//GPIOF

#defineSYSCTL_PERIPH_GPIOG0x20000040//GPIOG本例中使用

#defineSYSCTL_PERIPH_GPIOH0x20000080//GPIOH

/////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////

////

②第二個函數GPIOPinTyp函n()其實為GPIOPinTypeGPIOInput(),該函數在

gpio.c文件中,其定義為:

VoidGPIOPinTypeGPIOInput(unsignedlongulPort,unsignedcharucPins)

(

ASSERT(GPIOBaseValid(ulPort));//Checkthearguments.

GPIODirModeSet(ulPort,ucPins,GPIO-DIR_MODE_IN);//Makethepin(s)be

inputs.

GPIOPadConfigSet(ulPort,ucPins,GPIO-STRENGTH_2MA,

GPIO-PIN_TYPE_STD);

//Setthepad(s)forstandardpush-pulloperation.

)

調用該函數時傳入的參數為ulPort=GPI0_P0RTG_BASE=0x40026000和

ucPins=GPI0_PIN_5=0x00000020.

第一句有關ASSERT。宏的應用如前所述,不再贅述。

現在來看第二句GPIODirModeSet(ulPort,ucPins,GPI0.DIR一MODEJN);其

中新的參數GPIO-DIR.MODE.IN=0x00000000,該函數的目的是要將GPIOG的第5

個管腳置為輸入。該函數也在gpio.c文件中,其定義為:

VoidGPIODirModeSet(unsignedlongulPort,unsignedcharucPins,unsigned

longulPinlO)

(

ASSERT(GPIOBaseValid(ulPort));

ASSERT((ulPinlO==GPIO_DIR_MODE_IN)II(ulPinlO==GPIO_DIR_MODE_OUT)

II

(ulPinlO==GPIO-DIR.MODE.HW));//Checkthearguments.

HWREG(ulPort+GPIO_O_DIR)=((ulPinlO&1)?

(HWREG(ulPort+GPIO-O-DIR)|ucPins):

(HWREG(ulPort+GPIO_O_DIR)&-(ucPins)));

HWREG(ulPort+GPIO_O_AFSEL)=((ulPinlO&2)?

(HWREG(ulPort+GPIO-O-AFSEL)|ucPins):

(HWREG(ulPort+GPIO_O_AFSEL)&

(ucPins)));//Setthepindirectionandmode.

}

同上,前兩句不再贅述,第三句賦值表達式的左邊為HWREG(ulPort+

GPIO-O-DIR),此處ulPort==GPIO_PORTG_BASE=0x40026000,是GPIOG塊的基

地址,每個塊都有相同的GPIO寄存器,因此可以用BASE+OFFSET的方式尋址各

個塊的寄存器,GPIO_O_DIR=0x00000400,表明GPIO方向寄存器GPIODIR的偏

移量為0x400,因此HWREG(ulPort+GPIO_O_DIR)尋址到了GPIOG的寄存器

GPIODIR,該寄存器是數據方向寄存器,GPIODIR寄存器中設為1的位將相應的

管腳配置成輸出,而設為0的位將相應的管腳配置成輸入,所有位在復位時都會

被清零,即默認情況下所有GPIO管腳都是輸入。賦值號右邊是一個條件表達式,

條件為(ulPinlO&1),ulPinlO為傳入的第三個參數,為0則置為輸入管腳,

為1則置為輸出管腳,此處傳入GPIO_D管腳0DEJN=0x00000000,因此條件為

假,所以會將(HWREG(ulPort+GPIO_O_DIR)&-(ucPins))的值寫入寄存器

GPIODIR,下面分析如何實現,HWREG(ulPort+GPIO_O_DIR)取出GPIODIR的值,

此處的ucPins=GPIO_PIN_5=0x00000020,取反后只有第5位為0,其余位為P

與原值相與后把第5為清0,然后送回寄存器。

第四句與第三句形式一樣,不再詳細分析,只簡單說明其作用,HWREG(ulPort

+GPI0_0-AFSEL)為選中GPI0備用功能選擇(GPIOAFSEL)寄存器,向該寄存器

中的任意位寫“1”表示選擇該GPIO線路所對應的硬件控制(功能)。由于所有

的位都在復位時都會清零,因此在默認的情況下,并無GPI0線被設為硬件控制

(功能)。而參數ulPinlO有三種選擇,如下:

#defineGPIO_DIR_MODE_IN0x00000000//PinisaGPIOinput

#defineGPIO_DIR_MODE_OUT0x00000001//PinisaGPIOoutput

#defineGPIO-DIR-MODE-HW0x00000002//Pinisaperipheralfunction

因此ulPinI0=2時則將GPIOAFSEL寄存器的相應位置1,表示選擇其硬件控制功

能。本例中第5位清0。

③第三個函數為GPIOPinReadO,猜想其功能為讀取某端口某管腳的狀態,該

函數也在gpio.c中,其定義為:

LongGPIOPinRead(unsignedlongulPort,unsignedcharucPins)

(

ASSERT(GPIOBaseValid(ulPort));

return(HWREG(ulPort+(GPIO-O-DATA+(ucPins?2))));//Returnthepin

value(s).

}

其中HWREG(ulPort+(GPIO_O_DATA+(ucPins?2)))這句很重要,體現

了一種利用地址線屏蔽而實現可對任意位操作的機制,將地址總線的位[9:2]用

作屏蔽位,在讀操作過程中,如果與數據位相關聯的地址位被設為1,那么讀取

該值,如果與數據位相關聯的地址位被設為0,那么不管它的實際值是什么,都

將該值讀作0。下面結合本例解釋,將各個參數的值代入為HWREG(0x40026000+

(0x000+(0x00000020?2))),結果為HWREG(0x40026080)。

ADDR[9:2]9876543210

0x0800010000000

GPIODATA76543210

如上表所示,GPIODATA寄存器中除第5位外,其余都被屏蔽,可以只讀出

第5位的狀態。

④第四個函數SysCtlPeriDisable()的原型為void

SysCt1PeripheralDisable(unsignedlongulPeripheral),在sysctl.c文件中,

其定義為:

VoidSysCtlPeripheralDisable(unsignedlongulPeripheral)

ASSERT(SysCtlPeripheralValid(ulPeripheral));

HWREG(g_pu1RCGCRegs[SYSCTL_PERIPH_INDEX(ulPeriphera1)])&=

-SYSCTL_PERIPH_MASK(ulPeripheral);//Disablethisperipheral.

)

其形式和SysCt1PeripheralEnable()相似,不再贅述。

2012CSDN網站六大類職位火熱招聘中!點擊了解英特爾云計算2012年1月當

選微軟MVP的CSDN會員名單揭曉!

一、使用UART庫函數介紹

1,函數:UARTConfigSetExpClk()

功能:UART配置(要求提供明確的時鐘速率)

原型:voidUARTConfigSetExpClk(unsignedlongulBase,unsignedlong

ulUARTClk,

unsignedlongulBaud,unsignedlongulConfig)

參數:ulBase:UART端口的基址,取值UART0一BASE、UART1.BASE或UART2.BASE

ulUARTClk:提供給UART模塊的時鐘速率,即系

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論