標(biāo)題: PXA270處理器ADS編程 嵌入式實(shí)驗(yàn)報(bào)告 [打印本頁(yè)]

作者: 51hei單片    時(shí)間: 2016-3-14 16:44
標(biāo)題: PXA270處理器ADS編程 嵌入式實(shí)驗(yàn)報(bào)告
實(shí)驗(yàn)?zāi)康?/font>
①了解PXA270處理器結(jié)構(gòu)
②了解ARM指令集
③了解嵌入式系統(tǒng)的引導(dǎo)過(guò)程
④了解八段數(shù)碼管的知識(shí)
⑤了解系統(tǒng)的硬件尋址方式
⑥掌握ADS編程和調(diào)試方法
⑦掌握J(rèn)TAG調(diào)試技巧

實(shí)驗(yàn)內(nèi)容
①分析PXA270基本結(jié)構(gòu)
②分析Eeliod實(shí)驗(yàn)平臺(tái)實(shí)現(xiàn)的存儲(chǔ)系統(tǒng)架構(gòu)
③分析PXA270的引導(dǎo)過(guò)程
④分析Eeliod實(shí)驗(yàn)平臺(tái)LED發(fā)光管和7段數(shù)碼管的設(shè)計(jì)原理圖
⑤參考系統(tǒng)引導(dǎo)示例程序完成數(shù)碼管的控制代碼
⑥編譯程序,下載執(zhí)行,讓數(shù)碼管顯示一組特定的數(shù)組

實(shí)驗(yàn)原理
①LED實(shí)驗(yàn)原理
實(shí)驗(yàn)板上的八個(gè)LED的陰極直接與鎖存器74574的輸出端相連,陽(yáng)極通過(guò)限流電阻上拉到+5V,所以鎖存器的輸出直接控制了LED的發(fā)光與否;鎖存器的輸入連接到PXA270的數(shù)據(jù)總線的低八位上,鎖存器的鎖存信號(hào)來(lái)自一塊3-8譯碼器的輸出Y5,所以Y5從低到高的跳變將PXA270數(shù)據(jù)總線第八位數(shù)據(jù)送到鎖存器鎖存住,而3-8譯碼器的輸入的譯碼信號(hào)ABC連接到PXA270地址線的A20、A21和A22上,所以Y5選中需要A22~A20為101b;另外3-8譯碼器的使能控制信號(hào)G2B與PXA270的內(nèi)存空間片選信號(hào)CS4相連,CS4片選的內(nèi)存地址空間為0x1000_0000~0x13FF_FFFF,為簡(jiǎn)單起見,可將設(shè)為0x1000_0000,再加上A22~A20的編碼可得到LED的片選地址為0x1000_0000+0x0050_0000=0x1050_0000,后面只需向該地址寫一個(gè)字節(jié)的數(shù)據(jù)就可以控制LED。
②數(shù)碼管實(shí)驗(yàn)原理
實(shí)驗(yàn)板上有四個(gè)一位共陽(yáng)極八段數(shù)碼管,采用分立的鎖存器單獨(dú)控制。數(shù)碼管的陰極通過(guò)限流電阻直接與鎖存器74574的輸出相連。數(shù)碼管的第八段小數(shù)點(diǎn)沒有使用,相應(yīng)的第八段控制信號(hào)被用來(lái)控制數(shù)碼管的通電與否,通過(guò)一個(gè)PNP的三極管來(lái)控制,鎖存器輸出的Q8腳連接到該三極管的基極,Q8低電平時(shí)三極管導(dǎo)通,數(shù)碼管供電,所以數(shù)碼管正常顯示時(shí)Q8必須為低電平。以上對(duì)于四個(gè)數(shù)碼管通用。對(duì)于第一二個(gè)數(shù)碼管,它們相連的鎖存器的輸入數(shù)據(jù)信號(hào)分別為PXA270數(shù)據(jù)信號(hào)的D0~D7和D8~D15,兩個(gè)鎖存器的片選信號(hào)都接到LED實(shí)驗(yàn)原理中提到的3-8譯碼器的Y3上,同LED實(shí)驗(yàn)原理中的地址計(jì)算方法,可得數(shù)碼管1和2的地址為0x1000_0000+0x0030_0000=0x1030_0000,后面控制數(shù)碼管1和2時(shí)只需要向這個(gè)地址寫半個(gè)字(16位)的數(shù)據(jù)即可,其中數(shù)據(jù)的低八位對(duì)應(yīng)第一個(gè)數(shù)碼管,高八位對(duì)應(yīng)第二個(gè)數(shù)碼管(注意需要將每個(gè)八位的最高位置0來(lái)打開數(shù)碼管的供電)。數(shù)碼管3和4的控制跟1和2的控制類似,只不過(guò)將地址改為0x1000_0000+0x0040_0000=0x1040_0000即可。

實(shí)驗(yàn)步驟
第一步 分析代碼
結(jié)合以上說(shuō)明,對(duì)本實(shí)驗(yàn)提供的示例代碼分析,深入理解針對(duì)具體的硬件實(shí)現(xiàn),軟件是如何配合工作的。
第二步 程序的編譯和下載
利用ADS打開示例工程文件,執(zhí)行Project→Make,編譯、鏈接生成可執(zhí)行映像文件
第三步 觀察系統(tǒng)運(yùn)行情況,對(duì)系統(tǒng)進(jìn)行源碼調(diào)試

程序說(shuō)明
①LED控制
通過(guò)對(duì)LED的地址直接寫入數(shù)據(jù)即可完成對(duì)LED的控制,在高級(jí)語(yǔ)言中一般無(wú)法直接完成對(duì)內(nèi)存指定地址的操作,但在C語(yǔ)言中可以利用指針來(lái)完成該操作。同時(shí)由于PXA270內(nèi)部帶有高速緩存Cache,所以需要用關(guān)鍵字volatile來(lái)限定該指針使得每次對(duì)指針的操作都直接操作到內(nèi)存,而不通過(guò)Cache。
②數(shù)碼管控制
數(shù)碼管基本控制原理與LED控制相同,只是地址換成數(shù)碼管的地址。實(shí)驗(yàn)板上共有4個(gè)數(shù)碼管,4個(gè)數(shù)碼管分成兩組,每組用一個(gè)地址;在一組內(nèi),用16位二進(jìn)制(半字)來(lái)控制兩個(gè)數(shù)碼管;注意要使數(shù)碼管正常工作,每個(gè)該半字的第8位和第16位必須為0來(lái)控制三極管打開使得數(shù)碼管通電。

程序源代碼、注釋
①LED代碼
  1. //LED地址
  2. #define LED_VALUE                (*((volatile unsigned char *)(0x10500000)))

  3. //位定義
  4. #define BITNULL        (0x00<<0)
  5. #define BIT0                (0x01<<0)
  6. #define BIT1                (0x01<<1)
  7. #define BIT2                 (0x01<<2)
  8. #define BIT3                (0x01<<3)
  9. #define BIT4                (0x01<<4)
  10. #define BIT5                (0x01<<5)
  11. #define BIT6                (0x01<<6)
  12. #define BIT7                (0x01<<7)

  13. //粗略延時(shí)函數(shù)
  14. void Delay(unsigned int x)
  15. {
  16.         unsigned int n, j, k;
  17.         for (n =0; n <=x; n++)
  18.                 for (j = 0; j <0xff; j++)
  19.                         for (k = 0; k <0xff; k++);
  20. }

  21. int main(void)
  22. {       
  23.         int i;
  24.         //流水花樣查找表,這里是邏輯層0表示不顯示,1表示顯示,與硬件無(wú)關(guān)
  25.         unsigned char LUT[] =
  26.         {
  27.                 BIT0 + BIT7,
  28.                 BIT1 + BIT6,
  29.                 BIT2 + BIT5,
  30.                 BIT3 + BIT4,
  31.                 BIT2 + BIT5,
  32.                 BIT1 + BIT6,
  33.                 BIT0 + BIT7,
  34.                 BITNULL,
  35.         };

  36.         while (1)
  37.         {       
  38.                 LED_VALUE = 0xff;
  39.                
  40.                 for (i = 0; i < 8; i++)
  41.                 {
  42. //這里是電氣層,由于LED是共陽(yáng)極,所以這里需要取反
  43.                         LED_VALUE = ~LUT[i];
  44. Delay(200);
  45.                 }
  46.         }
  47.        
  48.         return 0;
  49. }

  50. ②數(shù)碼管代碼
  51. 1)SegLed.h文件
  52. #ifndef __SEGLED_H__
  53. #define __SEGLED_H__

  54. #define SEG_NULL        ('9' + 1)

  55. //顯示數(shù)字函數(shù)的控制參數(shù)
  56. enum
  57. {
  58.         DISP_NORMAL = 0,
  59.         DISP_BLANKING
  60. };

  61. extern signed char SegLedDispAt(unsigned char, signed char);
  62. extern signed char SegLedDispNum(short, unsigned char);

  63. #endif

  64. 2)SegLed.c文件
  65. #include "SegLed.h"

  66. //第一組和第二組數(shù)碼管的地址
  67. #define SEGLED0                (*((volatile unsigned short int *)(0x10300000)))
  68. #define SEGLED1                (*((volatile unsigned short int *)(0x10400000)))

  69. //數(shù)碼管上各個(gè)段對(duì)應(yīng)一個(gè)字節(jié)中的某個(gè)位的宏定義
  70. #define        SEGA        (0x01<<0u)
  71. #define        SEGB        (0x01<<1u)
  72. #define        SEGC        (0x01<<2u)
  73. #define        SEGD        (0x01<<3u)
  74. #define        SEGE        (0x01<<4u)
  75. #define        SEGF        (0x01<<5u)
  76. #define        SEGG        (0x01<<6u)
  77. #define        SEGH        (0x01<<7u)

  78. //數(shù)碼管顯示不顯示以及顯示0~9宏定義,這里只是邏輯層的定義,具體還需根據(jù)數(shù)碼管是共的什么極來(lái)確定需不需要取反
  79. #define DIGNULL        (SEGH)
  80. #define DIG0                (SEGA + SEGB + SEGC + SEGD + SEGE + SEGF + SEGH)
  81. #define DIG1                (SEGB + SEGC + SEGH)
  82. #define DIG2                (SEGA + SEGB + SEGD + SEGE + SEGG + SEGH)
  83. #define DIG3                (SEGA + SEGB + SEGC + SEGD + SEGG + SEGH)
  84. #define DIG4                (SEGB + SEGC + SEGF + SEGG + SEGH)
  85. #define DIG5                (SEGA + SEGC + SEGD + SEGF + SEGG + SEGH)
  86. #define DIG6                (SEGA + SEGC + SEGD + SEGE + SEGF + SEGG + SEGH)
  87. #define DIG7                (SEGA + SEGB + SEGC + SEGH)
  88. #define DIG8                (SEGA + SEGB + SEGC + SEGD + SEGE + SEGF + SEGG + SEGH)
  89. #define DIG9                (SEGA + SEGB + SEGC + SEGD + SEGF + SEGG + SEGH)


  90. unsigned short segBuff0, segBuff1;        //定義數(shù)碼管的"顯示緩沖"


  91. /*
  92.         名    稱:SegLedDispAt()
  93.         功    能:在四個(gè)數(shù)碼管的指定位置顯示指定的字符
  94.         入口參數(shù):ch:需要顯示的字符的ASCII值,目前支持的字符僅限于數(shù)字0~9(即'0' <= ch <= '9')和空字符SEGNULL
  95.                           pos:顯示的字符位于哪個(gè)數(shù)碼管,0 <= pos <= 3 分別表示第一到第四個(gè)數(shù)碼管
  96.         出口參數(shù):正確執(zhí)行返回0,否則返回-1
  97.         說(shuō)    明:本函數(shù)是對(duì)于底層數(shù)碼管的硬件抽象,所有上層驅(qū)動(dòng)都調(diào)用此函數(shù)完成各種顯示功能,一般情況下用戶程序
  98.                           不需要調(diào)用此函數(shù)。確實(shí)需要調(diào)用此函數(shù)時(shí),注意第一個(gè)參數(shù)是ASCII值,不是數(shù)字,而是數(shù)字對(duì)應(yīng)的ASCII
  99.         使用范例:SegLedDispAt('6', 0); 在第一個(gè)數(shù)碼管上顯示數(shù)字6
  100. */
  101. signed char SegLedDispAt(unsigned char ch, signed char pos)
  102. {
  103.         unsigned char tempDisp;
  104.         const unsigned char segLUT[] = {DIG0, DIG1, DIG2, DIG3, DIG4, DIG5, DIG6, DIG7, DIG8, DIG9, DIGNULL};
  105.         if((pos < 0) || (pos > 3))
  106.                 return -1;
  107.        
  108.         tempDisp = ~segLUT[ch - '0'];        //數(shù)碼管共陽(yáng)極的需要在這里取反,注意共陰極的除了不需要取反還要修改空顯示的宏定義
  109.                
  110.         switch(pos)
  111.         {
  112.                 case 0: segBuff0 = ((segBuff0 & 0xFF00) | tempDisp);break;
  113.                 case 1: segBuff0 = ((segBuff0 & 0x00FF) | tempDisp << 8);break;
  114.                 case 2: segBuff1 = ((segBuff1 & 0xFF00) | tempDisp);break;
  115.                 case 3: segBuff1 = ((segBuff1 & 0x00FF) | tempDisp << 8);break;
  116.                 default:break;
  117.         }
  118.        
  119.         SEGLED0 = segBuff0;
  120.         SEGLED1 = segBuff1;
  121.        
  122.         return 0;
  123. }

  124. /*
  125.         名    稱:SegLedDispNum()
  126.         功    能:在四個(gè)數(shù)碼管上顯示0~4位正整數(shù)
  127.         入口參數(shù):num:需要顯示的正整數(shù),范圍0~9999
  128.                           argv:顯示控制參數(shù),目前可選賦值為DISP_NORMAL和DISP_BLANKING支持普通顯示(不夠四位時(shí)前面補(bǔ)零)
  129.                           和消隱顯示(不夠四位時(shí)右對(duì)齊,前面不足處不顯示)
  130.         出口參數(shù):正確執(zhí)行返回0,否則返回-1
  131.         說(shuō)    明:無(wú)
  132.         使用范例:SegLedDispNum(666, DISP_BLANKING); 在數(shù)碼管上顯示666,右對(duì)齊,第一個(gè)數(shù)碼管不顯示
  133. */
  134. signed char SegLedDispNum(short num, unsigned char argv)
  135. {
  136.         unsigned char numLen = 0;
  137.         signed char i;
  138.         short tempNum;
  139.        
  140.        
  141.         if(num < 0 || num > 9999)
  142.                 return -1;
  143.        
  144.         switch(argv)
  145.         {
  146.                 case DISP_NORMAL:
  147.                 {
  148.                         for(i = 3; i != -1; i--)
  149.                         {
  150.                                 SegLedDispAt(num % 10 + '0', i);
  151.                                 num /= 10;
  152.                         }
  153.                         break;
  154.                 }
  155.                
  156.                 case DISP_BLANKING:
  157.                 {
  158.                         numLen = 1;
  159.                         for(tempNum = num; tempNum /= 10; numLen++);        //計(jì)算數(shù)字長(zhǎng)度,供消隱使用
  160.                        
  161.                         for(i = 3; i != 3 - numLen; i--)
  162.                         {
  163.                                 SegLedDispAt(num % 10 + '0', i);        //從個(gè)位開始一直顯示到消隱前一位
  164.                                 num /= 10;
  165.                         }
  166.                        
  167.                         for(; i != -1; i--)
  168.                         {
  169.                                 SegLedDispAt(SEG_NULL, i);        //對(duì)剩下的前面幾位消隱(寫空)
  170.                         }
  171.                         break;
  172.                 }
  173.                 default:
  174.                         break;
  175.         }
  176.        
  177.         return 0;
  178. }
復(fù)制代碼


總結(jié)
ADS集成開發(fā)環(huán)境的編譯器不支持在函數(shù)外對(duì)全局變量進(jìn)行初始化,在LED實(shí)驗(yàn)時(shí),定義了一個(gè)全局的查找表,通過(guò)查找表控制LED的顯示花樣,但是在運(yùn)行時(shí)發(fā)現(xiàn)LED的顯示始終不對(duì),后來(lái)在單步調(diào)試的時(shí)候發(fā)現(xiàn)全局變量那個(gè)查找表的內(nèi)容根本不對(duì),后來(lái)在函數(shù)內(nèi)部定義了一個(gè)查找表,問(wèn)題解決。







歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1