<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

標簽 > AT91RM9200

AT91RM9200

+關注 0人關注

AT91RM9200-QU是一種微處理器,數據總線寬度是32 bit,而本專題詳細記載了AT91RM9200開發調試手記,并且在設計路徑、電路結構設計等都有詳細的說明,對工程師開發AT91RM9200設計有很大的幫助。

文章: 18
瀏覽: 14796
帖子: 8

AT91RM9200簡介

 自己的AT91RM9200的板子已經調試了一段時間了,從開始動手制作PCB到現在,差不多有半年的時間了。在這期間一直忙著查資料,畫板布線,聯系制板廠家,聯系購買器件(呵呵,大小活全包),一直沒有時間寫寫總結之類的東西,另外平時也沒有養成隨時總結的好習慣。以前搞硬件基本上是以8位的51單片機為主,偶爾也用用PC104,AVR之類的控制器,其他16位、32位的控制器從沒用過,對其感覺甚為神秘。因此在做這塊板子之前,自己查閱了很多資料(網上資料為主,資源豐富,比較方便),在做了各種權衡利弊之后(做方案,選芯片是比較令人頭疼的事情,有過系統設計經歷的朋友可能有這種體會),最后才痛下決心,決定選用atmel的AT91RM9200做為控制芯片。因為在此之前從來沒有搞過32位的東東,所以當時心里一點底都沒有。

AT91RM9200百科

  AT91RM9200-QU是一種微處理器,數據總線寬度是32 bit。

  基本信息

  程序存儲器類型: ROM

  程序存儲器大?。?128 KB

  數據 RAM 大?。?16 KB

  接口類型: EBI or MCI or MII or SPI or TWI

  最大時鐘頻率: 180 MHz

  可編程輸入/輸出端數量: 122

  定時器數量: 6

  工作電源電壓: 3 V ~ 3.6 V

  工作溫度: -40°C ~ 85°C

  封裝: PQFP-208

  AT91RM9200開發調試手記

  自己的AT91RM9200的板子已經調試了一段時間了,從開始動手制作PCB到現在,差不多有半年的時間了。在這期間一直忙著查資料,畫板布線,聯系制板廠家,聯系購買器件(呵呵,大小活全包),一直沒有時間寫寫總結之類的東西,另外平時也沒有養成隨時總結的好習慣。以前搞硬件基本上是以8位的51單片機為主,偶爾也用用PC104,AVR之類的控制器,其他16位、32位的控制器從沒用過,對其感覺甚為神秘。因此在做這塊板子之前,自己查閱了很多資料(網上資料為主,資源豐富,比較方便),在做了各種權衡利弊之后(做方案,選芯片是比較令人頭疼的事情,有過系統設計經歷的朋友可能有這種體會),最后才痛下決心,決定選用atmel的AT91RM9200做為控制芯片。因為在此之前從來沒有搞過32位的東東,所以當時心里一點底都沒有。

  1. 制訂方案

  選定AT91RM9200之后,接下來就是圍繞它設計外圍電路了。因為我做的這個東西應用場合比較特殊:野外應用,因此在設計方案的時候盡量選用工業級的芯片。第一次用這款控制器,設計電路的時候最好的參考就是由atmel官方提供的開發板:AT91RM9200DK。但是這塊板上的網絡PHY部分采用的是DM9161E,查資料發現這個PHY非工業級產品,后來決定把它換成intel的LXT971A。另外我的應用中還需要一個網絡接口,在非PCI接口的網絡控制芯片中選來選去,最后決定用SMSC公司的LAN91C111I-NE,也是一款工業級別的芯片(網上資料反映其功耗較大,power hungry,但其他工業級的片子當時沒有查到,繆辦法呀)。其他的電路基本上都是參考AT91RM9200DK的原理圖設計的,除了復位電路采用了阻容電路(開發板上那個復位芯片國內很難買得到)。

  2. 畫圖制板

  方案確定之后接下來就是畫原理圖,布線,制板了。之前一直都用protel,在網上查閱資料的時候發現了有關allegro和mentor公司的相關產品,當時聽說是比較牛的軟件,比protel強多了,當時就有了放棄protel的想法(先不說功能,光是速度就讓我很郁悶,可能是因為以前的機器比較破的關系吧)。那學什么新軟件呢?當時在一個ftp上發現了allegro以及相關的一本書(臺灣出的那本),而mentor的沒找到多少相關資料。OK,就allegro了。全新的開始。

  因為用了allegro的原因,從畫原理圖到最后畫完PCB,前后將近2個月的時間。有關allegro的應用,以后有時間再寫個總結吧,我當時也是現學現賣。PCB畫完之后,因為制板工藝的原因,頗費一般周折之后才把板子交出去(拿到深圳做的,很羨慕在深圳工作的朋友,買器件制板都很方便)。一周之后,終于拿到了樣板。做工看上去蠻不錯,比在本地做的強多了。

  3.焊接檢查

  板子做完了,器件也買好了,下面就要焊接調試了。當時心里是比較緊張的,因為我做的PCB是雙面板,當時網上有朋友告訴我說雙面板可能會不穩定(9200能跑到200MHz),另外對自己的布線水平也沒信心(我對自己的定位是:啥都會,啥都不精)。板子上除了一個按鍵和幾個接插件,全部都是表貼。本地有專門提供焊接服務的,找到他們之后,2個小時半塊板子搞定(為什么是半塊?因為有一部分件沒有買齊,就是那個LAN91C111I-NE)。板子焊接完之后拿回來,在上電測試之前,按照我以前的習慣,先用萬用表量了一下板子的電源和地。這一量不要緊,驚出我一身冷汗:短路!心情一下子就#??!#@!#@!,怎么搞的嘛!沒別的辦法,檢查吧。首先確定是不是焊接的原因導致的,樣板一共做了10塊,拿另外一塊空板量了一下,暈倒!也是短路!

  板子上到處是電源和地,怎么檢查呢?我心里知道這種錯誤最難檢查了,要命的是我的板子已經焊接好了,要是萬一短路的地方在表貼件的下面,那豈不是太殘酷了?我心里一邊暗自禱告,一邊找來一塊板做我的犧牲品,各位可能知道我下一步要做什么了,嘿嘿,從電源輸入的地方開始,逐條把分支割斷。一共割了6刀,終于找到了短路的地方(其中有一處是憑俺肉眼瞅出來的)。短路原因是鋪的銅跟電源線太近而短路(這其中有加工方面的因素,另一方面也是因為我設置的間距太小了,0.3mm,以后還是用1mm好了)。又在焊接好的板子上割了兩刀,萬用表一測,OK!這次是運氣好,以后在焊接之前可要好好測試板子有沒有問題了。

  上面的短路故障是因為加工的原因導致的。后來又焊接了一塊板,也出現了短路的問題,是復位線和地線短路,與上面不同的是,這次短路是因為焊接導致的。所以在焊接前后一定要檢查。這兩次都算我運氣好,沒有出現燒毀芯片的問題。雖然是比較低級的錯誤,但有時卻是致命的。

  4.初步調試

  確定板子沒有問題之后(至少自己感覺是這樣),下一步就是檢查板子工作是否正常了。根據手頭掌握的資料,9200從片內啟動之后,會通過DEBGUG串口向外發送‘CCCCC‘字符(至于這個C字符代表什么含義,接下來會有描述)。OK,先從這里入手。首先啟動超級終端,參數設置為115200,8,no,1,no;

  將調試串口連到PC串口,給板子上電。

  超級終端無反應,按復位鍵,濤聲依舊!

  再檢查原理圖。首先看復位,暈倒,竟然沒有把復位電路里面用的7404焊上!斷電,找來烙鐵,我焊!

  再上電,超級終端還是沒有反應,又狂按復位鍵,還是沒反應。

  當時心情真是郁悶到了極點!檢查了一下調試串口的接口芯片,應該沒有問題。又仔細檢查了一下電路圖,先從串口部分看起,突然發現調試串口的2,3腳連接順序跟手頭的開發板不一樣,又仔細檢查了一下用的串口連接線(別的開發板上的),原來是直連的,而并非交叉線,還好,手頭有9針的串口接插頭,馬上作了一個轉接的。

  連接好以后,再上電,終于在超級終端上看到了久違的CCCCCCCCCC.。。。。。。

  OK,下面可以用U-BOOT和arm-linux來測試了。

  5. U-BOOT移植篇

  確定板子可以工作之后,接下來的工作就是把U-BOOT移植到我的板子上。因為有AT91RM9200DK板移植好的例子,所以移植工作要相對容易一些。在移植之前,我先用AT91RM9200DK板子上的U-BOOT做了一下測試,因為當時還沒有仔細研究U-BOOT的結構,而現在對U-BOOT也不是很了解,只能說是皮毛而已,等以后研究明白了再寫一些有關U-BOOT的文字。首先把現成的U-BOOT下載到我的板子上:

  A. 將串口連接好,打開超級終端,串口參數設置為115200,8,none, 1, none。

  B. 接通板子電源,超級終端出現“CCCCC”。

  C. 在超級終端中選擇菜單 transfer=》send file, 傳送協議選擇xmodem或者1K xmodem,傳送文件選擇loader.bin,文件傳送完畢后超級終端出現以下提示:

  loader 1.0 (Aug 8 2003 - 12:01:07)

  XMODEM: Download U-BOOT

  然后繼續顯示“CCCC”

  D. 在超級終端中選擇菜單 transfer=》send file, 傳送協議選擇xmodem或者1K xmodem,傳送文件選擇u-boot.bin,文件傳送完畢后超級終端出現u-boot提示符: U-BOOT》

  E. 由于我的板子上的PHY接口芯片由DM9161E換成了LXT971A,因此此時在U-BOOT中網絡接口是不能使用的,這給下載linux內核測試帶來了麻煩。但為了進一步確定板子可以正常工作,我還是用U-BOOT中的串口下載命令loadb將linux內核和ramdisk下載到了板子上:

  U-BOOT》 loadb 21000000 uImage

  U-BOOT》 loadb 21100000 ramdisk-rmk7

  U-BOOT》 setenv bootargs root=/dev/ram rw initrd=0x21100000,6000000 ramdisk_size=15360 console=ttyS0,115200 mem=32M

  U-BOOT》 bootm 21000000

  整個過程用了一個多小時,呵呵,太慢了。下載后linux可以啟動,基本上應該沒有問題了。下面的首要任務就是修改U-BOOT代碼,讓其支持LXT971A,要不然下載linux太費時間了。

  6. U-BOOT移植初步

  經過上述準備工作之后,基本上確定硬件沒有問題,下一步首要的任務就是要把板子上的以太網調通,以方便以后的下載調試工作。

  6.1 準備工作

  在移植之前,我手頭已經有一個Atmel官方提供的U-BOOT源代碼,但不是最新的版本。 因此我首先到U-BOOT的站點下載了最新的版本(sourceforge.net/projects/u-boot), 當時的最新版本是1.1.2 。 另外還需要一個交叉編譯器。 當時手頭上有arm-linux-gcc-2.95.3版本, 后來又從handhelds.org下載了3.3.2的版本。 版本并不是越高越好,因為存在兼容性的問題。 后來在用3.3.2版本編譯atmel提供的linux-2.4.19的時候,就出現了一堆錯誤,但改成2.95.3后就沒有問題了。

  *****小插曲******

  在做移植準備的過程中還出現了一個小小的插曲。 因為在此之前的硬件測試工作都是在windows環境下用超級終端進行的。而交叉編譯需要linux環境(當然在windows下用cygwin也可以,但兼容性不是很好),因此就需要一個linux環境下的“超級終端”,我對linux并不熟悉,從網上查了一些資料,決定用minicom. 自己經過摸索,可以操縱minicom了,但是在用xmodem協議向板上下載程序的時候遇到問題: 總是提示錯誤,下載無法進行。 急忙到google上面搜索相關資料,結果發現這是一個共性的問題,很多朋友都反映xmodem下載協議有問題, 據說是時序上的原因。 怎么辦呢? 最初從網上當了一些有關xmodem的資料以及一些源代碼, 后來決定自己編寫一個xmodem下載的程序。 下面就做一個小小的總結。

  A. xmodem協議簡介

  XMODEM協議是一種使用撥號調制解調器的個人計算機通信中廣泛使用的異步文件運輸協議。這種協議以128字節塊的形式傳輸數據,并且每個塊都使用一個校驗和過程來進行錯誤檢測。如果接收方關于一個塊的校驗和與它在發送方的校驗和相同時,接收方就向發送方發送一個認可字節。然而,這種對每個塊都進行認可的策略將導致低性能,特別是具有很長傳播延遲的衛星連接的情況時,問題更加嚴重。

  使用循環冗余校驗的與XMODEM相應的一種協議稱為XMODEM-CRC。還有一種是XMODEM-1K,它以1024字節一塊來傳輸數據。ZMODEM是最有效的一個XMODEM版本,它不需要對每個塊都進行認可。事實上,它只是簡單地要求對損壞的塊進行重發。ZMODEM對按塊收費的分組交換網絡是非常有用的。不需要認可回送分組在很大程度上減少了通信量。YMODEM也是一種XMODEM的實現。它包括XMODEM-1K的所有特征,另外在一次單一會話期間為發送一組文件,增加了批處理文件傳輸模式。

  有不少產品的維護和軟件升級都是采用XMODEM協議來進行的。

  B.xmodem協議的數據包格式

  首先看幾個定義: SOH---》 0x01 STX---》0x02 ACK---》0x06 NAK---》0x15 EOT---》0x04 CRC--》 ‘C’ 其中SOH代表一個數據包的開始標志,而STX與SOH有相同的含義,不過它是用在1K-XMODEM協議中的。 ACK是確認標志,NAK是非確認標志(要求重發),EOT是傳送結束標志,CRC是使用CRC校驗標志。一個完整數據包的格式如下:

  《SOH》 《數據包長度》 《255-數據包長度》 《128字節數據》 《校驗字》

  在1K-XMODEM協議中,數據長度由128字節提高到1K字節。

  在XMODEM協議中,對數據包進行校驗的方式有兩種,一種是采用校驗和,另一種是CRC校驗。那么收發雙方如何確認對方的校驗方式呢?

  C.傳輸建立過程

  在早期采用校驗和的XMODEM協議中,接收方準備就緒之后,會間隔一段時間發送“NAK”信號,每發送一個NAK,接收方就等待一段時間并檢查是否收到SOH信號,若接收到則開始數據傳送; 而發送方接收到NAK信號之后,便認為接收方已經準備好并開始數據傳送,這樣一個數據傳輸過程就建立起來了。在這種方式下采用的是校驗和的方式。

  在采用CRC校驗的XMODEM協議中,為了保持兼容性,接收方若支持CRC校驗,間隔發送的不是NAK而是CRC標志,也就是‘C’,看到這里大家可能明白了AT91RM9200片內啟動之后,為什么向外發送‘CCC’而不是其他的字符。 發送方接收到CRC標志之后,若支持CRC校驗方式,便開始數據的傳輸,否則不做任何響應。 若接收方兩種校驗方式都支持的話(取決于程序編寫),若對方不支持CRC,它就會轉到校驗和方式。

  D.數據傳輸過程

  下面是一個采用CRC校驗方式進行數據傳遞的過程示意圖:

  發送方 接收方

  《----------------------------------------------------- ‘C’

  《SOH》 《01》 《fe》 《128字節》 《CRC高字節》 《CRC低字節》 ------------》

  《------------------------------------------------------ 《ACK》

  《SOH》 《02》 《fd》 《128字節》 《CRC高字節》 《CRC低字節》 -------------》

  《----------------------------------------------------- 《NAK》

  《SOH》 《02》 《fd》 《128字節》 《CRC高字節》 《CRC低字節》 -------------》

  《------------------------------------------------------ 《ACK》

  。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

  《EOT》 -----------------------------------------------------------》

  《------------------------------------------------------《NAK》

  《EOT》 -----------------------------------------------------------》

  《------------------------------------------------------《ACK》

  傳送結束

  E. 程序編寫

  有了上面的了解,就可以編寫利用XMODEM協議進行數據傳送的程序了。 這里面涉及到linux下的串口編程,還有就是16位CRC校驗的生成。下面把我寫的源程序給出,供大家參考,程序在RedHat9.0下編譯測試通過。

  /***A simple program using xmodem/1kxmode send file*/

  #include 《stdio.h》

  #include 《stdlib.h》

  #include 《unistd.h》

  #include 《sys/types.h》

  #include 《sys/stat.h》

  #include 《fcntl.h》

  #include 《termios.h》

  #include 《errno.h》

  /*

  Xmodem Frame form: 《SOH》《blk #》《255-blk #》《--128 data bytes--》《CRC hi》《CRC lo》

  */

  #define XMODEM_SOH 0x01

  #define XMODEM_STX 0x02

  #define XMODEM_EOT 0x04

  #define XMODEM_ACK 0x06

  #define XMODEM_NAK 0x15

  #define XMODEM_CRC_CHR ‘C’

  #define XMODEM_CRC_SIZE 2 /* Crc_High Byte + Crc_Low Byte */

  #define XMODEM_FRAME_ID_SIZE 2 /* Frame_Id + 255-Frame_Id */

  #define XMODEM_DATA_SIZE_SOH 128 /* for Xmodem protocol */

  #define XMODEM_DATA_SIZE_STX 1024 /* for 1K xmodem protocol */

  #define USE_1K_XMODEM 0 /* 1 for use 1k_xmodem 0 for xmodem */

  #if (USE_1K_XMODEM)

  #define XMODEM_DATA_SIZE XMODEM_DATA_SIZE_STX

  #define XMODEM_HEAD XMODEM_STX

  #else

  #define XMODEM_DATA_SIZE XMODEM_DATA_SIZE_SOH

  #define XMODEM_HEAD XMODEM_SOH

  #endif

  /*********/

  #define SERIAL_DEVICE “/dev/ttyS0”

  #define BAUDRATE B115200;

  /***************SUB PROGRAM*******/

  unsigned short GetCrc16 ( char *ptr, unsigned short count )

  {

  unsigned short crc, i;

  crc = 0;

  while(count--)

  {

  crc = crc ^ (int) *ptr++ 《《 8;

  for(i = 0; i 《 8; i++)

  {

  if (crc & 0x8000)

  crc = crc 《《 1 ^ 0x1021;

  else

  crc = crc 《《 1;

  }

  }

  return (crc & 0xFFFF);

  }

  /*******************************/

  int Initial_SerialPort(void)

  {

  int fd;

  struct termios options;

  fd = open( SERIAL_DEVICE , O_RDWR &line; O_NOCTTY &line; O_NDELAY );

  if ( fd == -1 )

  {

  /*open error!*/

  perror(“port can‘t open!”);

  return -1;

  }

  /*Get the current options for the port.。.*/

  tcgetattr(fd, &options);

  /*Set the baud rates to BAUDRATE.。.*/

  cfsetispeed(&options, BAUDRATE);

  cfsetospeed(&options, BAUDRATE);

  tcsetattr(fd, TCSANOW, &options);

  if (0!= tcgetattr(fd, &options))

  {

  perror(“SetupSerial 1”);

  return -1;

  }

  /*

  * 8bit Data,no partity,1 stop bit.。。

  */

  options.c_cflag &= ~PARENB;

  options.c_cflag &= ~CSTOPB;

  options.c_cflag &= ~CSIZE;

  options.c_cflag &line;= CS8;

  tcflush(fd,TCIFLUSH);

  /***Choosing Raw Input*/

  options.c_lflag &= ~(ICANON &line; ECHO &line; ECHOE &line; ISIG);

  options.c_oflag &= ~OPOST;

  /*

  * Set the new options for the port.。。

  */

  if(0!=tcsetattr(fd, TCSANOW, &options))

  {

  perror(“SetupSerial error”);

  return -1 ;

  }

  return fd ;

  }

  //******************************

  void ClearReceiveBuffer(int fd)

  {

  unsigned char tmp;

  while((read(fd,&tmp,1))》0);

  return;

  }

  //********************************

  int main(int argc,char *argv[])

  {

  int fd;

  char data_file_name[80];

  char packet_data[ XMODEM_DATA_SIZE ];

  char frame_data[ XMODEM_DATA_SIZE + XMODEM_CRC_SIZE + XMODEM_FRAME_ID_SIZE + 1 ];

  unsigned char tmp;

  FILE *datafile;

  int complete,retry_num,pack_counter,read_number,write_number,i;

  unsigned short crc_value;

  unsigned char ack_id;

  //**open serial port1

  if ( (fd = Initial_SerialPort()) == -1) return -1 ;

  data_file_name = argv[1];

  if ((datafile=fopen(data_file_name,“rb”))==NULL)

  {

  perror(“file can’t open!”);

  return -1 ;

  }

  //*******************************

  pack_counter = 0;

  complete = 0;

  retry_num = 0;

  ClearReceiveBuffer(fd);

  while((read(fd,&ack_id,1))《=0);

  printf(“%c ”,ack_id);

  ack_id = XMODEM_ACK;

  while(!complete)

  {

  switch(ack_id)

  {

  case XMODEM_ACK:

  retry_num = 0;

  pack_counter++;

  read_number = fread( packet_data, sizeof(char), XMODEM_DATA_SIZE, datafile);

  if(read_number》0)

  {

  if (read_number《XMODEM_DATA_SIZE_SOH)

  {

  printf(“Start filling the last frame! ”);

  for(;read_number《XMODEM_DATA_SIZE;read_number++)

  packet_data[read_number] = 0x00;

  }

  frame_data[0] = XMODEM_HEAD;

  frame_data[1] = (char)pack_counter;

  frame_data[2] = (char)(255-frame_data[1]);

  for(i=0;i《XMODEM_DATA_SIZE;i++)

  frame_data[i+3]=packet_data[i];

  crc_value = GetCrc16(packet_data,XMODEM_DATA_SIZE);

  frame_data[XMODEM_DATA_SIZE_SOH+3]=(unsigned char)(crc_value 》》 8);

  frame_data[XMODEM_DATA_SIZE_SOH+4]=(unsigned char)(crc_value);

  write_number = write( fd, frame_data, XMODEM_DATA_SIZE_SOH + 5);

  printf(“waiting for ACK,%d,%d,。。。”,pack_counter,write_number);

  while((read(fd,&ack_id,1))《=0);

  if(ack_id == XMODEM_ACK)

  printf(“Ok! ”);

  else

  printf(“Error! ”);

  break;

  }

  else

  {

  ack_id = XMODEM_EOT;

  complete = 1;

  printf(“Waiting for complete ACK 。。。”);

  while(ack_id != XMODEM_ACK) ;

  {

  ack_id = XMODEM_EOT;

  write_number=write(fd,&ack_id,1);

  while((read(fd,&ack_id,1))《=0);

  }

  printf(“ok! ”);

  printf(“Sending file complete! ”);

  break;

  }

  case XMODEM_NAK:

  if( retry_num++ 》 10)

  {

  printf(“Retry too many times,Quit! ”);

  complete = 1;

  break;

  }

  write_num = write(fd,frame_data,XMODEM_DATA_SIZE + 5);

  printf(“Retry for ACK,%d,%d.。。”,pack_counter,write_number);

  while((read(fd,&ack_id,1))《=0);

  if( ack_id == XMODEM_ACK )

  printf(“Ok! ”);

  else

  printf(“Error! ”);

  break;

  default:

  printf(“Fatal Error! ”);

  complete = 1;

  break;

  }

  }

  fclose(datafile);

  close(fd);

  return 0;

  }

  7. U-BOOT移植之LXT971篇

  移植和測試都是在linux下進行的(Redhat 9.0)。 首先將以前下載的U-BOOT-1.1.2源代碼解壓到/usr/local/u-boot-1.1.2, arm-linux-gcc-3.3.2解壓到/usr/local/arm/3.3.2, 設置好路徑:

  export PATH=/usr/local/arm/3.3.2/bin:$PATH ( 告訴系統去哪里找 arm-linux- )

  打開u-boot-1.1.2下面的readme文件, 根據里面的提示, 要將U-BOOT移植到一個新板上,需要做以下改動:

  A. 修改根目錄下的Makefile以及MAKEFILE文件,向其中增加對你要新添加的板子的支持。 因為有AT91RM9200DK項做參考,所以這一步并不困難;

  B. 在/board下面新建一個目錄,里面包含你要增加的板子的信息。 我給我的板起名為at91rm9200my(呵呵,不夠響亮), 那么我要做的就是在/board下新建一個at91rm9200my的目錄, 根據readme里面的提示, 至少要包含這幾個文件: Makefile , at91rm9200my.c, flash.c 和 u-boot.lds, 有at91rm9200DK做參考,這一步也不困難。 (拷貝過來就OK了,我還沒有根據我的板子做修改)

  C. 在 /include/configs/ 下面建一個新板的配置文件, 我的是 at91rm9200my.h, 至于里面的內容,當然是參考at91rm9200dk.h了。

  D. 做完上面這些, 下面就是要做LXT971A的工作了。 at91rm9200dk上用的是DM9161E, 在/board/at91rm9200dk里面我找到了dm9161.c 這個文件, 那么我需要做的就是要改動這個文件了。 另外在Makefile里面我還看到了這么一行: OBJS := at91rm9200dk.o at45.o dm9161.o flash.o 我想這兩個文件是需要我改動的了。首先把dm9161.c文件另存為lxt971a.c, 把Makefile里面的那行改為:

  OBJS := at91rm9200dk.o at45.o lxt971a.o flash.o

  根據我的了解,DM9161是RMII接口,LXT971A是MII接口,而對PHY的控制是通過MDI來進行的,在DM9161.C里面,主要有這么幾個函數:

  dm9161_IsPhyConnected()

  dm9161_GetLinkSpeed()

  dm9161_InitPhy()

  dm9161_AutoNegotiate()

  at91rm92000_GetPhyInterface()

  除了最后一個外,前四個函數都是通過at91rm9200提供的MDI接口對PHY進行控制,那么我要做的工作就是根據LXT971A的手冊對這個函數改寫。 DM9161與LXT971A內部的寄存器地址大部分都是相同的,只有少數幾個的地址和位定義不同,改寫比較容易。 下面是我改寫完的 lxt971a.c :

  #include 《at91rm9200_net.h》

  #include 《net.h》

  #include 《lxt971a.h》 /***這個頭文件u-boot源文件里面有***/

  #ifdef CONFIG_DRIVER_ETHER

  #if (CONFIG_COMMANDS & CFG_CMD_NET)

  static unsigned int lxt971a_IsPhyConnected (AT91PS_EMAC p_mac)

  {

  unsigned short Id1, Id2;

  at91rm9200_EmacEnableMDIO (p_mac);

  at91rm9200_EmacReadPhy (p_mac, PHY_COMMON_ID1, &Id1);

  at91rm9200_EmacReadPhy (p_mac, PHY_COMMON_ID2, &Id2);

  at91rm9200_EmacDisableMDIO (p_mac);

  if ((Id1 == PHY_LXT971A))

  return TRUE;

  return FALSE;

  }

  static UCHAR lxt971a_GetLinkSpeed (AT91PS_EMAC p_mac)

  {

  unsigned short stat1, stat2;

  if (!at91rm9200_EmacReadPhy (p_mac, PHY_COMMON_STAT, &stat1))

  return FALSE;

  if (?。╯tat1 & PHY_COMMON_STAT_LNK_STAT)) /* link status up? */

  return FALSE;

  if (!at91rm9200_EmacReadPhy (p_mac, PHY_LXT971_STAT2, &stat2))

  return FALSE;

  if ((stat1 & PHY_COMMON_STAT_100BXFD) && (stat2 & PHY_LXT971_STAT2_100BTX) && (stat2 & PHY_LXT971_STAT2_DUPLEX_MODE)) {

  /*set Emac for 100BaseTX and Full Duplex */

  p_mac-》EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD;

  return TRUE;

  }

  if ((stat1 & PHY_COMMON_STAT_10BTFD) && ?。╯tat2 & PHY_LXT971_STAT2_100BTX) && (stat2 & PHY_LXT971_STAT2_DUPLEX_MODE)) {

  /*set MII for 10BaseT and Full Duplex */

  p_mac-》EMAC_CFG = (p_mac-》EMAC_CFG &

  ~(AT91C_EMAC_SPD | AT91C_EMAC_FD))

  | AT91C_EMAC_FD;

  return TRUE;

  }

  if ((stat1 & PHY_COMMON_STAT_100BXHD) && (stat2 & PHY_LXT971_STAT2_100BTX) && ?。╯tat2 & PHY_LXT971_STAT2_DUPLEX_MODE)) {

  /*set MII for 100BaseTX and Half Duplex */

  p_mac-》EMAC_CFG = (p_mac-》EMAC_CFG &

  ~(AT91C_EMAC_SPD | AT91C_EMAC_FD))

  | AT91C_EMAC_SPD;

  return TRUE;

  }

  if ((stat1 & PHY_COMMON_STAT_10BTHD) && ?。╯tat2 & PHY_LXT971_STAT2_100BTX) && ?。╯tat2 & PHY_LXT971_STAT2_DUPLEX_MODE)) {

  /*set MII for 10BaseT and Half Duplex */

  p_mac-》EMAC_CFG &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);

  return TRUE;

  }

  return FALSE;

  }

  static UCHAR lxt971a_InitPhy (AT91PS_EMAC p_mac)

  {

  UCHAR ret = TRUE;

  unsigned short IntValue;

  at91rm9200_EmacEnableMDIO (p_mac);

  if (!lxt971a_GetLinkSpeed (p_mac)) {

  /* Try another time */

  ret = lxt971a_GetLinkSpeed (p_mac);

  }

  /* Disable PHY Interrupts */

  at91rm9200_EmacReadPhy (p_mac, PHY_LXT971_INT_ENABLE, &IntValue);

  /* clear FDX, SPD, Link, INTR masks */

  IntValue &= ~(PHY_LXT971_INT_ENABLE_DUPLEXMSK | PHY_LXT971_INT_ENABLE_SPEEDMSK |

  PHY_LXT971_INT_ENABLE_LINKMSK | PHY_LXT971_INT_ENABLE_TINT);

  at91rm9200_EmacWritePhy (p_mac, PHY_LXT971_INT_ENABLE, &IntValue);

  at91rm9200_EmacDisableMDIO (p_mac);

  return (ret);

  }

  static UCHAR lxt971a_AutoNegotiate (AT91PS_EMAC p_mac, int *status)

  {

  unsigned short value;

  unsigned short PhyAnar;

  unsigned short PhyAnalpar;

  /* Set lxt971a control register */

  if (!at91rm9200_EmacReadPhy (p_mac, PHY_COMMON_CTRL, &value))

  return FALSE;

  value &= ~PHY_COMMON_CTRL_AUTO_NEG; /* remove autonegotiation enable */

  value |= PHY_COMMON_CTRL_ISOLATE; /* Electrically isolate PHY */

  if (!at91rm9200_EmacWritePhy (p_mac, PHY_COMMON_CTRL, &value))

  return FALSE;

  /* Set the Auto_negotiation Advertisement Register */

  /* MII advertising for Next page, 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3 */

  PhyAnar = PHY_COMMON_AUTO_ADV_NP | PHY_COMMON_AUTO_ADV_100BTXFD | PHY_COMMON_AUTO_ADV_100BTX |

  PHY_COMMON_AUTO_ADV_10BTFD | PHY_COMMON_AUTO_ADV_10BT | PHY_COMMON_AUTO_ADV_802_3;

  if (!at91rm9200_EmacWritePhy (p_mac, PHY_COMMON_AUTO_ADV, &PhyAnar))

  return FALSE;

  /* Read the Control Register */

  if (!at91rm9200_EmacReadPhy (p_mac, PHY_COMMON_CTRL, &value))

  return FALSE;

  value |= PHY_COMMON_CTRL_SPD_100 | PHY_COMMON_CTRL_AUTO_NEG | PHY_COMMON_CTRL_DUPLEX;

  if (!at91rm9200_EmacWritePhy (p_mac, PHY_COMMON_CTRL, &value))

  return FALSE;

  /* Restart Auto_negotiation */

  value |= PHY_COMMON_CTRL_RES_AUTO;

  if (!at91rm9200_EmacWritePhy (p_mac, PHY_COMMON_CTRL, &value))

  return FALSE;

  /*check AutoNegotiate complete */

  udelay (30000);

  at91rm9200_EmacReadPhy (p_mac, PHY_COMMON_STAT, &value);

  if (?。╲alue & PHY_COMMON_STAT_AN_COMP))

  return FALSE;

  /* Get the AutoNeg Link partner base page */

  if (!at91rm9200_EmacReadPhy (p_mac, PHY_COMMON_AUTO_LNKB, &PhyAnalpar))

  return FALSE;

  if ((PhyAnar & PHY_COMMON_AUTO_ADV_100BTXFD) && (PhyAnalpar & PHY_COMMON_AUTO_LNKB_100BTXFD)) {

  /*set MII for 100BaseTX and Full Duplex */

  p_mac-》EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD;

  return TRUE;

  }

  if ((PhyAnar & PHY_COMMON_AUTO_ADV_10BTFD) && (PhyAnalpar & PHY_COMMON_AUTO_LNKB_10BTFD)) {

  /*set MII for 10BaseT and Full Duplex */

  p_mac-》EMAC_CFG = (p_mac-》EMAC_CFG &

  ~(AT91C_EMAC_SPD | AT91C_EMAC_FD))

  | AT91C_EMAC_FD;

  return TRUE;

  }

  return FALSE;

  }

  /*

  * Name:

  * at91rm92000_GetPhyInterface

  * Description:

  * Initialise the interface functions to the PHY

  * Arguments:

  * None

  * Return value:

  * None

  */

  void at91rm92000_GetPhyInterface(AT91PS_PhyOps p_phyops)

  {

  p_phyops-》Init = lxt971a_InitPhy;

  p_phyops-》IsPhyConnected = lxt971a_IsPhyConnected;

  p_phyops-》GetLinkSpeed = lxt971a_GetLinkSpeed;

  p_phyops-》AutoNegotiate = lxt971a_AutoNegotiate;

  }

  #endif /* CONFIG_COMMANDS & CFG_CMD_NET */

  #endif /* CONFIG_DRIVER_ETHER */

  8. 關于板子的配制文件

  改寫完網絡部分以后,我將U-BOOT用arm-linux-gcc-3.3.2做了編譯:

  $ make mrproper

  $ make at91rm9200my_config

  $ make all

  將生成的u-boot.bin下載到我的板子上,結果發現網絡部分還是不能用。 仔細考慮了一下可能出問題的幾個地方:

  A. 硬件問題? 網線插上之后LAX971A的三個狀態指示都正常,應該不是PHY問題, 又想會不會是自己做的板子的問題(2層板,100M的網卡速度比較高), 后來又否定了自己的想法, 不應該一點反應都沒有,因為U-BOOT沒有提示MII方面的錯誤, 如果是板子布線方面的問題的話, 應該是出現不穩定現象。

  B. 軟件問題? 后來想如果真的是板子的原因,那可真是慘了,因為網卡是必須要用的。 因此我決定先從軟件方面找原因。 既然LXT971和DM9161接口方式不同(一個是MII,一個是RMII),那么在U-BOOT中應該有這方面的設置選項,在什么地方呢? 首先想到的就是移植板子的時候在/include/configs/下面添加的配制文件 at91rm9200my.h, 這個文件我是從at91rm9200dk復制過來的,里面有這么一個與RMII接口有關的配制項 #define CONFIG_AT91C_USE_RMII, 當時我是把它改成了#define CONFIG_AT91C_USE_RMII 0, 會不會是這里的問題呢? 那么這個選項影響哪個文件呢? 因為在dm9161.c里面沒有發現與這個定義有關的語句, 后來用sourceinsight( 閱讀源代碼的好工具哦) 在/cpu/at91rm9200/下面找到了這個文件: at91rm9200_eth.c 在這個文件里面有個函數 eth_init() 是用來對MAC進行初始化的, 應該就是它了,很快就找到了與RMII相關的那條語句:

  #if defined(CONFIG_AT91C_USE_RMII) && !defined(CONFIG_CMC_PU2)

  *AT91C_PIOB_PDR = AT91C_PB25_EF100 |

  AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV |

  AT91C_PB16_ERX3 | AT91C_PB15_ERX2 | AT91C_PB14_ETXER |

  AT91C_PB13_ETX3 | AT91C_PB12_ETX2;

  而其上面的語句是:

  *AT91C_PIOA_PDR = AT91C_PA16_EMDIO | AT91C_PA15_EMDC | AT91C_PA14_ERXER |

  AT91C_PA13_ERX1 | AT91C_PA12_ERX0 | AT91C_PA11_ECRS_ECRSDV |

  AT91C_PA10_ETX1 | AT91C_PA9_ETX0 | AT91C_PA8_ETXEN |

  AT91C_PA7_ETXCK_EREFCK;

  這兩段語句都是與設置PIO有關的,也就是將PIO設置成MAC的工作方式, 通過分析可以看出第二段是RMII和MII都需要進行的,而第一段是根據CONFIG_AT91C_USE_RMII是否定義來判斷的,而不是我最初理解的將CONFIG_AT91C_USE_RMII定義為0就可以了(呵呵,比較菜) , 重新對at91rm9200my.h做修改,將

  #define CONFIG_AT91C_USE_RMII 改成 #undef CONFIG_AT91C_USE_RMII

  然后重新編譯,下載, OK, 板上的網口終于起來了。

  另外在用U-BOOT提供的tftp下載linux內核和根文件系統的時候,還遇到一個問題,就是在linux下, tftp服務默認設置是不自動啟動的,所以要修改/etc/xinet.d/ 下面的tftp配制文件,將里面的 disable = yes 改為 no或者把這一行注釋掉。 另外還有一個問題,就是記得把linux的防火墻(我用的是redhat9.0)關掉,要不然也無法用tftp下載。 詳細的下載過程后面接著說。

  9. linux內核移植

  對U-BOOT 做了簡單的修改,使其網絡部分可以使用之后,接下來就是讓linux也能認出我的PHY來。

  9.1 內核修改

  我用的內核源文件是atmel提供的linux-2.4.19-rmk7, 在對源文件做修改之前, 首先編譯試驗了一下,結果發現用arm-linux-gcc-3.3.2編譯有問題(U-BOOT是用3.3.2編譯的),沒辦法,又把2.95.3裝上,再試,沒有問題。

  接下來就是要確定要修改哪些文件了。 linux內核源文件的層次還是比較清楚的,我很快在/drivers/at91/net/下面找到了at91_ether.h 和 at91_ether.c 這兩個個文件, 把這兩個文件打開看了一些, 覺得這就是我要找的。 在at91_ether.h里面找到了這么幾行定義:

  #define MII_DM9161_ID 0x0181b880 /*****PHY的ID***/

  #define MII_DSCSR_REG 17 /***PHY的內部寄存器地址***/

  #define MII_DSINTR_REG 21 /****PHY的內部寄存器地址***/

  根據前面在修改U-BOOT的時候的得到的信息, 這三個定義是與LXT971A不同的,根據LXT971A的手冊, 做了以下修改,增加了下面幾行定義:

  #define MII_LXT971A_ID 0x001378e0 /****對應MII_DM9161_ID

  #define MII_LXT971_INT_ENABLE 0x12 /***對應MII_DSCSR_REG

  #define MII_LXT971_INT_STATUS 0x13 /***對應MII_DSINTR_REG

  然后對 at91_ether.c 里面的PHY管理部分做相應修改如下:

  static int update_linkspeed(struct net_device *dev, AT91PS_EMAC regs) {

  unsigned int bmsr, bmcr, lpa, mac_cfg;

  unsigned int speed, duplex;

  /* Link status is latched, so read twice to get current value */

  read_phy(regs, MII_BMSR, &bmsr);

  read_phy(regs, MII_BMSR, &bmsr);

  if (?。╞msr & BMSR_LSTATUS)) return -1; /* no link */

  read_phy(regs, MII_BMCR, &bmcr);

  if (bmcr & BMCR_ANENABLE) { /* AutoNegotiation is enabled */

  if (?。╞msr & BMSR_ANEGCOMPLETE)) return -2; /* auto-negotitation in progress */

  read_phy(regs, MII_LPA, &lpa);

  if ((lpa & LPA_100FULL) || (lpa & LPA_100HALF)) speed = SPEED_100;

  else speed = SPEED_10;

  if ((lpa & LPA_100FULL) || (lpa & LPA_10FULL)) duplex = DUPLEX_FULL;

  else duplex = DUPLEX_HALF;

  } else {

  speed = (bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10;

  duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF;

  }

  /* Update the MAC */

  mac_cfg = regs-》EMAC_CFG & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);

  if (speed == SPEED_100) {

  if (duplex == DUPLEX_FULL) /* 100 Full Duplex */

  regs-》EMAC_CFG = mac_cfg | AT91C_EMAC_SPD | AT91C_EMAC_FD;

  else /* 100 Half Duplex */

  regs-》EMAC_CFG = mac_cfg | AT91C_EMAC_SPD;

  } else {

  if (duplex == DUPLEX_FULL) /* 10 Full Duplex */

  regs-》EMAC_CFG = mac_cfg | AT91C_EMAC_FD;

  else /* 10 Half Duplex */

  regs-》EMAC_CFG = mac_cfg;

  }

  printk(KERN_INFO “%s: Link now %i-%s ”, dev-》name, speed, (duplex == DUPLEX_FULL) ? “FullDuplex” : “HalfDuplex”);

  return 0;

  }

  /*

  * Handle interrupts from the PHY

  */

  void at91ether_phy_interrupt(int irq, void *dev_id, struct pt_regs *regs)

  {

  struct net_device *dev = (struct net_device *) dev_id;

  AT91PS_EMAC emac = (AT91PS_EMAC) dev-》base_addr;

  int status;

  unsigned int phy;

  enable_mdi(emac);

  read_phy(emac, MII_LXT971_INT_STATUS, &phy); /* acknowledge interrupt in PHY */

  status = AT91_SYS-》PIOC_ISR; /* acknowledge interrupt in PIO */

  status = update_linkspeed(dev, emac);

  if (status == -1) { /* link is down */

  netif_carrier_off(dev);

  printk(KERN_INFO “%s: Link down. ”, dev-》name);

  } else if (status == -2) { /* auto-negotiation in progress */

  /* Do nothing - another interrupt generated when negotiation complete */

  } else { /* link is operational */

  netif_carrier_on(dev);

  }

  disable_mdi(emac);

  }

  /*

  * Initialize and enable the PHY interrupt when link-state changes

  */

  void enable_phyirq(struct net_device *dev, AT91PS_EMAC regs)

  {

  struct at91_private *lp = (struct at91_private *) dev-》priv;

  unsigned int dsintr, status;

  static int first_init = 0;

  if (first_init == 0) {

  // TODO: Check error code. Really need a generic PIO (interrupt)

  // layer since we‘re really only interested in the PC4 line.

 ?。╲oid) request_irq(4, at91ether_phy_interrupt, 0, dev-》name, dev);

  /* AT91_SYS-》PIOC_ODR = AT91C_PIO_PC4; Configure as input */

  AT91_SYS-》PIOC_ODR = AT91C_PIO_PB29;

  first_init = 1;

  }

  else {

  status = AT91_SYS-》PIOC_ISR; /* clear any pending PIO interrupts */

  AT91_SYS-》PIOC_IER = AT91C_PIO_PB29; /* Enable interrupt */

  spin_lock_irq(&lp-》lock);

  enable_mdi(regs);

  read_phy(regs, MII_LXT971_INT_ENABLE, &dsintr);

  dsintr = dsintr | 0x00f2; /* set bits 7..4 and 1 */

  write_phy(regs, MII_LXT971_INT_ENABLE, dsintr);

  disable_mdi(regs);

  spin_unlock_irq(&lp-》lock);

  }

  }

  /*

  * Disable the PHY interrupt

  */

  void disable_phyirq(struct net_device *dev, AT91PS_EMAC regs)

  {

  struct at91_private *lp = (struct at91_private *) dev-》priv;

  unsigned int dsintr;

  spin_lock_irq(&lp-》lock);

  enable_mdi(regs);

  read_phy(regs, MII_LXT971_INT_ENABLE, &dsintr);

  dsintr = dsintr & 0x00f2; /* clear bits 8..11 */

  write_phy(regs, MII_LXT971_INT_ENABLE, dsintr);

  disable_mdi(regs);

  spin_unlock_irq(&lp-》lock);

  AT91_SYS-》PIOC_IDR = AT91C_PIO_PB29; /* Disable interrupt */

  }

  int at91ether_probe(struct net_device *dev)

  {

  AT91PS_EMAC regs = (AT91PS_EMAC) AT91C_VA_BASE_EMAC;

  unsigned int phyid1, phyid2;

  int detected = -1;

  /* Configure the hardware - RMII vs MII mode */

  #ifdef CONFIG_AT91_ETHER_RMII

  AT91_CfgPIO_EMAC_RMII();

  #else

  AT91_CfgPIO_EMAC_MII();

  #endif

  AT91_SYS-》PMC_PCER = 1 《《 AT91C_ID_EMAC; /* Enable Peripheral clock */

  /* Read the PHY ID registers */

  enable_mdi(regs);

  read_phy(regs, MII_PHYSID1, &phyid1);

  read_phy(regs, MII_PHYSID2, &phyid2);

  disable_mdi(regs);

  if (((phyid1 《《 16) | (phyid2 & 0xfff0)) == MII_LXT971A_ID) {

  detected = at91ether_setup(dev);

  }

  AT91_SYS-》PMC_PCDR = 1 《《 AT91C_ID_EMAC; /* Disable Peripheral clock */

  return detected;

  }

  另外,是否使用RMII接口在/include/config/at91/ether下面的rmii.h中定義

  #define CONFIG_AT91_ETHER_RMII 1 將其改為

  #undef CONFIG_AT91_ETHER_RMII

  做完上述修改之后,就可以進行編譯了。

  9.2 內核的編譯下載和執行

  內核編譯過程如下:

  $ make at91rm9200dk_config

  $ make oldconfig

  如果想調整內核, $ make menuconfig

  $ make bzImage

  編譯完后在/arch/arm/boot下生成映像文件。 如果想生成供U-BOOT下載使用的uImage文件, 接著執行:

  $ /usr/local/arm/2.95.3/bin/arm-linux-objcopy -O binary -S vmlinux linux.bin

  $ gzip -v9 linux.bin

  $ mkimage -A arm -O linux -C gzip -a 0x20008000 -e 0x20008000 -d linux.bin.gz uImage

  生成uImage以后,就可以用U-BOOT來下載并啟動linux內核了,過程如下:(假設U-BOOT已經運行)

  在linux主機下將uImage和ramdisk-rmk7拷貝到/tftpboot下

  U-BOOT》 setenv ethaddr 00:11:22:33:44:55:66

  U-BOOT》 setenv ipaddr 10.10.155.200

  U-BOOT》 setenv serverip 10.10.155.211

  U-BOOT》 tftp 21000000 uImage

  U-BOOT》 tftp 21100000 ramdisk-rmk7

  U-BOOT》 setenv bootargs root=/dev/ram rw initrd=0x21100000,6000000 ramdisk_size=15360 console=ttyS0,115200 mem=32M

  U-BOOT》 bootm 21000000

  如果沒有問題,就會看到linux的啟動信息.linux內核啟動之后, 用root (無密碼) 登錄。 如果想使用網絡,還需要進行一些配置,例如:

 ?。踨oot@AT91RM9200DK /root]$ ifconfig eth0 down

 ?。踨oot@AT91RM9200DK /root]$ ifconfig eth0 10.10.155.2 up

  另外,默認情況下是不可以更改9200的MAC地址的,如果想更改,在編譯內核的時候,需要修改相應的頭文件。

  花了兩天的時間對前面的調試工作做了總結, 雖然這其中的很多東西對我來說都是第一次, 但總的來說過程還算順利, 雖然遇到了不少的問題, 但都得到了比較好的解決, 在這里特別感謝網絡上不知名的朋友們的幫助。 到現在為止, 工作才剛剛開始, 軟件方面還有大量的工作需要去做, 希望自己能延續自己在前一段時間的好運氣, 盡快將軟件寫完調通。 這也是我第一次使用linux, 第一次接觸開源軟件, 雖然以前也用C,但是接觸了linux,讀了其他優秀的源代碼,突然感覺以前自己的寫的C是多么的native, 多么的缺乏組織,呵呵。 就先寫這么多了,以后有時間再寫吧。

查看詳情

at91rm9200技術

基于AT91RM9200芯片的串口服務器功能設計

基于AT91RM9200芯片的串口服務器功能設計

串口服務器是一種通信協議轉換器,它設有兩類通信端口:一類是標準的RS232/422/485格式的串行端口,遠程的RTU(遠程終端設備)監控模塊通過串行控...

2019-09-25 標簽:USB接口RS232接口AT91RM9200 1510 0

基于AT91RM9200 處理器系統中BootLoader與內核的參數傳遞

基于AT91RM9200 處理器系統中BootLoader與內核的參數傳遞

本文著重介BootLoader與內核之間 參數傳遞 這一基本功能。本文的硬件平臺是基于AT91RM9200 處理器系統,軟件平臺是Linux-2.6.1...

2018-03-28 標簽:內核at91rm9200bootLoader 1782 0

AT91RM9200的UBOOT啟動燒寫過程詳解

不同廠商的出的Soc片子在啟動方式大都提供片內和片外啟動兩種方式,一般都是在片內固化一段小程序方便于程序開發而已。

2018-06-18 標簽:at91rm9200uboot 5528 0

基于ARM芯片AT91RM9200的無線打印模塊的硬件平臺設計

基于ARM芯片AT91RM9200的無線打印模塊的硬件平臺設計

在ARM芯片AT91RM9200上構建了 無線打印模塊 的硬件平臺,在Android操作系統上完成了軟件平臺的搭建,通過調用Linux內核的CUPS,實...

2018-02-07 標簽:armat91rm9200 1585 0

基于AT91RM9200系統電源的設計與調試

基于AT91RM9200系統電源的設計與調試

隨著計算機技術、半導體技術以及電子技術的發展,嵌入式系統以其體積小、可靠性高、功耗低、軟硬件集成度高等特點廣泛應用于工業制造、過程控制、通信、儀器、儀表...

2014-08-28 標簽:AT91RM9200系統電源 1700 0

基于ARM9的多行列鍵盤設計及其驅動實現

基于ARM9的多行列鍵盤設計及其驅動實現

論文展示了一種在ARM等嵌入式設備上擴展特殊鍵盤的新設計方法,并以運行ARM-Linux操作系統的AT91RM9200系統為例,對鍵盤接口電路設計和鍵盤...

2012-05-29 標簽:鍵盤AT91RM9200驅動程序 1949 0

查看更多>>

at91rm9200資訊

基于ARM平臺的RFID系統設計與實現

本文提出了一種基于ARM 平臺的RFID 系統設計與實現方案,以滿足人們在嵌入式領域對RFID技術的開發與應用。

2012-11-14 標簽:ARMRFIDAT91RM9200 1655 0

基于ARM9的車載GPS定位終端設計

基于ARM9的車載GPS定位終端設計

車載GPS定位終端在過去十年內已經成為汽車工業發展的焦點。在歐美國家和日本,車載GPS定位終端在最近幾年內得以廣泛的應用。車載GPS定位終端是融全球衛星...

2011-10-27 標簽:GPSARM9AT91RM9200 2400 0

基于ARM的新型智能交通信號燈系統設計

本文提出了一種具有分布式特征的交通信號燈控制系統設計方案,它利用RFID技術提高路況信息的收集精度, 利用電流環遠距離傳輸方式,并且應用人工智能理論使得...

2011-10-19 標簽:ARMAT91RM9200交通信號燈 4736 0

多串口通訊協議轉換案例

隨著網絡經濟時代的到來,基于TCP/IP協議的IP網的應用得到廣泛普及,利用網絡資源可以實現設備的網絡接入,設備聯網監控已經成為工業自動化的發展趨勢。

2011-10-11 標簽:IP網絡AT91RM9200多串口協議 1568 0

基于ARM9的音頻系統設計

基于ARM9的音頻系統設計

本文利用 ATMEL公司 的 AT91RM9200型微處理器 和 Philips公司的 UDA1341型立體聲音頻編解碼器設計了一種嵌入式音頻系統。該嵌...

2011-09-19 標簽:音頻ARM9AT91RM9200 1905 0

基于AT91RM9200的嵌入式ARM開發平臺的設計

基于AT91RM9200的嵌入式ARM開發平臺的設計

嵌入式系統是以應用為中心,以計算機技術為基礎,軟硬件可以裁剪來適應系統對功能、可靠性、成本、體積、功耗要求嚴格的專用計算機體系。隨著各種微處理器功能的完...

2011-09-16 標簽:ARM嵌入式AT91RM9200 1155 0

基于ARM9處理器AT91RM9200和MCP25lO的CA

基于ARM9處理器AT91RM9200和MCP25lO的CA

 隨著現場總線技術高速發展和標準化程度的不斷提高,以現場總線技術為基礎的開放型集散測控系統得到廣泛應用??偩€是控制器局域網(controller are...

2010-08-18 標簽:ARM9at91rm9200AT91R 2100 0

VxWorks移植到AT91RM9200的BSP定制過程

VxWorks移植到AT91RM9200的BSP定制過程

VxWorks是美國Wind River公司開發的嵌入式實時操作系統,具有高性能、可裁減性好等特點,能支持多種微處理器(如PowerPC、X85

2010-07-29 標簽:ATVxWorksat91rm9200 1582 0

AT91RM9200設計的保數據采集方案

1、  應用背景     環保信息網絡承載著環保信息監測預警服務,為了保障環保數據的不間斷采集

2010-07-22 標簽:ARMat91rm9200AT91RM 842 0

AT91RM9200的導航計算機測試儀設計

AT91RM9200的導航計算機測試儀設計

AT91RM9200的導航計算機測試儀設計 0 概述導航計算機是捷聯組合導航組件的組成部件,可接收來自多路輸入數據接口的數據,并將結果由輸出...

2010-04-01 標簽:AT91RM9200 924 0

查看更多>>

at91rm9200數據手冊

相關標簽

相關話題

換一批
  • AMS1117
    AMS1117
    +關注
    AMS1117系列穩壓器有可調版與多種固定電壓版,設計用于提供1A輸出電流且工作壓差可低至1V。在最大輸出電流時,AMS1117器件的最小壓差保證不超過1.3V,并隨負載電流的減小而逐漸降低。
  • 電機控制芯片
    電機控制芯片
    +關注
  • MSP430G2553
    MSP430G2553
    +關注
    德州儀器(TI)MSP430系列超低功耗微控制器包含多種器件,它們特有面向多種應用的不同外設集。這種架構與5種低功耗模式相組合,專為在便攜式測量應用中延長電池使用壽命而優化。該器件具有一個強大的16位 RISCCPU,16位寄存器和有助于獲得最大編碼效率的常數發生器。
  • 24c02
    24c02
    +關注
  • nRF51822
    nRF51822
    +關注
  • 反向電壓
    反向電壓
    +關注
    反向電壓是什么意思?反向電壓怎么產生的?我們這邊為大家分享一下正向電壓和反向電壓的區別;光電效應反向電壓;解讀最大反向電壓怎么求?二極管最高反向工作電壓?最高反向工作電壓的計算公式等知識點。
  • MPU-6050
    MPU-6050
    +關注
    MPU-6000(6050)為全球首例整合性6軸運動處理組件,相較于多組件方案,免除了組合陀螺儀與加速器時間軸之差的問題,減少了大量的封裝空間。
  • eV1527
    eV1527
    +關注
  • 電芯
    電芯
    +關注
  • 74hc245
    74hc245
    +關注
    總線收發器,典型的CMOS型三態緩沖門電路,八路信號收發器,。由于單片機或CPU的數據/地址/控制總線端口都有一定的負載能力,如果負載超過其負載能力,一般應加驅動器。
  • 基準電壓
    基準電壓
    +關注
      基準電壓是指傳感器置于0℃的溫場(冰水混合物),在通以工作電流(100μA)的條件下,傳感器上的電壓值。實際上就是0點電壓。其表示符號為V(0),該值出廠時標定,由于傳感器的溫度系數S相同,則只要知道基準電壓值V(0),即可求知任何溫度點上的傳感器電壓值,而不必對傳感器進行分度。
  • IN4007
    IN4007
    +關注
  • ad623
    ad623
    +關注
  • max3232
    max3232
    +關注
    MAX3232 器件由兩個線路驅動器、兩個線路接收器和一個雙路電荷泵電路組成,具有端子間(串行端口連接端子,包括 GND)±15kV ESD 保護。
  • 半橋驅動芯片
    半橋驅動芯片
    +關注
  • cnn
    cnn
    +關注
  • 74HC138
    74HC138
    +關注
  • ISD1820
    ISD1820
    +關注
  • MLX90615
    MLX90615
    +關注
  • EG8010
    EG8010
    +關注
  • DA轉換器
    DA轉換器
    +關注
    DA轉換器一般指數模轉換器。它是把數字量轉變成模擬的器件。D/A轉換器基本上由4個部分組成,即權電阻網絡、運算放大器、基準電源和模擬開關。模數轉換器中一般都要用到數模轉換器,模數轉換器即A/D轉換器,簡稱ADC,它是把連續的模擬信號轉變為離散的數字信號的器件。
  • TTP223
    TTP223
    +關注
    TTP223是觸摸鍵檢測IC,提供1個觸摸鍵。觸摸檢測IC是為了用可變面積的鍵取代傳統的按鈕鍵而設計的。低功耗和寬工作電壓是觸摸鍵的DC和AC特點。111
  • 1N4148
    1N4148
    +關注
  • lm741
    lm741
    +關注
  • max485
    max485
    +關注
    MAX485是一個八引腳的RS485電平收發器(只能單工或半雙工)。內部含有一個輸入信號接收器R、一個輸出信號驅動器D。
  • PCB元件
    PCB元件
    +關注
  • 6n137
    6n137
    +關注
  • DK112
    DK112
    +關注
  • l7805
    l7805
    +關注
  • SM7525
    SM7525
    +關注

關注此標簽的用戶(1人)

118114

編輯推薦廠商產品技術軟件/工具OS/語言教程專題

亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>