这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » wenyangzeng ARM DIY进程贴 红外解码

共107条 4/11 |‹ 2 3 4 5 6 7 ›| 跳转至
工程师
2012-04-19 22:44:32     打赏
31楼

ARM DIY进程7:I2C

    有了上例的串行通讯调试终端,接下来的I2C1调试就很方便,只要一条printf()就把24C02的读写内容都显示在屏幕上了。I2C1的设置先设置GPIO引脚为开漏输出,然后初始化I2C1工作模式、主机地址、速率。初始化完成后就可以对其进行读写了。下图是读写结果通过串口发送到PC机的截屏,上次练习关于串口的初始化函数就不列出了。


                                                                                                   图1 I2C读写结果


工程师
2012-04-19 22:45:52     打赏
32楼

相关代码:

#include "stm32f10x.h"
#include <stdio.h>
#define AT24C01A
u16 speed=2000;
u16   Count=0;
RCC_ClocksTypeDef RCC_ClockFreq;
void GPIO_Configuration(void) ;
void I2C_Configuration(void);
void Delay(u16 speed);
extern void I2C_Test(void);
extern  void USART_Configuration(void);

int main(void)
{   
 SystemInit();
 RCC_GetClocksFreq(&RCC_ClockFreq);
 GPIO_Configuration();
 I2C_Configuration();
  USART_Configuration();
  printf("写入24C02芯片128字节:\r\n");
  I2C_Test();
  while (1)
  { 
  }
}

//--------
//I2C函数
//--------

#include "stm32f10x.h"
#include <stdio.h>
#define AT24C01A
#define EEPROM_ADDR 0xA0
#define I2C_PAGESIZE 4
void I2C_Configuration(void)
{
    I2C_InitTypeDef  I2C_InitStructure;
    GPIO_InitTypeDef  GPIO_InitStructure;
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_5|GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    I2C_DeInit(I2C1);
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
    I2C_InitStructure.I2C_OwnAddress1 = 0x30;
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C_InitStructure.I2C_ClockSpeed = 100000;
    I2C_Cmd(I2C1, ENABLE);
    I2C_Init(I2C1, &I2C_InitStructure);
    I2C_AcknowledgeConfig(I2C1, ENABLE);
    GPIOB->ODR &=~0xff2f;

}

//-----------
//I2C_ReadS
//------------
void I2C_ReadS_24C(u8 addr ,u8* pBuffer,u16 no)
{
    if(no==0)
 return;
 while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
 I2C_AcknowledgeConfig(I2C1, ENABLE);
    I2C_GenerateSTART(I2C1, ENABLE);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));/*EV5,主模式*/
 I2C_Send7bitAddress(I2C1, addr<<1, I2C_Direction_Receiver);
 while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
    while (no)
    {
  if(no==1)
  {
       I2C_AcknowledgeConfig(I2C1, DISABLE); 
      I2C_GenerateSTOP(I2C1, ENABLE); 
  }
    
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
     *pBuffer = I2C_ReceiveData(I2C1);
     pBuffer++;
     no--;
    }
 I2C_AcknowledgeConfig(I2C1, ENABLE);
}

/-----------------
//I2C_Standby_24C
/------------------
void I2C_Standby_24C(void)     
{
  vu16 SR1_Tmp;
  do
  {
    I2C_GenerateSTART(I2C1, ENABLE);
    SR1_Tmp = I2C_ReadRegister(I2C1, I2C_Register_SR1);
 I2C_Send7bitAddress(I2C1, 0, I2C_Direction_Transmitter);
  }while(!(I2C_ReadRegister(I2C1, I2C_Register_SR1) & 0x0002));
  I2C_ClearFlag(I2C1, I2C_FLAG_AF);
  I2C_GenerateSTOP(I2C1, ENABLE);
}

//------------------
//I2C_ByteWrite_24C
//-----------------
void I2C_ByteWrite_24C(u8 addr,u8 dat)
{
   I2C_GenerateSTART(I2C1, ENABLE);
   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); 
 I2C_Send7bitAddress(I2C1, addr<<1, I2C_Direction_Transmitter);
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
   I2C_SendData(I2C1, dat);
   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
   I2C_GenerateSTOP(I2C1, ENABLE);
   I2C_Standby_24C();
}
//--------------------------
//函数名:I2C_PageWrite_24C
//--------------------------
void I2C_PageWrite_24C(u8 addr,u8* pBuffer, u8 no)
{
 while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
 I2C_GenerateSTART(I2C1, ENABLE);
 while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
 I2C_Send7bitAddress(I2C1, addr<<1, I2C_Direction_Transmitter);
 while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
 while(no--) 
 {
   I2C_SendData(I2C1, *pBuffer);
   pBuffer++;
   while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
 }
 I2C_GenerateSTOP(I2C1, ENABLE);
}
//--------------------
//I2C_WriteS_24C
//-------------------
void I2C_WriteS_24C(u8 addr,u8* pBuffer,  u16 no)
{ u8 temp;
 temp=addr % I2C_PAGESIZE;
 if(temp)
 {
  temp=I2C_PAGESIZE-temp;
  I2C_PageWrite_24C(addr,pBuffer,  temp);
  no-=temp;
  addr+=temp;
  pBuffer+=temp;
  I2C_Standby_24C();
 }
 while(no)
 {
  if(no>=I2C_PAGESIZE)
  {
   I2C_PageWrite_24C(addr,pBuffer,  I2C_PAGESIZE);
   no-=I2C_PAGESIZE;
   addr+=I2C_PAGESIZE;
   pBuffer+=I2C_PAGESIZE;
   I2C_Standby_24C();
  }
  else
  {
   I2C_PageWrite_24C(addr,pBuffer,  no);
   no=0;
   I2C_Standby_24C();
  }
 }
}

void I2C_Test(void)
{
 u8 i;
 u8 I2c_Buf[128];
 for(i=0;i<128;i++)
  {
  I2c_Buf[i]=i;
   printf(" %x",i);
   }
 I2C_PageWrite_24C(4,I2c_Buf,  4);
  printf("\r\n");
 printf("读出24C02芯片128字节:\r\n");
 for(i=0;i<128;i++)
  I2c_Buf[i]=0;
 I2C_Standby_24C();
 I2C_ReadS_24C(0,I2c_Buf,8);

 for(i=0;i<128;i++)
  I2c_Buf[i]=i;
 I2C_WriteS_24C(0,I2c_Buf,128);
 for(i=0;i<128;i++)
  I2c_Buf[i]=0;
 I2C_ReadS_24C(0,I2c_Buf,128);
 
 for(i=0;i<128;i++)
 {  printf(" %x",I2c_Buf[i]);
  if(I2c_Buf[i]!=i)

   printf("I2C测试失败");
 }

}

 


工程师
2012-04-21 15:26:15     打赏
33楼

ARM DIY进程8:SD卡读FAT文件

    读写SD卡分普通SD(SPI)和SDHC(4总线)方式,老的STM32固件库的例程只支持SPI方式,4总线方式听说只有V3.4版固件库可用,V3.5版反而用不起来了。查阅开发板硬件连接,才知道我们的DIY板还挺超前的。只支持4总线方式,无奈我的固件库现在使用的是V3.5版,也“超前”了点,看来4总线方式读写SD卡是用不起来了。不死心借来一块STM32108PKT板来熟悉一下SPI的SD卡练习。


                     
                                              图1 借来的STM32108PKT开发板

    STM32108PKT板读SD卡SIP方式要用到连接线有:GPIOA_4-CS,GPIOA_5-CLK,GPIOA_6-MISO,GPIOA_7-MOSI。SD卡预先在PC机上创建一个子目录\ARM_DIY\,在子目录里建立一个文本文件ARM_DIY.TXT。ARM_DIY.TXT写进一些文本供显示用。 
    USART1连接到PC机的串口作显示终端。运行时提示插入预先建立了子目录和文件的SD卡,然后按住开发板上的“SELECT”键,在显示终端上显示ARM_DIY.TXT文件的内容。




                    图2 SD卡的文件总算读出来了,知其然不知其所以然也,要是老板给我一个SD卡开发项目,我的头就大了

    哪位网友如果用4总线方式在ARM开发板上读写SD卡成功了,记得一起分享喔!


工程师
2012-04-21 15:28:22     打赏
34楼

相关代码:

#include "STM32Lib\\stm32f10x.h"
#define GET_SELECT()(!GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7))
void TestBoard(void);
int main(void)
{
 SystemInit();
 RCC_GetClocksFreq(&RCC_ClockFreq);
 RCC_Configuration();
 USART_Configuration();
 USART1_Puts("\r\n 测试SD卡,请把SD卡插入,并确保存在/ARM_DIY/ARM_DIY.txt \r\n"); /
 TurnToSD();
 USART1_Puts("\r\n 按下SELECT键显示SD卡ARM_DIY子目录中的ARM_DIT.TXT文件内容\r\n");
 while(!GET_SELECT());
 TestSD();
 for(;;)
 {
 }
}

//------------
//SD.C
//-------------
#include "STM32Lib\\stm32f10x.h"
#include "diskio.h"
#include "tff.h"
#include "hal.h"
//#include "usart.h"
#define CMD0 (0x40+0) /* GO_IDLE_STATE */
#define CMD1 (0x40+1) /* SEND_OP_COND (MMC) */
#define ACMD41 (0xC0+41) /* SEND_OP_COND (SDC) */
#define CMD8 (0x40+8) /* SEND_IF_COND */
#define CMD9 (0x40+9) /* SEND_CSD */
#define CMD10 (0x40+10) /* SEND_CID */
#define CMD12 (0x40+12) /* STOP_TRANSMISSION */
#define ACMD13 (0xC0+13) /* SD_STATUS (SDC) */
#define CMD16 (0x40+16) /* SET_BLOCKLEN */
#define CMD17 (0x40+17) /* READ_SINGLE_BLOCK */
#define CMD18 (0x40+18) /* READ_MULTIPLE_BLOCK */
#define CMD23 (0x40+23) /* SET_BLOCK_COUNT (MMC) */
#define ACMD23 (0xC0+23) /* SET_WR_BLK_ERASE_COUNT (SDC) */
#define CMD24 (0x40+24) /* WRITE_BLOCK */
#define CMD25 (0x40+25) /* WRITE_MULTIPLE_BLOCK */
#define CMD55 (0x40+55) /* APP_CMD */
#define CMD58 (0x40+58) /* READ_OCR */
#define MMC_SELECT()     GPIO_ResetBits(GPIOA, GPIO_Pin_4)       /* MMC CS = L */
#define MMC_DESELECT()   GPIO_SetBits(GPIOA, GPIO_Pin_4)         /* MMC CS = H */

static volatile
DSTATUS Stat = STA_NOINIT;
static
BYTE CardType;
extern volatile
unsigned int Timer1, Timer2;   
void SPI_Release(void);
void MMC_SPI_Config(void)
{
}
void TurnToSD(void)
{
    SPI_InitTypeDef  SPI_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA  |
            RCC_APB2Periph_GPIOC |
            RCC_APB2Periph_AFIO |
            RCC_APB2Periph_SPI1,
            ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_SetBits(GPIOA, GPIO_Pin_4);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    SPI_Cmd(SPI1, DISABLE); //必须要有才能改变MODE
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;       
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;      
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;        
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;       
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;        
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;      
    SPI_InitStructure.SPI_CRCPolynomial = 7;        
    SPI_Init(SPI1, &SPI_InitStructure);
    SPI_Cmd(SPI1, ENABLE);
 SPI_Release(); 
}

#define NULL 0
void TestSD(void)
{FATFS fs;
    FIL fil;
 FRESULT res;
 char byte[65];
    u32 len;
 f_mount(0,&fs);
 res=f_open(&fil,"/ARM_dIY/ARM_diy.txt",FA_OPEN_EXISTING|FA_READ);
    if(res!=FR_OK)
    {
       printf("SD卡打开文件失败\r\n");
       return;
    }

    for(;;)
 {
        res = f_read(&fil, byte, sizeof(byte)-1, &len);
     if (res || len == 0)
            break;
     byte[len]='\0';
        printf(byte);
 }
    f_close(&fil);
    f_mount(0, NULL);
}

static
u8 SPI_ReadWrite_Byte(unsigned char byte)
{
    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
    SPI_I2S_SendData(SPI1, byte);
    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
    return SPI_I2S_ReceiveData(SPI1); 
}
static
void SPI_LowSpeed(void)
{
    SPI_InitTypeDef  SPI_InitStructure;
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial = 7;
    SPI_Cmd(SPI1, ENABLE);
}

static
void SPI_HighSpeed(void)
{
    SPI_InitTypeDef  SPI_InitStructure;
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial = 7;
    SPI_Init(SPI1, &SPI_InitStructure);
    SPI_Cmd(SPI1, ENABLE);
}

static
BYTE Wait_Ready (void)
{
    BYTE res;
    Timer2 = 50;
    SPI_ReadWrite_Byte(0xff);;
    do{
        res = SPI_ReadWrite_Byte(0xff);
    }while ((res != 0xFF) && Timer2);

    return res;
}
static
void SPI_Release(void)
{
    MMC_DESELECT();
    SPI_ReadWrite_Byte(0xff);;
}

#define MMC_POWERON()
#define MMC_POWEROFF()
int chk_power(void)
{
    return 1;
}
static
bool Receive_DataBlock(
        BYTE *buff,
        UINT btr 
        )
{
    BYTE token;
    Timer1 = 10;
    do {        token = SPI_ReadWrite_Byte(0xff);
    } while ((token == 0xFF) && Timer1);
    if(token != 0xFE) return FALSE;
    do { *buff++ = SPI_ReadWrite_Byte(0xff);
    } while (btr--);
    SPI_ReadWrite_Byte(0xff);
    SPI_ReadWrite_Byte(0xff);
    return TRUE;
}
#if _READONLY == 0
static
bool Transmit_DataBlock (
        const BYTE *buff,
        BYTE token
        )
{
    BYTE resp;
    UINT wc;
    if (Wait_Ready() != 0xFF) return FALSE;
    SPI_ReadWrite_Byte(token);
    if (token != 0xFD) {
        wc = 512;
        do { SPI_ReadWrite_Byte(*buff++);
        } while (--wc);
        SPI_ReadWrite_Byte(0xFF);
        SPI_ReadWrite_Byte(0xFF);
        resp = SPI_ReadWrite_Byte(0xff);
        if ((resp & 0x1F) != 0x05)
            return FALSE;
    }
    return TRUE;
}
#endif
static
BYTE Send_Command(
        BYTE cmd,
        DWORD arg
        )
{
    BYTE n, res;
    if (cmd & 0x80) {
        cmd &= 0x7F;
        res = Send_Command(CMD55, 0);
        if (res > 1) return res;
    }
   MMC_DESELECT();
    MMC_SELECT();
    if (Wait_Ready() != 0xFF) return 0xFF;
    SPI_ReadWrite_Byte(cmd);
    SPI_ReadWrite_Byte((BYTE)(arg >> 24));
    SPI_ReadWrite_Byte((BYTE)(arg >> 16));
    SPI_ReadWrite_Byte((BYTE)(arg >> 8));
    SPI_ReadWrite_Byte((BYTE)arg);
    n = 0x01;
    if (cmd == CMD0) n = 0x95;
    if (cmd == CMD8) n = 0x87;
    SPI_ReadWrite_Byte(n);
    if (cmd == CMD12) {
        SPI_ReadWrite_Byte(0xff);     
    }
    n = 10;        
    do{
        res = SPI_ReadWrite_Byte(0xff);
    }while ((res & 0x80) && --n);

    return res; 
}

DSTATUS disk_initialize (
        BYTE drv
        )
{
    BYTE n, cmd, ty, ocr[4];
    if (drv) return STA_NOINIT; 
    if (Stat & STA_NODISK) return Stat; 
    MMC_SPI_Config(); //初始化IO
     MMC_POWERON(); 
    for(Timer1=50; Timer1; );             
    SPI_LowSpeed();   
    MMC_DESELECT();
    Timer1 = 500;
    do{
        for (n = 10; n; n--) SPI_ReadWrite_Byte(0xff);
    }
    while((Send_Command(CMD0,0) != 1) && Timer1);

    ty = 0;
    Timer1 = 200;
    if (Send_Command(CMD8, 0x1AA) == 1) {
        for (n = 0; n < 4; n++)
            ocr[n] = SPI_ReadWrite_Byte(0xff);
        if (ocr[2] == 0x01 && ocr[3] == 0xAA) {   
            while (Timer1 && Send_Command(ACMD41, 1UL << 30));      
            if (Timer1 && Send_Command(CMD58, 0) == 0) {  
                for (n = 0; n < 4; n++)
                    ocr[n] = SPI_ReadWrite_Byte(0xff);
                ty = (ocr[0] & 0x40) ? 12 : 4;
            }
        }
    } else {       
        if (Send_Command(ACMD41, 0) <= 1) {
            ty = 2; cmd = ACMD41;
        } else {
            ty = 1; cmd = CMD1; 
        }
        while (Timer1 && Send_Command(cmd, 0)); 
        if (!Timer1 || Send_Command(CMD16, 512) != 0)
            ty = 0;
    }

    CardType = ty; 
    SPI_HighSpeed();
    SPI_Release();
    if (ty) {
        Stat &= ~STA_NOINIT; 
    } else {              
        MMC_POWEROFF();
    }
    return Stat;
}
DSTATUS disk_status (
        BYTE drv
        )
{
    if (drv) return STA_NOINIT; 
    return Stat;
}
DRESULT disk_read (
        BYTE drv,
        BYTE *buff,
        DWORD sector,
        BYTE count
        )
{
    if (drv || !count) return RES_PARERR;
    if (Stat & STA_NOINIT) return RES_NOTRDY;
    if (!(CardType & 8)) sector *= 512;
    if (count == 1) {
        if ((Send_Command(CMD17, sector) == 0)
                && Receive_DataBlock(buff, 512))
            count = 0;
    }
    else {
        if (Send_Command(CMD18, sector) == 0) {
            do {
                if (!Receive_DataBlock(buff, 512)) break;
                buff += 512;
            } while (--count);
            Send_Command(CMD12, 0);
        }
    }
    SPI_Release();
    return count ? RES_ERROR : RES_OK;
}
#if _READONLY == 0
DRESULT disk_write (
        BYTE drv,
        const BYTE *buff,
        DWORD sector, 
        BYTE count
        )
{
    if (drv || !count) return RES_PARERR;
    if (Stat & STA_NOINIT) return RES_NOTRDY;
    if (Stat & STA_PROTECT) return RES_WRPRT;

    if (!(CardType & 8)) sector *= 512; 

    if (count == 1) {
        if ((Send_Command(CMD24, sector) == 0)
                && Transmit_DataBlock(buff, 0xFE))
            count = 0;
    }
    else {     if (CardType & 6) Send_Command(ACMD23, count);
        if (Send_Command(CMD25, sector) == 0) {
            do {
                if (!Transmit_DataBlock(buff, 0xFC)) break;
                buff += 512;
            } while (--count);
            if (!Transmit_DataBlock(0, 0xFD))
                count = 1;
        }
    }
    SPI_Release();

    return count ? RES_ERROR : RES_OK;
}
#endif

#if _USE_IOCTL != 0
DRESULT disk_ioctl (
        BYTE drv,
        BYTE ctrl,
        void *buff
        )
{
    DRESULT res;
    BYTE n, csd[16], *ptr = buff;
    WORD csize;
    if (drv) return RES_PARERR;
    res = RES_ERROR;
    if (ctrl == CTRL_POWER) {
        switch (*ptr) {
            case 0:
                if (chk_power())
                    MMC_POWEROFF();
                res = RES_OK;
                break;
            case 1: 
                MMC_POWERON();
                res = RES_OK;
                break;
            case 2:
                *(ptr+1) = (BYTE)chk_power();
                res = RES_OK;
                break;
            default :
                res = RES_PARERR;
        }
    }
    else {
        if (Stat & STA_NOINIT) return RES_NOTRDY;

        switch (ctrl) {
            case CTRL_SYNC :
                MMC_SELECT();
                if (Wait_Ready() == 0xFF)
                    res = RES_OK;
                break;
            case GET_SECTOR_COUNT :
                if ((Send_Command(CMD9, 0) == 0) && Receive_DataBlock(csd, 16)) {
                    if ((csd[0] >> 6) == 1) {
                        csize = csd[9] + ((WORD)csd[8] << 8) + 1;
                        *(DWORD*)buff = (DWORD)csize << 10;
                    } else { 
                        n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
                   csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1;
                        *(DWORD*)buff = (DWORD)csize << (n - 9);
                    }
                    res = RES_OK;
                }
                break;
            case GET_SECTOR_SIZE :
                *(WORD*)buff = 512;
                res = RES_OK;
                break;

            case GET_BLOCK_SIZE :
                if (CardType & 4) {
                    if (Send_Command(ACMD13, 0) == 0) { 
                        SPI_ReadWrite_Byte(0xff);
                        if (Receive_DataBlock(csd, 16)) {
                            for (n = 64 - 16; n; n--) SPI_ReadWrite_Byte(0xff); 
                            *(DWORD*)buff = 16UL << (csd[10] >> 4);
                            res = RES_OK;
                        }
                    }
                } else {
                    if ((Send_Command(CMD9, 0) == 0) && Receive_DataBlock(csd, 16)) {
                        if (CardType & 2) {
                            *(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7)

+ 1) << ((csd[13] >> 6) - 1);
                        } else {
                            *(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3)

<< 3) + ((csd[11] & 224) >> 5) + 1);
                        }
                        res = RES_OK;
                    }
                }
                break;

            case MMC_GET_TYPE : 
                *ptr = CardType;
                res = RES_OK;
                break;

            case MMC_GET_CSD : 
                if (Send_Command(CMD9, 0) == 0 
                        && Receive_DataBlock(ptr, 16))
                    res = RES_OK;
                break;

            case MMC_GET_CID : 
                if (Send_Command(CMD10, 0) == 0 
                        && Receive_DataBlock(ptr, 16))
                    res = RES_OK;
                break;

            case MMC_GET_OCR : 
                if (Send_Command(CMD58, 0) == 0) {
                    for (n = 4; n; n--) *ptr++ = SPI_ReadWrite_Byte(0xff);
                    res = RES_OK;
                }
                break;

            case MMC_GET_SDSTAT :
                if (Send_Command(ACMD13, 0) == 0) {
                    SPI_ReadWrite_Byte(0xff);
                    if (Receive_DataBlock(ptr, 64))
                        res = RES_OK;
                }
                break;

            default:
                res = RES_PARERR;
        }

    }
   
    SPI_Release();
    return res;
}
#endif

DWORD get_fattime (void)
{
    return 0; 
}
太长了,还有一个TTF.C就不贴了。


工程师
2012-04-25 22:28:39     打赏
35楼

ARM DIY进程9:正弦波信号发生器(3相50HZ)

       练习利用STM32定时器1的PWM输出和定时器2的溢出中断功能,产生50HZ的3相正弦波信号。要在实验室或家中使用到三相交流电来调试嵌入式系统,有时还真是件不容易的事情。有了这个信号发生器,就方便多了。
        要使用定时器,先要打开stm32f10x_conf.h中的#include "stm32x_tim.h"和#include "stm32x_misc.h",开放定时器总线.定时器1的CCR1、CCR2、CCR3通道分别对应GPIOA_PIN8-PIN11,需要将其设置为GPIO_Mode_AF_PP模式。定时器1负责PWM输出,定时器2负责在中断中查表更新各路PWM的CCRx值,得到不同的占空比。3路PWM脉冲输出经过RC滤波器(见图1)后产生相位相差120度的50HZ正弦波信号。示波器只有2踪,以B相时间轴为基准,分别拍摄了A-B和B-C的波形。

                     
                                                                 图1  外接的RC滤波器


                                                               图2  A-B 相波形


                                                    图3  B-C相波形


工程师
2012-04-25 22:29:34     打赏
36楼


代码
//------
//main.c
//------
#include "STM32Lib\\stm32f10x.h"
u8 const pwm_duty[]={
0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,
0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,0xd8,
0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf5,
0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,
0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0xde,0xdc,
0xda,0xd8,0xd5,0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb3,
0xb0,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x98,0x95,0x92,0x8f,0x8c,0x89,0x86,0x83,
0x80,0x7c,0x79,0x76,0x73,0x70,0x6d,0x6a,0x67,0x63,0x60,0x5d,0x5a,0x57,0x54,0x51,
0x4f,0x4c,0x49,0x46,0x43,0x40,0x3e,0x3b,0x38,0x36,0x33,0x31,0x2e,0x2c,0x2a,0x27,
0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x12,0x10,0x0f,0x0d,0x0c,0x0a,
0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,
0x09,0x0a,0x0c,0x0d,0x0f,0x10,0x12,0x13,0x15,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x23,
0x25,0x27,0x2a,0x2c,0x2e,0x31,0x33,0x36,0x38,0x3b,0x3e,0x40,0x43,0x46,0x49,0x4c,
0x4f,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,0x67,0x6a,0x6d,0x70,0x73,0x76,0x79,0x7c};
int main(void)

 RCC_Configuration();
 GPIO_Configuration();
 Tim1_Configuration();
 NVIC_Configuration();
 for(;;)
 {
 }
}
//-------
//NVIC.C
//-------
#include "STM32Lib\\stm32f10x.h"
void NVIC_Configuration(void)
{
 NVIC_InitTypeDef NVIC_InitStructure;
 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
 NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
 NVIC_Init(&NVIC_InitStructure);
}
//-------
//GPIO.C
//-------
void GPIO_Configuration(void)
{ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
 GPIO_InitTypeDef GPIO_InitStructure;
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //开漏输出
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M时钟速度
 GPIO_Init(GPIOA, &GPIO_InitStructure);
}
//-------
//TIM.C
//------- 
#include "STM32Lib\\stm32f10x.h"
void Tim1_Configuration(void)
{
 TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
 TIM_OCInitTypeDef  TIM_OCInitStructure;
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
 TIM_DeInit(TIM1);
 TIM_TimeBaseStructure.TIM_Prescaler = 10;
 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
 TIM_TimeBaseStructure.TIM_Period = 256; 
 TIM_TimeBaseStructure.TIM_ClockDivision = 0;
 TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0;
 TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);
 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
 TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
 TIM_OCInitStructure.TIM_Pulse = 1;
 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
 TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; 
 TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
 TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; 
 TIM_OC1Init(TIM1,&TIM_OCInitStructure);
 TIM_OC2Init(TIM1,&TIM_OCInitStructure);
 TIM_OC3Init(TIM1,&TIM_OCInitStructure);
 TIM1->CCR1=1;
  TIM1->CCR2=33;
 TIM1->CCR3=66;
 TIM1->CR2   &=~0x01;
  TIM_CtrlPWMOutputs(TIM1,ENABLE);
 TIM_Cmd(TIM1,ENABLE);

 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
 TIM_DeInit(TIM2);
 TIM_TimeBaseStructure.TIM_Prescaler = 20;
 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
 TIM_TimeBaseStructure.TIM_Period = 267; 
 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV2;
 TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0;
 TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);
 TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
 TIM_ITConfig(TIM2,TIM_IT_Update, ENABLE);
 TIM_Cmd(TIM2,ENABLE);
}
//-------
//中断函数
//------
void TIM2_IRQHandler(void)
{
 static unsigned char i=0;
 static unsigned char j=85;
 static unsigned char k=170;
  if (TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET)
   {
   TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
      TIM1->CCR1 =  pwm_duty[i];
      TIM1->CCR2 =pwm_duty[j];
      TIM1->CCR3 = pwm_duty[k];
      i++;
   j++;
   k++;
    }
   return;
}


工程师
2012-05-07 16:26:24     打赏
37楼

ARM DIY进程10:CAN双机通信

    觉得CAN如果玩Polling有点象陆地学游泳,还是搞个双机通信才能真正体会真实效果,但这需要2台STM32。弄来一部万利EK-STM32F,这种开发板不知道当初为何要捆绑J-LINK下载器在板上,而且其驱动程序只能兼容低版本的IAR,不支持KEIL下载,外部下载器一接上就发生冲突。花费了不少时间对其进行改造,终于能支持KLEIL下载了,并将该板的LCD显示代码从IAR环境移植到了KEIL环境,现在可以实战演练CAN了,呵呵!
    CAN的接收采用中断方式,DIY开发板上的CAN连接到了PB8和PB9,需要对CAN复用功能重映射,参见图1的《用户手册》截图。
GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);
    双机通信中两机的通信协议设置一定要相同,而甲乙两机的ID地址要错开,本例中甲机设为TxMessage.StdId=0x12,乙机设为TxMessage.StdId=0x11 .程序运行过程按住发送键,发送方就将本机的ADC转换结果发送给对方,接收方将传送的数据显示在LCD屏幕上,并根据数值的大小分别点亮1-4只LED。连接2台机器的导线使用了双绞线,H对H,L对L。



                                                             图1



                                                      CAN双机通信连接


工程师
2012-05-07 16:37:50     打赏
38楼


                                                 甲机data<1000     亮 1个LED



                                                 甲机data<2000     亮 2个LED

                                               

工程师
2012-05-07 16:40:06     打赏
39楼


                                  甲机data  <3000亮3个LED



                                   甲机data  >3000亮4个LED

工程师
2012-05-07 16:42:23     打赏
40楼



                                     乙机data  <1000亮1个LED



                                        乙机data  <2000亮2个LED

共107条 4/11 |‹ 2 3 4 5 6 7 ›| 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]