bj-stm8 发表于 2010-11-22 13:11:03

AT91SAM7S64资料汇总,感兴趣的朋友请进

AT91SAM7S64带usb,貌似j-link上就是这个用的它

bj-stm8 发表于 2010-11-22 13:12:58

点击此处下载 ourdev_599610GZGJIL.pdf(文件大小:5.45M) (原文件名:AT91SAM7S64中文说明.pdf)

bj-stm8 发表于 2010-11-22 16:03:04

点击此处下载 ourdev_599633EUXVUK.pdf(文件大小:392K) (原文件名:AT91SAM7S64调试笔记 .pdf)

bj-stm8 发表于 2010-11-22 16:21:50

点击此处下载 ourdev_599641OMT5AE.rar(文件大小:2.48M) (原文件名:新建文件夹.rar)

rtems 发表于 2010-11-22 18:34:01

几年前用AT91SAM7S64设计过好几个产品,挺好用的。

bbs2009 发表于 2010-11-22 19:00:49

bj-stm8 发表于 2010-11-22 19:54:19

是的,比较老.
今天处理废品把这些没用的书和旧板都卖给收废品的了
看到有些板子上有AT91SAM7S64就留了几个,外壳也挺漂亮的

http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_599820LY32S4.jpg
(原文件名:zigbee.jpg)

bj-stm8 发表于 2010-11-23 09:15:55

http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_599821YRJZTF.jpg
(原文件名:zigbee.jpg)

bj-stm8 发表于 2010-12-14 11:13:29

这个模块的原理图:

bj-stm8 发表于 2010-12-14 11:16:08

http://cache.amobbs.com/bbs_upload782111/files_35/ourdev_604507CI61IY.jpg
(原文件名:64.jpg)

bj-stm8 发表于 2010-12-14 11:35:54

USB-Zigbee Key软件设计说明
硬件总体包括三部分:主控芯片、FLASH和Zigbee模块,其中Zigbee模块由无线组负责,它和主控芯片之间的通信通过串口实现;主控芯片和FLASH之间通过SPI通信。其具体功能描述如下:
        提供一个USB串行接口,用于连接PC;
        提供ZigBee模块,相关需求请参见 “ZigBee模块需求”;
        一个指示密钥获取状态的指示灯(例如在获取密钥的过程中指示灯闪,获取完毕后灯灭)。

bj-stm8 发表于 2010-12-14 11:43:01

1.        任务概述
1.1.        目标
1、        通过USB口和上位PC机通信
2、        通过USART口和zbm模块通信
3、        通过SPI口和FLASH通信
1.2.        运行环境
1、        软件环境为IAR Embedded workbench for ARM V4.31.A
2、        硬件环境为AT91SAM7S64
1.3.        需求概述
整个系统的需求可以概括为以下两个方面:
1、        建立上位PC机和数据存储FLASH之间的数据连接
2、        建立上位PC机和zbm无线模块之间的数据连接

bj-stm8 发表于 2010-12-14 11:51:49

http://cache.amobbs.com/bbs_upload782111/files_35/ourdev_604510K1HXOT.jpg
(原文件名:tu.jpg)

bj-stm8 发表于 2010-12-14 11:52:04

2.2.        总体结构和模块外部设计
程序总体为顺序结构,只有接收zbm数据采用中断插入方式。模块之间通过数据缓存区来交换信息。
需要注意的是,因为ARM7具有DMA方式,所以实际数据传输流程是不需要MCU一直进行干预的。

bj-stm8 发表于 2010-12-14 11:52:52

2.3.        功能分配
根据功能,整个系统可以分为一下模块:USB读写模块,USB命令处理模块,SPI读写模块,USART读写模块

bj-stm8 发表于 2010-12-14 11:53:35

3.        各个模块总体规划说明
3.1.        USB读写模块
USB读写模块拥有最高优先级,它是整个系统的核心。它通过USB的不同端点来接收或者发送数据。
3.2.        USB命令处理模块
根据USB-Key协议,解析收到的命令,再调用相应的数据处理模块进行处理;完成相应的动作之后,将处理结果进行封包,通过USB读写模块传回PC机。
3.3.        SPI读写模块
当需要对外置FLASH存储器进行操作时,调用SPI读写模块进行数据传递。数据传递的方向、大小和地址都由上位PC机通过USB-Key协议来确定。
3.4.        USART读写模块
USART读写模块在系统中拥有次高的优先级,仅次于USB读写模块。之所以选用这种优先级排序,主要是考虑到USB命令的读写是系统稳定工作的保证,而且zbm模块的通信速率和通信量相对较小。
USART的读操作采用了ping-pong模式,这样可以保证,在USB读取模块操作共享数据区的过程中,USART模块能正确的接收数据。

bj-stm8 发表于 2010-12-14 11:53:53

4.        接口设计
4.1.        外部接口
USB接口:USB控制端点进行枚举处理、USB数据端点读写数据
USART:DMA中断方式读写数据
SPI:DMA中断方式读写数据
4.2.        内部接口
Ping-pong模式共享数据缓存区。

bj-stm8 发表于 2010-12-14 11:54:13

5.        系统可靠性设计规划
5.1.        运行设计
各个模块自身采用DMA方式收发数据。
除USART读数据外,其余模块只能通过主程序直接调用启动。
Ping-pong模式共享数据缓存,保证数据安全和完整。
5.2.        出错处理设计
5.2.1.        出错处理对策
只能由PC上位机通过USB控制端点零来进行重启。
5.3.        可测试性设计
根据协议,只要数据处理完成,则通过USB数据入端点返回处理结果。

bj-stm8 发表于 2010-12-14 12:29:18

http://cache.amobbs.com/bbs_upload782111/files_35/ourdev_604515KKEK22.jpg
(原文件名:usart.jpg)

http://cache.amobbs.com/bbs_upload782111/files_35/ourdev_604516HYY4DB.jpg
(原文件名:usb_ctrl.jpg)

http://cache.amobbs.com/bbs_upload782111/files_35/ourdev_604517OZ4FXS.jpg
(原文件名:usb_in.jpg)

http://cache.amobbs.com/bbs_upload782111/files_35/ourdev_604518IWP4AD.jpg
(原文件名:程序流程.jpg)

bj-stm8 发表于 2010-12-14 15:05:16

/* C **************************************************************************/
// 名称:main.c
// 功能:
// 说明:
/* C **************************************************************************/

/* include */
#include "compiler.h"
#include "board.h"
#include "basic.h"

#if check_flash
#include "usb_spi.h"
#endif

struct _zkey_usb_ms s_MASS;
char usb_running;
uint GV_usart_rec_length;        // usart收到的数据总长

#if usbziji_v1
uint zkeyF_isusbconnect()
{
return (true);
}
#endif

extern void zkeyF_USART_Open( void );

void main ( void )
{
AT91C_BASE_RSTC->RSTC_RMR = AT91C_RSTC_URSTEN | (0x4<<8) | (unsigned int)(0xA5<<24); // 允许复位,最小复位时间960 us

zkeyF_led_init();
        usb_running = 0;
        GV_usart_rec_length = 0;

        zkeyF_spi_start();      
        zkeyF_usb_open();   
        while(!s_MASS.isconfigured(&s_MASS));   
        zkeyF_USART_Open();

while(1)
{
    zkeyF_usb_task(&s_MASS);
                if(usb_running == 1)        // from 0-> 1
                {
                        AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, LED_MASK ) ; // 点亮LED   
                }
                else
                {
                        AT91F_PIO_SetOutput( AT91C_BASE_PIOA, LED_MASK );    // 关闭LED
                }   
}

bj-stm8 发表于 2010-12-14 15:08:32

#include "basic.h"

/*--------------------- global variable --------------------------------------*/
extern struct _s_usb_cbw    ms_usb_cbw;
extern struct _s_usb_csw    ms_usb_csw;

void zkeyF_led_init (void)
{
AT91F_PIO_CfgOutput( AT91C_BASE_PIOA, LED_MASK ) ;    // PIOA配置为输出,用于LED
AT91F_PIO_SetOutput( AT91C_BASE_PIOA, LED_MASK ) ;    // 熄灭LED
}

bj-stm8 发表于 2010-12-14 15:13:10

//*----------------------------------------------------------------------------
//* File Name         : dataflash.c
//* Object            : SPI dataflash 程序
//* Creation            :
//*----------------------------------------------------------------------------
// Include Standard files
#include "usb_spi.h"
#if new_board
uchar FLASH_PBR;
#include "down_pbr.h"
#endif

#define   SpiDataflash_SYS_LEVEL         6//定义SpiDataflash的中断优先级为最高优先级


zkeyS_dataflashfeatures                deviceAT45DB161d;         //定义一个数据结构为 AT45DB321C
zkeyS_dataflashdesc                dataflashdesc;            //定义一个数据结构为 dataflashdesc
zkeyS_dataflash                        dataflash;                //定义一个数据结构为 dataflash
// ucharBuffer_Dataflash;         //定义一个缓冲区为   dataflash

//*-----------------------定义需要的,而库里没有的函数---------------------------
__inline unsigned int AT91F_SPI_GetStatus( // \return SPI Interrupt Mask Status
      AT91PS_SPI pSpi) // \argpointer to a SPI controller
{
      return pSpi->SPI_SR;
}
//*----------------------------------------------------------------------------
//* 函数名: AT91F_SPI0_CfgSPI
//* 功能:配置SPI0
//*----------------------------------------------------------------------------
static voidzkeyF_spi_cfgspi(void)
{
    //* 复位SPI
        AT91F_SPI_Reset(AT91C_BASE_SPI);

    //* 配置 SPI 工作在主模式--固定外设--NPCS0片选 //如果选用不同的片选可在此处修改
        AT91F_SPI_CfgMode(AT91C_BASE_SPI, AT91C_SPI_MSTR | AT91C_SPI_PS_FIXED | AT91C_SPI_MODFDIS | (0xE<<16));

      //* SPI MODE 0:CPOL/NCPHA 0/1, 传输后片选上升, 配置8 位数据位
        AT91F_SPI_CfgCs(AT91C_BASE_SPI,0, AT91C_SPI_NCPHA | AT91C_SPI_BITS_8 | (AT91C_SPI_DLYBS & 0x100000) |((MCK/(DATAFLASH_CLK)) << 8));

   //* 启动 SPI0
       AT91F_SPI_Enable(AT91C_BASE_SPI);
}

//*----------------------------------------------------------------------------
//* 函数名:zkeyF_cfgdataflash
//* 功能:   初始化DataFlash 数据结构
//*----------------------------------------------------------------------------
static void zkeyF_cfgdataflash (void)
{
       // 初始化DATAFLASH特性,使之适合AT45D321C   //如果选用其他型号的的FLASH则依据FLASH的特性,在此修改
        deviceAT45DB161d.pages_number = 4095;
        deviceAT45DB161d.pages_size   = 512;
        deviceAT45DB161d.page_offset= 10;
        deviceAT45DB161d.byte_mask    = 0x300;
       
        // 初始化 AT91S_DataflashDesc 结构
        dataflashdesc.state             = IDLE;
        dataflashdesc.DataFlash_state   = IDLE;

        // 初始化 AT91S_DataFlash 全局结构, AT45DB321C 作为默认选择
        dataflash.pDataFlashDesc = &dataflashdesc;
        dataflash.pDevice        = &deviceAT45DB161d;
}

//*----------------------------------------------------------------------------
//* 函数名:zkeyF_dataflashhandler
//* 功能:   SPI0中断处理程序
//*----------------------------------------------------------------------------
static void zkeyF_dataflashhandler(
        zkeyPS_dataflashdesc pDesc,
        unsigned int status)
{
   //* 判断是否接收完,产生的中断
    if (( status & AT91C_SPI_RXBUFF))
    {
          if( pDesc->state == BUSY)
             {
                       //*设置DATAFLASH的下一个状态为空闲状态,
                pDesc->state = IDLE;
                if (pDesc->DataFlash_state == DATAFLASH_GET_STATUS)
                pDesc->DataFlash_state = *( (unsigned char *) (pDesc->rx_cmd_pt) +1);

                //AT91F_USRT_Printk(AT91C_BASE_US0,"receive interrupt\n\r");

              //* 禁止传输中断
              AT91C_BASE_SPI->SPI_IDR = AT91C_SPI_RXBUFF;
               //*允许PDC 发送和接收 --PDC 传输控制寄存其
              AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;
              return;
               }       
    }
      //否则状态错误
        pDesc->state = ERROR;
       // 禁止PDC接收和发送中断
        AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;
      //禁止出RXBUFF之外的所有中断
       AT91C_BASE_SPI->SPI_IDR = status;
}

//*----------------------------------------------------------------------------
//* 函数名: zkeyF_spi_handler
//* 功能:   SPI中断入口
//*----------------------------------------------------------------------------
void zkeyF_spi_handler(void)
{
   unsigned int status;
   //禁止 SPI0 中断
   AT91F_AIC_DisableIt(AT91C_BASE_AIC,AT91C_ID_SPI);
//--------------------------------------------------------------------------
   //取得 SPI_SR 和 SPI_IMR ----的状态
   status=( AT91F_SPI_GetStatus(AT91C_BASE_SPI)&AT91F_SPI_GetInterruptMaskStatus(AT91C_BASE_SPI));
   //调用中断处理函数
   zkeyF_dataflashhandler(dataflash.pDataFlashDesc, status);
   //---------------------------------------------------------------------
   // 允许SPI1中断
   AT91F_AIC_EnableIt(AT91C_BASE_AIC,AT91C_ID_SPI);
}

//*----------------------------------------------------------------------------
//*函数名:zkeyF_spi_open
//* 功能:   初始化SPI0,与串口DataFlash通信
//*----------------------------------------------------------------------------
void zkeyF_spi_open(void)
{
// ============================= 初始化 SPI 接口 =============================
   // 初始化 SPI 作为 dataflash 接口
   zkeyF_spi_CfgPIO();       
   //开启SPI PMC
   AT91F_SPI_CfgPMC();
   //允许接收缓冲区满中断---RXBUFF
   AT91F_SPI_EnableIt(AT91C_BASE_SPI,0x1<<6);
   //配置SPI 特性
   zkeyF_spi_cfgspi();
   //开启 PDC
   AT91F_PDC_Open(AT91C_BASE_PDC_SPI);
//配置 AT45DB161C
   zkeyF_cfgdataflash();
   // 配置 SPI 中断
   AT91F_AIC_ConfigureIt(AT91C_BASE_AIC,
                          AT91C_ID_SPI,
                          SpiDataflash_SYS_LEVEL,
                          AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL,
                          zkeyF_spi_handler);               
    // 允许 SPI0 中断
    AT91F_AIC_EnableIt(AT91C_BASE_AIC,AT91C_ID_SPI);
}

//*----------------------------------------------------------------------------
//* 函数名:zkeyF_spiwrite
//* 功能:设置 PDC 传输功能
//说明:此处为重先编写的直接PDC传输功能,因为SPI接受和发送是同时的,所以直接对寄存器操作比较方便,
//          也可以调用库函数AT91F_SPI_ReceiveFrame()其功能与此处相同,
//          可参考usart.c 文件,里面的传输采用调用库函数来实现的!
//          详细了解,参见DATASHEET 的PDC部分。
//*----------------------------------------------------------------------------
static void zkeyF_spiwrite ( zkeyPS_dataflashdesc pDesc )
{        
       //设置设备的状态为忙,等待中断清除这种状态
           pDesc->state = BUSY;

           // 禁止PDC接收和发送中断
           AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;
          
           //* 初始化发送和接收指针
      AT91C_BASE_SPI->SPI_RPR = (unsigned int)pDesc->rx_cmd_pt ;
      AT91C_BASE_SPI->SPI_TPR = (unsigned int)pDesc->tx_cmd_pt ;

      //* 初始化发送和接收计数器
      AT91C_BASE_SPI->SPI_RCR = pDesc->rx_cmd_size ;
      AT91C_BASE_SPI->SPI_TCR = pDesc->tx_cmd_size ;

        if ( pDesc->tx_data_size != 0 )
           {
       //* 初始化下一个接受和发送指针
            AT91C_BASE_SPI->SPI_RNPR = (unsigned int)pDesc->rx_data_pt ;
      AT91C_BASE_SPI->SPI_TNPR = (unsigned int)pDesc->tx_data_pt ;

        //* 初始化下一个发送和接收计数器
       AT91C_BASE_SPI->SPI_RNCR = pDesc->rx_data_size ;
       AT91C_BASE_SPI->SPI_TNCR = pDesc->tx_data_size ;
           }
           //* 允许接收满中断---- RXBUFF
      AT91C_BASE_SPI->SPI_IER = AT91C_SPI_RXBUFF;
      //* PDC传输控制----- 允许PDC传输和接收
           AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTEN + AT91C_PDC_RXTEN;

}

//*----------------------------------------------------------------------------
//* 函数名:zkeyF_dataflashgetstatus
//* 功能:   读DATAFLASH的状态
//*----------------------------------------------------------------------------
static zkeyS_dataflashstatus zkeyF_dataflashgetstatus(zkeyPS_dataflashdesc pDesc)
{
    //* 如果数据传输没有结束 ==> 返回 0       
    if( (pDesc->state) != IDLE)
    return DATAFLASH_BUSY;
    //* 首先发送和读取状态命令(D7H)
    pDesc->command = DB_READ_STATUS;
    pDesc->command = 0;

    pDesc->DataFlash_state= DATAFLASH_GET_STATUS;
    pDesc->tx_data_size         = 0 ;        //* 传输命令,接收读取的状态----非数据传输
    pDesc->tx_cmd_pt                 = pDesc->command ;
    pDesc->rx_cmd_pt                 = pDesc->command ;
    pDesc->rx_cmd_size                 = 2 ;
    pDesc->tx_cmd_size                 = 2 ;
    zkeyF_spiwrite (pDesc);
    return DATAFLASH_OK;
}


//*----------------------------------------------------------------------------
//* 函数名:zkeyF_dataflashsendcommand
//* 功能: 通过SPI发送命令到 dataflash
//*----------------------------------------------------------------------------
static zkeyS_dataflashstatus zkeyF_dataflashsendcommand (
        zkeyPS_dataflash pDataFlash,
        unsigned char OpCode,
        unsigned int CmdSize,
        unsigned int DataflashPageAddress)
{
    unsigned int addr;

    if ( (pDataFlash->pDataFlashDesc->state) != IDLE)
    return DATAFLASH_BUSY;
                               
        //* process the address to obtain page address and byte address
    addr = DataflashPageAddress << (pDataFlash->pDevice->page_offset);

        //* fill thecommandbuffer */
    pDataFlash->pDataFlashDesc->command = OpCode;
    pDataFlash->pDataFlashDesc->command = (unsigned char)((addr & 0x00FF0000) >> 16);
    pDataFlash->pDataFlashDesc->command = (unsigned char)((addr & 0x0000FF00) >>8);
    pDataFlash->pDataFlashDesc->command = (unsigned char)((addr & 0x000000FF) >>0);
    pDataFlash->pDataFlashDesc->command = 0;
    pDataFlash->pDataFlashDesc->command = 0;
    pDataFlash->pDataFlashDesc->command = 0;
    pDataFlash->pDataFlashDesc->command = 0;

        /* Initialize the SpiData structure for the spi write fuction */
    pDataFlash->pDataFlashDesc->tx_cmd_pt   =pDataFlash->pDataFlashDesc->command ;       
    pDataFlash->pDataFlashDesc->tx_cmd_size =CmdSize ;
    pDataFlash->pDataFlashDesc->rx_cmd_pt   =pDataFlash->pDataFlashDesc->command ;
    pDataFlash->pDataFlashDesc->rx_cmd_size =CmdSize ;

       /* send the command and read the data */
    zkeyF_spiwrite (pDataFlash->pDataFlashDesc);

    return DATAFLASH_OK;
}

//*----------------------------------------------------------------------------
//* 函数名: zkeyF_dataflashpageread
//* 功能:读取DATAFLASH的某一页
//*----------------------------------------------------------------------------
zkeyS_dataflashstatus zkeyF_dataflashpageread (
        zkeyPS_dataflash pDataFlash,
        unsigned int addr,
        char *dataBuffer,
        int sizeToRead )
{
    pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer ;        //* 读操作缓冲区的地址
    pDataFlash->pDataFlashDesc->rx_data_size = sizeToRead;        //* 读数据大小
    pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer ;
    pDataFlash->pDataFlashDesc->tx_data_size = sizeToRead;

   //* 发送读命令到dataflash
   return (zkeyF_dataflashsendcommand (pDataFlash, DB_MAIN_PAGE_READ, 8, addr));
}

//*----------------------------------------------------------------------------
//* 函数名:zkeyF_dataflashpagepgmbuf
//* 功能:通过缓冲区1向DATAFLASH写一页数据with erase
//*----------------------------------------------------------------------------
zkeyS_dataflashstatus zkeyF_dataflashpagepgmbuf(
        zkeyPS_dataflash pDataFlash,
        char *src,
        unsigned int addr,
        unsigned int SizeToWrite)
{       
    pDataFlash->pDataFlashDesc->tx_data_pt = src ;
    pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite ;
    pDataFlash->pDataFlashDesc->rx_data_pt = src;
    pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite;

   /* 发送写命令到dataflash */
   return(zkeyF_dataflashsendcommand (pDataFlash,DB_MAIN_PROGRAM_BUFF1, 4, addr));
}

//*----------------------------------------------------------------------------
//* 函数名:zkeyF_dataflashpageerase
//* 功能:   通过缓冲区1或缓冲区2擦除DATAFLASH
//*----------------------------------------------------------------------------
zkeyS_dataflashstatus zkeyF_dataflashpageerase(
        zkeyPS_dataflash pDataFlash,
        char *src,
        unsigned int address,
        unsigned int SizeToWrite)
{       
    pDataFlash->pDataFlashDesc->tx_data_pt = src ;
    pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite ;
    pDataFlash->pDataFlashDesc->rx_data_pt = src;
    pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite;

   /* 发送擦除命令到dataflash */
   return(zkeyF_dataflashsendcommand (pDataFlash, DB_PAGE_ERASE, 4, address));
}

//*----------------------------------------------------------------------------
//* 函数名:zkeyF_dataflashwaitready
//* 功能:等待DATAFLAH操作完 (bit7 of the status register == 1)
//*----------------------------------------------------------------------------
zkeyS_dataflashstatus zkeyF_dataflashwaitready(zkeyPS_dataflashdesc pDataFlashDesc, unsigned int timeout)
{
        unsigned int i;

        pDataFlashDesc->DataFlash_state = IDLE;       

        do
        {
                zkeyF_dataflashgetstatus(pDataFlashDesc);
                timeout--;
                // 简单的等待
                for(i=0;i<1000;i++);
        }
        while( ((pDataFlashDesc->DataFlash_state & 0x80) != 0x80) && (timeout>0) );

        if((pDataFlashDesc->DataFlash_state & 0x80) != 0x80)
                return DATAFLASH_ERROR;
               
        return DATAFLASH_OK;
}


void zkeyF_spi_select_flash ( AT91PS_SPI pSPI )
{
#if usbziji_v1
uint i;
AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, FLASH_POWER_CONTROL);
for(i=0; i<100; i++);
#endif
pSPI->SPI_MR |= 0xe<<16;// 激活片选信号
}

void zkeyF_spi_CfgPIO (void)
{
AT91F_PIO_CfgPeriph(
                AT91C_BASE_PIOA, // PIO controller base address
                ((unsigned int) AT91C_PA13_MOSI    ) |
                ((unsigned int) AT91C_PA14_SPCK    ) |
                ((unsigned int) AT91C_PA11_NPCS0   ) |
                ((unsigned int) AT91C_PA12_MISO    ),
                0);
}

// IN usb_bulk.h

// in basic.h
void zkeyF_spi_close(void)
{
;
}

void zkeyF_spi_start(void)
{
zkeyF_spi_open();
}

uchar zkeyF_scsi_get_flash_status ( void )
{
uint i;
uchar flash_status;
ushort time;
       
        time = 50000;
while(time && zkeyF_dataflashgetstatus(dataflash.pDataFlashDesc)!=DATAFLASH_OK);
for(i=0;i<100;i++);
flash_status = dataflashdesc.DataFlash_state;

if (flash_status & 0x80)
    flash_status = FLASH_OK;
else if (flash_status & 0x20)
    flash_status = FLASH_PROTECT;
else if (flash_status == 0x00)
    flash_status = FLASH_NO_PRESENT;
else
    flash_status = FLASH_BUSY;

return(flash_status);
}

zkeyS_dataflashstatus zkeyF_dataflashconfigure ( zkeyPS_dataflash pDataFlash )
{
    if ( (pDataFlash->pDataFlashDesc->state) != IDLE)
    return DATAFLASH_BUSY;
                               
        //* fill thecommandbuffer */
    pDataFlash->pDataFlashDesc->command = 0x3D;
    pDataFlash->pDataFlashDesc->command = 0x2A;
    pDataFlash->pDataFlashDesc->command = 0x80;
    pDataFlash->pDataFlashDesc->command = 0xA6;
    pDataFlash->pDataFlashDesc->command = 0;
    pDataFlash->pDataFlashDesc->command = 0;
    pDataFlash->pDataFlashDesc->command = 0;
    pDataFlash->pDataFlashDesc->command = 0;

        /* Initialize the SpiData structure for the spi write fuction */
    pDataFlash->pDataFlashDesc->tx_cmd_pt   =pDataFlash->pDataFlashDesc->command ;       
    pDataFlash->pDataFlashDesc->tx_cmd_size =4 ;
    pDataFlash->pDataFlashDesc->rx_cmd_pt   =pDataFlash->pDataFlashDesc->command ;
    pDataFlash->pDataFlashDesc->rx_cmd_size =4 ;

       /* send the command and read the data */
    zkeyF_spiwrite (pDataFlash->pDataFlashDesc);

    return DATAFLASH_OK;

catzl7 发表于 2010-12-14 15:58:42

先顶一个再看

bj-stm8 发表于 2010-12-14 17:34:52

/* C **************************************************************************/
// 名称: usb_enum.c
// 功能: usb功能的初始化、枚举处理过程等
// 说明:
/* C **************************************************************************/

#include "at91usb_conf.h"

typedef unsigned char uchar;
typedef unsigned intuint;

//应用于全局的变量控制、程序控制结构体
struct _KEYS_USBpskeyUSB;

void          KEYF_USB_Open      ( void );
KEYPS_USB   KEYF_CDC_Open      ( KEYPS_USB psUSB, AT91PS_UDP psUDP );
void          KEYF_Init_USB      ( KEYPS_USB psUSB );
static ucharKEYF_IsUSBConfigured ( KEYS_USB *psUSB );
static void   KEYF_USB_Enumerate   ( KEYS_USB *psUSB );
static void   KEYF_USB_SendData    ( AT91PS_UDP psUDP, const char *pData, uint length);
void          KEYF_USB_SendZlp   ( AT91PS_UDP psUDP );
void          KEYF_USB_SendStall   ( AT91PS_UDP psUDP );
static uint   KEYF_USB_Write       ( KEYS_USB *psUSB, const char *pData, uint Length );
static uint   KEYF_USB_Read      ( KEYS_USB *psUSB, char *pData, uint Length );
//void          KEYF_Toggle_LED      ( char LED );

KEYS_CDC_LINE_CODING line =
{
115200, // 波特率
0,      // 1位停止位
0,      // 无校验
8       // 8位数据
};   

/* Fuction ********************************************************************/
//名称:KEYF_USB_Open
//功能:USB环境初始化 - PLL时钟、上拉电阻、初始化全局结构体等
//参数:无
//返回值:无
/* Fuction ********************************************************************/
void KEYF_USB_Open ( void )
{
// Set the PLL USB Divider
AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1 ;   // 设置PLL时钟
AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_UDP;             // 允许48MHz USB时钟频率
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_UDP);
AT91F_PIO_CfgOutput(AT91C_BASE_PIOA,AT91C_PIO_PA21);// 设置PIO模式,配置为输出
AT91F_PIO_ClearOutput(AT91C_BASE_PIOA,AT91C_PIO_PA21);// 设置上拉电阻
KEYF_CDC_Open(&pskeyUSB, AT91C_BASE_UDP);            // 通过初始化usb结构体打开CDC
}

/* Fuction ********************************************************************/
//名称:AT91F_CDC_Open
//功能:初始化USB全局结构体 - pskeyUSB
//参数:全局结构体、当前USB寄存器地址
//返回值:全局结构体
/* Fuction ********************************************************************/
KEYPS_USB KEYF_CDC_Open ( KEYPS_USB pskeyUSB, AT91PS_UDP psUDP )
{
pskeyUSB->psUSB             = psUDP;   // USB寄存器地址
pskeyUSB->USBConfiguration= 0;
pskeyUSB->USBConnection   = 0;
pskeyUSB->USBRcvBank      = AT91C_UDP_RX_DATA_BK0;
pskeyUSB->IsUSBConfigured   = KEYF_IsUSBConfigured;
pskeyUSB->USBWrite          = KEYF_USB_Write;
pskeyUSB->USBRead         = KEYF_USB_Read;
return pskeyUSB;
}

/* Fuction ********************************************************************/
//名称:KEYF_IsUSBConfigured
//功能:判断枚举处理状态
//参数:全局结构体
//返回值:当前配置序号
/* Fuction ********************************************************************/
static uchar KEYF_IsUSBConfigured ( KEYS_USB *pskeyUSB )
{
AT91PS_UDP psUDP = pskeyUSB->psUSB; // usb寄存器地址
AT91_REG usb_isr = psUDP->UDP_ISR;// isr寄存器状态
if ( usb_isr & AT91C_UDP_ENDBUSRES )// 总线重启
{
    psUDP->UDP_ICR = AT91C_UDP_ENDBUSRES; // 清除总线重启标志-置ICR相应位
    KEYF_Init_USB(pskeyUSB); // 初始化EP0
}
else if ( usb_isr & AT91C_UDP_EPINT0 )// 端点零发生中断
{
    psUDP->UDP_ICR = AT91C_UDP_EPINT0;// 清除ep0中断标志
    KEYF_USB_Enumerate ( pskeyUSB ); // 调用枚举处理函数
}
return pskeyUSB->USBConfiguration;// 返回当前配置序号
}

/* Fuction ********************************************************************/
//名称:KEYF_Init_USB
//功能:初始化EP0端点
//参数:当前使用的全局结构体
//返回值:无
/* Fuction ********************************************************************/
static void KEYF_Init_USB ( KEYPS_USB pskeyUSB )
{
AT91PS_UDP lcl_psUDP = pskeyUSB->psUSB; // usb寄存器地址
lcl_psUDP->UDP_RSTEP = (uint) -1;             // 复位所有端点
lcl_psUDP->UDP_RSTEP = 0;                     // 清除EP0复位标志
lcl_psUDP->UDP_FADDR = AT91C_UDP_FEN;         // 开USB功能允许
lcl_psUDP->UDP_CSR= ( AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL ); // 使能端点,定义端点类型为控制
}

/* Fuction ********************************************************************/
//名称:KEYF_USB_Enumerate
//功能:处理主机枚举过程中调用
//参数:全局结构体
//返回值:无
/* Fuction ********************************************************************/
static void KEYF_USB_Enumerate( KEYPS_USB pskeyUSB )
{
AT91PS_UDP psUDP = pskeyUSB->psUSB; // USB寄存器
char bmRequestType, bRequest;
ushort wValue, wIndex, wLength, wStatus;

if ( !(psUDP->UDP_CSR & AT91C_UDP_RXSETUP))return; // FIFO中没有有效的设置数据包

bmRequestType =psUDP->UDP_FDR;
bRequest      =psUDP->UDP_FDR;
wValue      = (psUDP->UDP_FDR & 0xFF);
wValue       |= (psUDP->UDP_FDR << 8);
wIndex      = (psUDP->UDP_FDR & 0xFF);
wIndex       |= (psUDP->UDP_FDR << 8);
wLength       = (psUDP->UDP_FDR & 0xFF);
wLength      |= (psUDP->UDP_FDR << 8);

if (bmRequestType & 0x80) // 传输方向设置
{
    psUDP->UDP_CSR |= AT91C_UDP_DIR; // 设置端点传输方向为in - 对主机而言
    while ( !( psUDP->UDP_CSR & AT91C_UDP_DIR ) ); // 等待设置完成
}

psUDP->UDP_CSR &= ~AT91C_UDP_RXSETUP;// 通知主机已经取走数据
while ( (psUDP->UDP_CSR& AT91C_UDP_RXSETUP) ); // 等待主机发送新的设置数据包

switch ( (bRequest << 8) | bmRequestType )
{
case STD_GET_DESCRIPTOR:
    if ( wValue == 0x100 )      // 设备描述符
      KEYF_USB_SendData( psUDP, DevDescriptor, Min(sizeof(DevDescriptor), wLength) );
    else if ( wValue == 0x200 )   // 配置描述符
      KEYF_USB_SendData( psUDP, User_CfgDescriptor, Min(sizeof(User_CfgDescriptor), wLength) );
    else
      KEYF_USB_SendStall( psUDP );
    break;
   
case STD_SET_ADDRESS:
    KEYF_USB_SendZlp ( psUDP );// 发送零长度数据
    psUDP->UDP_FADDR = ( AT91C_UDP_FEN | wValue );// 使能端点 + 端点地址
    psUDP->UDP_GLBSTATE = ( wValue ) ? AT91C_UDP_CONFG : AT91C_UDP_FADDEN;// 配置USB器件状态
    break;
   
case STD_SET_CONFIGURATION:
    pskeyUSB->USBConfiguration = wValue;// 更改当前配置序号
    KEYF_USB_SendZlp( psUDP );
    psUDP->UDP_GLBSTATE = ( wValue ) ? AT91C_UDP_CONFG : AT91C_UDP_FADDEN;// 配置成功与否
    psUDP->UDP_CSR = ( wValue ) ? ( AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT ) : 0; // 配置端点1
    psUDP->UDP_CSR = ( wValue ) ? ( AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN ): 0; // 配置端点2
    psUDP->UDP_CSR = ( wValue ) ? ( AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_ISO_IN )   : 0; // 配置端点3
    break;
   
case STD_GET_CONFIGURATION:
    KEYF_USB_SendData( psUDP, (char*) &(pskeyUSB->USBConfiguration), sizeof(pskeyUSB->USBConfiguration) );
    break;
   
case STD_GET_STATUS_ZERO:
    wStatus = 0;
    KEYF_USB_SendData(psUDP, (char*) &wStatus, sizeof(wStatus));
    break;
   
case STD_GET_STATUS_INTERFACE:
    wStatus = 0;
    KEYF_USB_SendData(psUDP, (char*) &wStatus, sizeof(wStatus));
    break;
   
case STD_GET_STATUS_ENDPOINT: // 获得端点状态
    wStatus = 0;
    wIndex &= 0x0F; // 请求的端点号
    if ( (psUDP->UDP_GLBSTATE & AT91C_UDP_CONFG) && (wIndex <=3) ) // 端点必须已经被配置好
    {
      wStatus = (psUDP->UDP_CSR & AT91C_UDP_EPEDS) ? 0 : 1; // 端点使能的时候表示no halt
      KEYF_USB_SendData(psUDP, (char*) &wStatus, sizeof(wStatus));   
    }
    else if ( (psUDP->UDP_GLBSTATE & AT91C_UDP_FADDEN) && (wIndex == 0) ) // 端点0已经分配地址
    {
      wStatus = (psUDP->UDP_CSR & AT91C_UDP_EPEDS) ? 0 : 1;
      KEYF_USB_SendData(psUDP, (char*) &wStatus, sizeof(wStatus));   
    }
    else
      KEYF_USB_SendStall(psUDP); // 端点已经停止
    break;
   
case STD_SET_FEATURE_ZERO:
    KEYF_USB_SendStall(psUDP);
    break;
   
case STD_SET_FEATURE_INTERFACE:
    KEYF_USB_SendZlp(psUDP);
    break;
   
case STD_SET_FEATURE_ENDPOINT:
    wIndex &= 0x0F;
    if ( (wValue == 0) && wIndex && (wIndex <= 3))
    {
      psUDP->UDP_CSR = 0;
      KEYF_USB_SendZlp(psUDP);
    }
    else
      KEYF_USB_SendStall(psUDP);
    break;
   
case STD_CLEAR_FEATURE_ZERO:
    KEYF_USB_SendStall(psUDP);
    break;
   
case STD_CLEAR_FEATURE_INTERFACE:
    KEYF_USB_SendZlp(psUDP);
    break;
   
case STD_CLEAR_FEATURE_ENDPOINT:
    wIndex &= 0x0F;
    if ( (wValue == 0) && wIndex && (wIndex <= 3))
    {
      if (wIndex == 1)
      psUDP->UDP_CSR = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT);
      else if (wIndex == 2)
        psUDP->UDP_CSR = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN);
      else if (wIndex == 3)
        psUDP->UDP_CSR = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_ISO_IN);
        KEYF_USB_SendZlp(psUDP);
    }
    else
      KEYF_USB_SendStall(psUDP);
    break;
   
    // 处理CDC类请求
case SET_LINE_CODING:
    while ( !(psUDP->UDP_CSR & AT91C_UDP_RX_DATA_BK0) );
    psUDP->UDP_CSR &= ~(AT91C_UDP_RX_DATA_BK0);
    KEYF_USB_SendZlp(psUDP);
    break;

case GET_LINE_CODING:
    KEYF_USB_SendData(psUDP, (char *) &line, Min(sizeof(line), wLength));
    break;
   
case SET_CONTROL_LINE_STATE:
    pskeyUSB->USBConnection = wValue;
    KEYF_USB_SendZlp(psUDP);
    break;
   
default:
    KEYF_USB_SendStall(psUDP);
    break;   
}
}

/* Fuction ********************************************************************/
//名称: KEYF_USB_SendData
//功能: 通过端点0发送数据到主机
//参数: USB寄存器, 数据地址, 数据长度
//返回值: 无
//说明: 在配置USB期间,控制端点只能发送8字节数据,而且最多只发送8字节
/* Fuction ********************************************************************/
static void KEYF_USB_SendData ( AT91PS_UDP psUDP, const char *pData, uint length)
{
uint count = 0;
AT91_REG usb_csr;

do
{
    count = Min(length, 8);
    length -= count;
    while ( count-- ) psUDP->UDP_FDR = *pData++;
   
    if ( psUDP->UDP_CSR & AT91C_UDP_TXCOMP ) // 主机已经成功接收到数据
    {
      psUDP->UDP_CSR &= ~(AT91C_UDP_TXCOMP); // 清除标志
      while ( psUDP->UDP_CSR & AT91C_UDP_TXCOMP );
    }
   
    psUDP->UDP_CSR |= AT91C_UDP_TXPKTRDY; // 固件通知外设数据入FIFO
   
    do// 等待主机发"已经接收到数据信息" - (TXCOMP = 1)
    {
      usb_csr = psUDP->UDP_CSR;
      if (usb_csr & AT91C_UDP_RX_DATA_BK0) // 外设"数据存入FIFO零"完成
      {
      psUDP->UDP_CSR &= ~(AT91C_UDP_RX_DATA_BK0);// 清除标志
      return;
      }
    }while ( !(usb_csr & AT91C_UDP_TXCOMP) );   
}while (length);

if (psUDP->UDP_CSR & AT91C_UDP_TXCOMP) // 发送完成后,清除TXCOMP标志a
{
    psUDP->UDP_CSR &= ~(AT91C_UDP_TXCOMP);
    while ( psUDP->UDP_CSR & AT91C_UDP_TXCOMP );
}
}

/* Fuction ********************************************************************/
//名称: KEYF_USB_SendZlp
//功能: 通过控制端点0发送零数据包
//参数: USB寄存器
//返回值: 无
//说明: 因为发送的是零长度包,所以不需要检测外设是否已经完成"数据入FIFO"
/* Fuction ********************************************************************/
void KEYF_USB_SendZlp ( AT91PS_UDP psUDP )
{
psUDP->UDP_CSR |= AT91C_UDP_TXPKTRDY;
while ( !(psUDP->UDP_CSR & AT91C_UDP_TXCOMP) );
psUDP->UDP_CSR &= ~(AT91C_UDP_TXCOMP);
while ( psUDP->UDP_CSR & AT91C_UDP_TXCOMP );
}

/* Fuction ********************************************************************/
//名称: KEYF_USB_SendStall
//功能: 停止控制端点
//参数: USB寄存器
//返回值: 无
//说明: 无
/* Fuction ********************************************************************/
void KEYF_USB_SendStall ( AT91PS_UDP psUDP )
{
psUDP->UDP_CSR |= AT91C_UDP_FORCESTALL;// 端点进入stall状态
while( !(psUDP->UDP_CSR & AT91C_UDP_ISOERROR) ); // 等待主机应答stall
psUDP->UDP_CSR &= ~(AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR);// 清除标志
while ( psUDP->UDP_CSR & (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR) );
}

/* Fuction ********************************************************************/
//名称: KEYF_USB_Write
//功能: 通过"输入端点"发送数据
//参数: USB全局结构体, 数据地址, 数据长度
//返回值: 传输剩余长度length
//说明: 如果修改端点序号,请在"at91usb_conf.h"中直接修改"AT91C_IN_EP"
/* Fuction ********************************************************************/
static uintKEYF_USB_Write ( KEYS_USB *pskeyUSB, const char *pData, uint length )
{
AT91PS_UDPpsUDP = pskeyUSB->psUSB;
uint      count = 0;

count = Min( length, AT91C_EP_IN_SIZE );// 发送第一个数据包
length -= count;
while (count--) psUDP->UDP_FDR = *pData++;
psUDP->UDP_CSR |= AT91C_UDP_TXPKTRDY;

while (length)
{
    count = Min ( length, AT91C_EP_IN_SIZE );
    length -= count;   
    while (count--) psUDP->UDP_FDR =*pData++;
   
    while ( !(psUDP->UDP_CSR & AT91C_UDP_TXCOMP) ) // 等待主机完成数据接收
      if ( !KEYF_IsUSBConfigured(pskeyUSB) ) return length;// 设备没有被配置
   
    psUDP->UDP_CSR &= ~(AT91C_UDP_TXCOMP); // 清除标志
    while ( psUDP->UDP_CSR & (AT91C_UDP_TXCOMP) );
   
    psUDP->UDP_CSR |= AT91C_UDP_TXPKTRDY;// 通知数据准备发送到主机
}

while ( !(psUDP->UDP_CSR & AT91C_UDP_TXCOMP) ) // 等待主机应答
    if ( !KEYF_IsUSBConfigured(pskeyUSB) ) return length;// 设备没有被配置

psUDP->UDP_CSR &= ~AT91C_UDP_TXCOMP;
while ( psUDP->UDP_CSR & AT91C_UDP_TXCOMP );
//KEYF_Toggle_LED ( LED2 );
AT91F_PIO_ClearOutput ( AT91C_BASE_PIOA, LED2 );
return length;
}

/* Fuction ********************************************************************/
//名称: KEYF_USB_Read
//功能: 通过"输出端点"接收数据
//参数: USB全局结构体, 数据地址, 数据地址
//返回值: 收到的数据
//说明: 如果修改端点序号,请在"at91usb_conf.h"中直接修改"AT91C_OUT_EP"
/* Fuction ********************************************************************/
static uintKEYF_USB_Read ( KEYS_USB *pskeyUSB, char *pData, uint length )
{
AT91PS_UDP psUDP = pskeyUSB->psUSB;
uint packetSize, nbBytesRcv = 0, currentReceiveBank = pskeyUSB->USBRcvBank;

while (length)
{
    if ( !KEYF_IsUSBConfigured(pskeyUSB) ) // 设备没有配置好
      break;
    if ( psUDP->UDP_CSR & currentReceiveBank )// FIFO中收到数据包
    {
      packetSize = Min( psUDP->UDP_CSR >> 16, length);        //
      length -= packetSize;
      
      if ( packetSize < AT91C_EP_OUT_SIZE )
              length = 0;
             
      while ( packetSize--)
              pData = psUDP->UDP_FDR;
      psUDP->UDP_CSR &= ~(currentReceiveBank);
      
      if (currentReceiveBank == AT91C_UDP_RX_DATA_BK0)        //
              currentReceiveBank = AT91C_UDP_RX_DATA_BK1;
      else
              currentReceiveBank = AT91C_UDP_RX_DATA_BK0;                     
    }
}
pskeyUSB->USBRcvBank = currentReceiveBank;
return nbBytesRcv;
}

eworker 发表于 2010-12-14 20:24:41

回复【11楼】bj-stm8 珍惜生命 远离天_朝
-----------------------------------------------------------------------

很好的资料,LZ打个包一起发上来?

bj-stm8 发表于 2010-12-15 08:50:26

回复【25楼】eworker
回复【11楼】bj-stm8 珍惜生命 远离天_朝
-----------------------------------------------------------------------
很好的资料,lz打个包一起发上来?
-----------------------------------------------------------------------

不打包,因为有我们的应用程序在里面,需要剔除后才能发布

eworker 发表于 2010-12-15 08:57:54

回复【26楼】bj-stm8 珍惜生命 远离天_朝
回复【25楼】eworker
回复【11楼】bj-stm8 珍惜生命 远离天_朝
-----------------------------------------------------------------------
很好的资料,lz打个包一起发上来?
-----------------------------------------------------------------------
不打包,因为有我们的应用程序在里面,需要剔除后才能发布
-----------------------------------------------------------------------

多发几个设计文档,其实文档意义更大些!

bj-stm8 发表于 2010-12-15 11:23:51

回复【27楼】eworker
-----------------------------------------------------------------------
多发几个设计文档,其实文档意义更大些!
-----------------------------------------------------------------------

是的,文档写好了很容易忽悠老板的。老板看到会感觉非常有成果。
如果你是做事直接读代码好了

eworker 发表于 2010-12-16 11:02:44

回复【28楼】bj-stm8 珍惜生命 远离天_朝
回复【27楼】eworker
-----------------------------------------------------------------------
多发几个设计文档,其实文档意义更大些!
-----------------------------------------------------------------------
是的,文档写好了很容易忽悠老板的。老板看到会感觉非常有成果。
如果你是做事直接读代码好了
-----------------------------------------------------------------------

虽然有代码就是文档的说法,......

bj-stm8 发表于 2010-12-16 15:54:55

http://cache.amobbs.com/bbs_upload782111/files_35/ourdev_604986XRDQJS.jpg
(原文件名:usb.jpg)

lininglive 发表于 2010-12-16 17:34:27

mark mark mark

bj-stm8 发表于 2011-4-27 09:21:44

中通680108186766 发货11套zigbee,另外送AT91SAM7S64一套

znjerase123456 发表于 2011-4-30 23:38:44

mark, appreciate your great support!

bj-stm8 发表于 2011-8-15 09:41:05

大量AT91SAM7S64成品库存急需处理,欢迎联系

taitzhang 发表于 2011-8-16 09:15:18

代码是程序员的文档,文档时BOSS的程序

bj-stm8 发表于 2011-8-24 09:04:22

深圳汪工,中通快递单号:201032362507
AT91SAM7S64,20片拆板芯片,请查收!

另外,为了让更多的坛友能得到芯片。10片也发货,10元一片

kingsabbit 发表于 2011-8-24 10:26:54

我觉得这个片子的库很烂

bj-stm8 发表于 2011-8-24 15:29:04

回复【37楼】kingsabbit 电子白菜
我觉得这个片子的库很烂
-----------------------------------------------------------------------

我觉得多数人要这个片子是为了搞jlink

wuhai85 发表于 2011-9-8 09:27:41

谢谢。

2fen 发表于 2011-12-5 11:14:33

这个模块又有10套了,带塑料外壳,测试完好,提供源代码,每个49元!

jordonwu 发表于 2011-12-5 13:20:54

mark

lovewwy 发表于 2011-12-5 19:53:53

mark .

hushui 发表于 2012-1-17 09:25:00

怎么交易啊   还有吗 楼主??

2fen 发表于 2012-1-17 10:01:27

淘宝联系,年后发货
页: [1]
查看完整版本: AT91SAM7S64资料汇总,感兴趣的朋友请进