<strike id="tpvd9"><dfn id="tpvd9"></dfn></strike>

        <em id="tpvd9"></em>

          <address id="tpvd9"></address>
            <dfn id="tpvd9"><sub id="tpvd9"></sub></dfn>

            <thead id="tpvd9"><noframes id="tpvd9">
            <ruby id="tpvd9"></ruby>

                  <thead id="tpvd9"></thead>
                  歡迎您訪(fǎng)問(wèn)鄭州興邦電子股份有限公司官方網(wǎng)站!
                  阿里巴巴誠信通企業(yè)
                  全國咨詢(xún)熱線(xiàn):40000-63966
                  興邦電子,中國水控機第一品牌

                  聯(lián)系興邦電子

                  全國咨詢(xún)熱線(xiàn):40000-63966

                  售后:0371-55132951/55132952

                  工廠(chǎng):河南省 鄭州市 高新區蓮花街電子電器產(chǎn)業(yè)園

                  用DSP的GPIO管腳實(shí)現與IC卡通信

                  文章出處:http://psychicreadingswithdeb.com 作者:北京郵電大學(xué) 張彬&nbsp;&nbsp; 人氣: 發(fā)表時(shí)間:2011年11月03日

                  [文章內容簡(jiǎn)介]:用DSP的GPIO管腳實(shí)現與IC卡通信

                   IC卡可以分為接觸式的和非接觸式(射頻卡),本文主要討論存儲卡和智能卡(CPU卡)這兩種接觸式IC卡的結構特點(diǎn)和讀寫(xiě)操作,詳細敘述如何使用DSP的GPIO(通用輸入輸出)管腳實(shí)現與各種IC卡進(jìn)行通信,并給出了DSP函數實(shí)現。

                    常見(jiàn)與IC卡連接的都是基于單片機的系統,但是某些應用要求IC卡讀寫(xiě)終端具有較強的實(shí)時(shí)運算和控制能力,這時(shí)DSP就是最好的選擇。以TI公司的C5409為例,它的8根HPI管腳(HD0~HD7)可以配置成GPIO使用,配置方法是在復位時(shí)將HPI16管腳置高或者HPIENA管腳置低,這樣就可以通過(guò)配置DSP內部GPIOCR和GPIOSR兩個(gè)寄存器來(lái)控制這8根GPIO管腳的輸出和輸入。GPIOCR寄存器的低8位用來(lái)控制每個(gè)GPIO管腳的方向,若管腳為輸出則對應位設為“1”,若為輸入則設為“0”(DSP復位后GPIOCR缺省值為“0”,即GPIO管腳默認為輸入)。GPIOSR寄存器的低8位用來(lái)控制每個(gè)GPIO管腳的值,若為輸出,向對應位寫(xiě)“1”,則該管腳輸出高,寫(xiě)“0”則該管腳輸出低;若為輸入,則對應位的值為管腳上輸入的值,向其寫(xiě)操作無(wú)效。

                  下面給出了控制GPIO的函數(控制低兩位GPIO管腳,即HD0和HD1):
                  #define gpio_dir *(short *)0x3c
                  #define gpio_val *(short *)0x3d //定義兩個(gè)寄存器的地址
                  void gpio_setval(short i,short j) //設置GPIO的輸出
                  {
                  if(i==0) //控制HD0管腳
                  gpio_val=gpio_val&0xfffe; //設為0
                  else if(i==1)
                  gpio_val=gpio_val|0x0001; //設為1
                  if(j==0) //控制HD1管腳
                  gpio_val=gpio_val&0xfffd;
                  else if(j==1)
                  gpio_val=gpio_val|0x0002;
                  wait();
                  }
                  void gpio_setdir(short i) //控制GPIO的方向
                  {
                  if(i==1)
                  gpio_dir=gpio_dir|0x0001; //設為輸出
                  else if(i==0)
                  gpio_dir=gpio_dir&0xfffe; //設為輸入
                  }
                  short gpio_getval(short i) //讀入GPIO的值
                  {
                  short j;
                  if(i==0) j=gpio_val&0x0001;
                  else if(i==1) j=(gpio_val&0x0002)>>1;
                  return j;
                  }

                  常見(jiàn)的接觸式IC卡可以分為存儲卡和智能卡(又叫作CPU卡),下面分別介紹DSP如何與這兩種卡進(jìn)行連接通信。

                  DSP和存儲卡的連接

                  存儲卡只具有簡(jiǎn)單存儲功能,實(shí)際上是一片串行EEPROM的IC卡模式,以Atmel公司的AT24C16SC為例,它實(shí)質(zhì)上就是兩線(xiàn)串行EEPROM AT24C16,兩者接口時(shí)序基本一樣。存儲卡的管腳如圖1所示。AT24C16SC同時(shí)支持3V和5V,訪(fǎng)問(wèn)速度分別可以達到100Kbps(3V)和400Kbps(5V);內部容量為16Kb,分為128頁(yè),每頁(yè)16字節;雙向數據線(xiàn)(SDA)為OD(Open-Drain)驅動(dòng),需要加上拉電阻才能正常通信。 


                  存儲卡的訪(fǎng)問(wèn)時(shí)序為I2C標準時(shí)序。首先,正常通信中只有在時(shí)鐘線(xiàn)(SCL)為低時(shí)SDA才可變化,即在SCL為高時(shí),SDA必須保持狀態(tài)(數據有效期),而在SCL為高時(shí),SDA的變化表示下面兩種控制狀態(tài):開(kāi)始狀態(tài):當SCL為高時(shí),SDA由高變低表示一個(gè)開(kāi)始狀態(tài),通常任何操作前均需要一個(gè)開(kāi)始狀態(tài);停止狀態(tài):當SCL為高時(shí),SDA由低變高表示一個(gè)停止狀態(tài),通常跟在每個(gè)操作后,從而將卡置于等待模式。

                  在讀寫(xiě)中,地址和數據都是按照8位的大小進(jìn)行傳輸,接收的一方需要返回一個(gè)ACK信號表示確認,這個(gè)ACK信號是在第9位的位置返回一個(gè)“0”來(lái)表示。如在讀卡的時(shí)候,DSP在收到8位后,在第9個(gè)時(shí)鐘應向卡發(fā)送“0”表示收到了正確的數據,同時(shí)要求卡繼續發(fā)送下一個(gè)8位數據,如果沒(méi)有這個(gè)ACK信號,則將會(huì )中止當前讀操作返回等待模式。寫(xiě)卡的時(shí)候,卡在收到DSP發(fā)送的地址和數據后也應該返回ACK信號以表示收到了正確的命令。開(kāi)始和停止狀態(tài)、確認信號時(shí)序如圖2所示。 


                  一個(gè)讀寫(xiě)操作的開(kāi)始需要先發(fā)送一個(gè)器件地址(device address)字節,該字節的高4位是“1010”,接著(zhù)3位是卡的高位地址,如AT24C16SC需要有11位地址(2K字節的大小),高3位地址就是這里來(lái)指示,最后1位是讀寫(xiě)控制位,若為“1”,則表示后面進(jìn)行一個(gè)讀操作,若為“0”,則表示后面進(jìn)行一個(gè)寫(xiě)操作。

                  寫(xiě)卡操作分為字寫(xiě)和頁(yè)寫(xiě)。字寫(xiě)時(shí),當發(fā)送完器件地址字節(最后1位為“0”指明寫(xiě)操作)后,接著(zhù)再發(fā)送一個(gè)字地址(word address)字節,即為卡的低8位地址,然后就可送入一個(gè)字節的數據,最后發(fā)送停止狀態(tài)。對于頁(yè)寫(xiě)時(shí),可以連續發(fā)送16個(gè)字節后再發(fā)送停止狀態(tài),需要注意的是,當頁(yè)寫(xiě)時(shí),低4位地址在卡內部自動(dòng)遞增,當到達頁(yè)末地址時(shí)會(huì )自動(dòng)返回頁(yè)首地址,所以要正確發(fā)送停止狀態(tài),否則繼續寫(xiě)入的字節就會(huì )覆蓋原來(lái)的數據。

                  讀卡操作分為讀當前地址、讀任意地址和順序讀幾種方式。幾種方式大同小異,下面主要介紹讀任意地址的操作,另兩種方式都較簡(jiǎn)單。讀任意地址時(shí),在發(fā)送完器件地址字節(最后1位為“1”指明讀操作)后,發(fā)送字地址字節,這一過(guò)程是裝載要讀的地址,下面再發(fā)送一個(gè)器件地址字節(同樣最后1位為“1”指明讀操作),然后便可從卡讀到一個(gè)連續8位數據,然后DSP發(fā)送停止狀態(tài)(而不是ACK信號)結束讀操作。

                  通過(guò)以上介紹可以看出,DSP與存儲卡連接的關(guān)鍵就是如何做出SCL和SDA的時(shí)序,也就是I2C時(shí)序。用DSP的兩根GPIO分別連接存儲卡的SCL和SDA,然后同時(shí)設置兩者的高低關(guān)系并且正確改變連接SDA那根GPIO的輸入和輸出方向,我們就可以解決這個(gè)問(wèn)題。例如,對于圖3這個(gè)數據有效期的時(shí)序,我們可以將兩根GPIO依次設置為:“01”、“11”、“01”,需要注意的是,改變狀態(tài)之間需要插入等待周期,因為DSP的工作時(shí)鐘很高,其GPIO的改變遠高于I2C時(shí)序的要求。 


                  下面給出一個(gè)寫(xiě)卡函數:
                  short write_ic(short page,short addr,short length,short *buff)
                  //page-要訪(fǎng)的問(wèn)高3位地址,addr-要訪(fǎng)問(wèn)的低8位地址,length-要寫(xiě)入的數據長(cháng)度,通常為16,buff-要寫(xiě)入的數據
                  {
                  short device_address,ack,i,loop=0;
                  start_ic(); //發(fā)送一個(gè)開(kāi)始狀態(tài)
                  device_address=0xa0|(page<<1);
                  put_ic(device_address); //發(fā)送器件地址字節,0xa0表示寫(xiě)
                  gpio_setdir(0); //改變GPIO方向為輸入
                  ack=1;
                  do
                  {
                  ack=get_ic();
                  loop++;
                  if(loop>10000)
                  return 0;
                  }while(ack!=0); //等待讀入確認信號,否則超時(shí)退出
                  device_address=addr; //要訪(fǎng)問(wèn)的低8位地址
                  put_ic(device_address); //發(fā)送字地址字節
                  gpio_setdir(0);
                  ack=1;
                  do
                  {
                  ack=get_ic();
                  loop++;
                  if(loop>10000)
                  return 0;
                  }while(ack!=0);


                  for(i=0;i{
                  put_ic(*buff++);
                  dir(0);
                  ack=1;
                  do
                  {
                  ack=get_ic();
                  }while(ack!=0);
                  } //寫(xiě)入數據
                  stop_ic();
                  return 1;
                  }
                  void put_ic(short c)
                  {
                  short temp,i;
                  gpio_setdir(1); //改變GPIO為輸出
                  for(i=7;i>=0;i--)
                  {
                  temp=1temp=temp<<(-i);


                  if(temp==0)
                  {
                  gpio_setval(0,0); //設置兩根GPIO的輸出
                  gpio_setval(1,0);
                  gpio_setval(0,0);
                  }
                  else if(temp==1)
                  {
                  gpio_setval(0,1);
                  gpio_setval(1,1);
                  gpio_setval(0,1);
                  }
                  }
                  }

                  DSP和智能卡的連接

                  智能卡是IC卡中最高級的一種,其內部一般有CPU、ROM、RAM和EEPROM等資源,卡內一般都駐有智能卡操作系統(COS),該操作系統對卡進(jìn)行維護和管理并解釋終端的各種命令。由于卡內有CPU和RAM,所以可以根據需要進(jìn)行一些運算和數據加密,同時(shí)卡內的EEPROM也可以存放一些用戶(hù)資料(容量也較存儲卡大)。智能卡的管腳如圖4所示。 


                  智能卡的操作遵循ISO7816-3規范,通信時(shí)序類(lèi)似于雙向RS-232通信協(xié)議(RS-232是單向的)。首先,操作前需要對卡進(jìn)行激活,激活過(guò)程必須保證智能卡的觸點(diǎn)接觸良好。激活的步驟為:VCC供電,RST為低,I/O設為輸入,提供CL,然后對卡進(jìn)行復位。復位分為冷復位和熱復位,兩者區別在于冷復位時(shí)RST由低變高,而熱復位時(shí)RST由高變低再變高,在復位后,卡應有復位應答;接受到卡正確的復位應答后,DSP可以向卡發(fā)送命令;取卡前需要進(jìn)行釋放,步驟順序與激活相反:RST變低,CLK變低,VCC掉電。

                  卡的復位應答可以告訴終端一些卡的原始信息,它的組成如圖5所示: 


                  TS:初始化字節,用來(lái)進(jìn)行位同步和指示后續通信的編碼方式,例如0x3f表示反碼編碼,0x3b表示正常編碼;
                  T0:格式字節,高4位用來(lái)指示是否傳輸TA1、TB1、TC1、TD1,低4位用來(lái)指示有多少個(gè)歷史字符;
                  TAi、TBi、TCi:接口字節,用來(lái)設置操作的一些參數,比如速率,保護時(shí)間,編程電壓等;
                  TDi:接口字節,高4位用來(lái)指示是否傳輸TAi+1、TBi+1、TCi+1,低4位用來(lái)指示傳輸類(lèi)型T。T=0,字符半雙工模式;T=1,塊半雙工模式,其他的T值保留。我們常用T=0即字符模式;
                  T1~TK:歷史字符,由制卡商提供;
                  TCK:校驗位,是T0~TK所有字節的異或,T=0時(shí)不傳此字節。
                  訪(fǎng)問(wèn)卡的時(shí)序如圖6所示。 


                  可以看出,1個(gè)字節幀由13位組成,1個(gè)開(kāi)始位、8個(gè)數據位、1個(gè)校驗位和2個(gè)保護時(shí)間位。在外部提供時(shí)鐘方式(常用方式)下,上圖中每個(gè)位所占的時(shí)間(ETU,Elementary Time Unit)默認為外部時(shí)鐘周期的372倍,如當外部時(shí)鐘為3.57M時(shí),1/ETU約為9600,即工作在9600速率下。保護時(shí)間默認為2個(gè)ETU,最大可以為254個(gè)ETU。

                  DSP與智能卡的連接跟存儲卡有些差異。首先,智能卡比存儲卡多一個(gè)RST管腳用來(lái)對CPU進(jìn)行復位,可以使用DSP的一根GPIO來(lái)控制;存儲卡的CLK為通信時(shí)鐘,速度不高,沒(méi)有速率要求,可以隨時(shí)停止,只要時(shí)序關(guān)系正確即可,可以由DSP的GPIO實(shí)現;但智能卡的CLK為卡內CPU的工作時(shí)鐘,速度很高(通常介于1M~5M),并且要求穩定,用DSP的GPIO來(lái)提供該時(shí)鐘是不可能的,因為DSP的GPIO的翻轉速度有限制,并且高速翻轉必定占用大量DSP系統資源。因此可以使用DSP的一個(gè)串口McBSP的發(fā)送時(shí)鐘CLKX來(lái)提供智能卡時(shí)鐘。同時(shí),還需要DSP的一根GPIO來(lái)連接智能卡的I/O信號,跟智能卡一樣的是,I/O線(xiàn)同樣是雙向的,需要正確改變DSP的GPIO方向,但不同的是智能卡的I/O有精確的速率要求,即為CLK速率的1/372,可以采用DSP內部的定時(shí)器來(lái)結合GPIO實(shí)現。

                  選擇DSP內部定時(shí)器的周期為提供時(shí)鐘的串口時(shí)鐘周期的372/8倍,當每個(gè)定時(shí)器中斷到來(lái)時(shí)進(jìn)行一次GPIO操作,這樣等于是8倍頻輸出和采入數據,即操作的最小周期是1/8個(gè)ETU,從而確保了精度。從實(shí)現上看,上述過(guò)程類(lèi)似于用定時(shí)器和GPIO來(lái)實(shí)現RS-232協(xié)議。需要注意的是,為了保證中斷響應和系統資源,定時(shí)器中斷程序中最好不進(jìn)行GPIO操作,而只作標志位設置,GPIO操作留給讀寫(xiě)函數實(shí)現。下面為一個(gè)讀卡函數的實(shí)現。

                  void readword_sim(unsigned short *buff,unsigned short length)
                  //buff-讀入的數據放的buffer,length-讀入的長(cháng)度
                  {
                  short tempbit,tempbyte,i,j,bitcount,parry;
                  rw=0; //設置GPIO為讀
                  for(j=0;j{
                  bitcount=0;
                  while(!bitcount)
                  {
                  ready=0;
                  while(!ready);
                  if(simdata==0) bitcount=1;
                  } //讀入開(kāi)始位
                  tempbyte=0;
                  bitcount=0;
                  for(;bitcount<11;)
                  {
                  tempbit=0;
                  for(i=0;i<8;i++)
                  {
                  ready=0;
                  while(!ready);
                  if(simdata==1)
                  tempbit=tempbit+(1<} //讀入一位的8倍采樣
                  if((tempbit&0x18)==0 && bitcount==0)
                  bitcount++;
                  else if(bitcount>0 && bitcount<9)
                  {
                  if((tempbit&0x18)!=0)
                  tempbyte=tempbyte+(1<<(bitcount-1));
                  bitcount++;
                  } //組成一個(gè)字節
                  else if(bitcount==9)
                  {
                  if((tempbit&0x18)!=0)
                  parry=1;
                  else parry=0;
                  bitcount++;
                  } //讀入校驗位
                  else if(bitcount==10) bitcount++; //保護時(shí)間
                  }
                  buff[j]=tempbyte;
                  }
                  }
                  shorterrupt void tshort() //定時(shí)器中斷
                  {
                  if(ready==0)
                  {
                  if(rw==0)
                  simdata=gpio_getval();
                  ready=1;
                  }
                  }
                  上面的程序實(shí)現了智能卡的讀寫(xiě)協(xié)議,余下的就是對卡發(fā)送命令即可,關(guān)于命令的結構和定義本文不作闡述。

                  本文關(guān)鍵詞:用dsp的gpio管腳實(shí)現與ic卡通信
                  回到頂部
                  99久热只有精品视频在线17_精品一区二区三区自拍图片_最新国产v亚洲_久久综合九色综合久
                  <strike id="tpvd9"><dfn id="tpvd9"></dfn></strike>

                        <em id="tpvd9"></em>

                          <address id="tpvd9"></address>
                            <dfn id="tpvd9"><sub id="tpvd9"></sub></dfn>

                            <thead id="tpvd9"><noframes id="tpvd9">
                            <ruby id="tpvd9"></ruby>

                                  <thead id="tpvd9"></thead>