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

共75条 3/8 1 2 3 4 5 6 ›| 跳转至
工程师
2012-04-16 15:11:45     打赏
21楼

ARM DIY进程5:RTC

    曾经玩过HT1380实时时钟,觉得玩STM32的这个RTC应该也没有什么大不了的。岂料真的进入了。才知道并非易事。STM32的RTC只是个简单的秒中断定时器,它的年月日时分秒要存储在备份寄存器中。使用时要开放stm32f10x_bkp.h、stm32f10x_pwr.h和stm32f10x_rtc.h。还要使能内部的RCC_APB1Periph_PWR 和RCC_APB1Periph_BKP,还要开放RTC中断。年月日时分秒,闰年等等都要自己计算。晕!
    如果你想要在DIY开放板上COPY范例代码来直接套用,由于硬件方面牵涉到LCD显示电路引脚的不同和显示代码的差异,真的不像运行跑马灯那样简单了。费了九牛二虎之力,总算让RTC时钟跑起来了。图1中显示结果是相隔1秒拍的2张照片。你的脑子肯定比我聪明,希望你的RTC做的比我的好。



                                                                           图1 RTC时钟动了


工程师
2012-04-16 15:16:56     打赏
22楼

部分代码(看了头真的有点晕)

//主函数
#include "stm32f10x.h"
#include "user.h"
#include "LCD.C"
#include "RTC.C"
int main(void)
{   
 SystemInit();
 RCC_GetClocksFreq(&RCC_ClockFreq);
 GPIO_Configuration();
  TestLCDS();
 RTC_Configuration();
  Clock_Adjustment();

  while (1)
  { 
 byte_disp(5,0,' ');
 byte_disp(5,1,' ');
 byte_disp(5,6,((RealTime.hour)/10)+0x30);
 byte_disp(5,7,((RealTime.hour)%10)+0x30);
 byte_disp(5,8,':');
 byte_disp(5,9,((RealTime.minute)/10)+0x30);
 byte_disp(5,10,((RealTime.minute)%10)+0x30);
 byte_disp(5,11,':');
 byte_disp(5,12,((RealTime.second)/10)+0x30);
 byte_disp(5,13,((RealTime.second)%10)+0x30);

 byte_disp(4,0,' ');
 byte_disp(4,1,' ');
 byte_disp(4,5,'2');
 byte_disp(4,6,'0');
 byte_disp(4,7,((RealTime.year)/10)+0x30);
 byte_disp(4,8,((RealTime.year)%10)+0x30);
 byte_disp(4,9,'/');
 byte_disp(4,10,((RealTime.month)/10)+0x30);
 byte_disp(4,11,((RealTime.month)%10)+0x30);
  byte_disp(4,12,'/');
 byte_disp(4,13,((RealTime.date)/10)+0x30);
 byte_disp(4,14,((RealTime.date)%10)+0x30);


  }
}
//RTC函数
#include "stm32f10x.h"
void RTC2Time(void);
void TimeToRTC(T_STRUCT* time);
void Clock_Adjustment(void) ;
void RTC_IRQHandler(void);
void GetTime(T_STRUCT* time);
static u8 RTC_Blank=0;
void RTC_Configuration(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
 PWR_BackupAccessCmd(ENABLE);
 if(BKP_ReadBackupRegister(BKP_DR1) !=  0xA5A5)
 {
  BKP_DeInit();
  RCC_LSEConfig(RCC_LSE_ON);
  while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)  ==  RESET);
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); 
  RCC_RTCCLKCmd(ENABLE);
  RTC_WaitForSynchro();
  RTC_WaitForLastTask();
  RTC_ITConfig(RTC_IT_SEC, ENABLE);
  RTC_WaitForLastTask();
  RTC_SetPrescaler(32776);
  RTC_WaitForLastTask();
  BKP_WriteBackupRegister(BKP_DR1, 0xA5A5); 
  RTC_Blank = 1; 
 }
   else
 {
    RTC_WaitForSynchro();
  RTC_WaitForLastTask();
  RTC2Time();
    RTC_ITConfig(RTC_IT_SEC, ENABLE); 
    RTC_WaitForLastTask();
   }
 RCC_ClearFlag(); 
}
//----------------------------
extern const u8 Month2Day_Tab[12];
void RTC2Time(void)
{
 u32 count;
 u8 tmp,change = 0;
 RealTime.year  = BKP_ReadBackupRegister(BKP_DR2);
 RealTime.month = BKP_ReadBackupRegister(BKP_DR3);
 RealTime.date  = BKP_ReadBackupRegister(BKP_DR4);
 RealTime.day   = BKP_ReadBackupRegister(BKP_DR5);
 RTC_ITConfig(RTC_IT_SEC, DISABLE);
 count = RTC_GetCounter();
 while(count >= 0x0001517f)
 { change = 1;
  count -= 0x0001517f;
  if((++RealTime.day) >= 8)
   RealTime.day = 1;
  if(RealTime.month == 2)
  {
   if(RealTime.year%4)
    tmp = 28;
   else
    tmp = 29;
  }
  else
  {
   tmp = Month2Day_Tab[RealTime.month-1];
  }
  if((++RealTime.date)>tmp)
  {
   RealTime.date = 1;
   
   if((++RealTime.month)>12)
   {
    RealTime.month = 1;
    
    if((++RealTime.year) >= 100)
    { 
     RealTime.year = 0;
    }
   }
  }
 }
 RealTime.hour = count/3600;
 RealTime.minute = (count%3600)/60;
 RealTime.second = (count%3600)%60;
 if(change)
 {
  RTC_SetCounter(count);
  BKP_WriteBackupRegister(BKP_DR5,RealTime.day);
  BKP_WriteBackupRegister(BKP_DR4,RealTime.date);
  BKP_WriteBackupRegister(BKP_DR3,RealTime.month);
  BKP_WriteBackupRegister(BKP_DR2,RealTime.year);
 }
 RTC_ITConfig(RTC_IT_SEC, ENABLE);
}
//------------------------
void TestRtc(void)
{
 if(RTC_Blank)
 Clock_Adjustment();
}
//---------------------------
void TimeToRTC(T_STRUCT* time)
{
 u32 count;
 RTC_ITConfig(RTC_IT_SEC, DISABLE);
 RTC_WaitForLastTask();
 RealTime.year = time->year;
 RealTime.month = time->month;
 RealTime.date = time->date;
 RealTime.hour = time->hour;
 RealTime.minute = time->minute;
 RealTime.second = time->second;
 RealTime.day = time->day;
 BKP_WriteBackupRegister(BKP_DR5,RealTime.day);
 BKP_WriteBackupRegister(BKP_DR4,RealTime.date);
 BKP_WriteBackupRegister(BKP_DR3,RealTime.month);
 BKP_WriteBackupRegister(BKP_DR2,RealTime.year);
 count = RealTime.hour*3600+RealTime.minute*60+RealTime.second;
 RTC_WaitForLastTask();
 RTC_SetCounter(count);
 RTC_WaitForLastTask();
 RTC_ITConfig(RTC_IT_SEC, ENABLE);
}


工程师
2012-04-16 15:17:52     打赏
23楼

//--------------------------------
void Clock_Adjustment(void)
{      
 T_STRUCT time;
 u8 d[14];
  d[0]=1;
  d[1]=2;
  d[2]=0;
  d[3]=4;
  d[4]=1;
  d[5]=6;
  d[6]=1;
  d[7]=1;
  d[8]=5;
  d[9]=0;
  d[10]=0;
  d[11]=0;
  d[12]=1;
  time.year   = d[0]*10+d[1];
  time.month  = d[2]*10+d[3];
  time.date   = d[4]*10+d[5];
  time.hour   = d[6]*10+d[7];
  time.minute = d[8]*10+d[9];
  time.second = d[10]*10+d[11];
  time.day    = d[12];   
  TimeToRTC(&time);
}
//--------------------------
extern T_STRUCT RealTime;
void GetTime(T_STRUCT* time)
{
 RTC_ITConfig(RTC_IT_SEC, DISABLE);
 RTC_WaitForLastTask();
 time->year = RealTime.year;
 time->month = RealTime.month;
 time->date = RealTime.date;
 time->hour = RealTime.hour;
 time->minute = RealTime.minute;
 time->second = RealTime.second;
 time->day = RealTime.day;
 RTC_WaitForLastTask();
 RTC_ITConfig(RTC_IT_SEC, ENABLE);
}

//----------------------
//中断函数
//----------------------
 T_STRUCT RealTime;
 void RTC_IRQHandler(void)

 u8 tmp;
 if(RTC_GetITStatus(RTC_IT_SEC) != RESET)
 {
  RTC_WaitForLastTask();  
  RTC_ClearITPendingBit(RTC_IT_SEC);
  if((++RealTime.second)>59)  
  {
   RealTime.second=0;
   if((++RealTime.minute)>59)
   {
    RealTime.minute=0;
    if((++RealTime.hour)>23)
    {
     RealTime.hour=0;
     if((++RealTime.day)>=8)
    RealTime.day=1;
   BKP_WriteBackupRegister(BKP_DR5,RealTime.day);
    if(RealTime.month==2)
     {
      if(RealTime.year%4)
       tmp=28;
      else
       tmp=29;
     }
     else
     {
      tmp=Month2Day_Tab[RealTime.month-1];
     }
     if((++RealTime.date)>tmp)
     {
      RealTime.date = 1;
      if((++RealTime.month)>12)
      {
       RealTime.month=1;    

   
       if((++RealTime.year)>99)
       {      

     
        RealTime.year=0;
       }
  BKP_WriteBackupRegister(BKP_DR2,RealTime.year);
      }
  BKP_WriteBackupRegister(BKP_DR3,RealTime.month);
    }

  BKP_WriteBackupRegister(BKP_DR4,RealTime.date);
   }
  }
 }
  
 RTC_WaitForLastTask();
   if(RTC_GetCounter() >= 0x0001517f) 
   RTC_SetCounter(0x0);

  }
}
//-----------
//中断初始化
//-----------
 NVIC_InitTypeDef NVIC_InitStructure;
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
 NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
 NVIC_Init(&NVIC_InitStructure);


工程师
2012-04-18 08:28:59     打赏
24楼

ARM DIY进程6:Usart

    串口通讯的练习,将ARM开发板的COM1与PC机的COM1连接,通讯协议设置为8位数据位,1位停止位,无奇偶校验,9600波特率。开发板上要显示的信息用fprint()发送到PC机。PC机用串口调试软件SSCOM,PC机成为一个显示终端。调试中的变量可以以十进制、十六进制、字符式在PC机上显示。
    记得将options-Target-Use MicroLIB选项打勾。

               图1


工程师
2012-04-18 08:32:31     打赏
25楼

   上图是运行结果。以后就可以用这个调试环境来跟踪变量了。
代码
#include "stm32f10x.h"
int main(void)
{
 u32 a;
 ChipHalInit(); 
 ChipOutHalInit();
 a=0x23;
 printf("变量a用无符号十进制形式显示:%u\r\n",a);
 printf("变量a用十六进制形式显示:%x\r\n",a);
 printf("变量a用字符形式显示:%c\r\n",a);
 while(1);
}

void USART_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    USART_ClockInitTypeDef USART_ClockInitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|
                                                           RCC_APB2Periph_AFIO |
                                                         RCC_APB2Periph_USART1 ,
                                                         ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    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_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    USART_InitStructure.USART_BaudRate = 9600;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
 USART_InitStructure.USART_StopBits = USART_StopBits_1;
 USART_InitStructure.USART_Parity = USART_Parity_No;
 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
 USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
 USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
 USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;
 USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;
 USART_ClockInit(USART1, &USART_ClockInitStructure);
    USART_Init(USART1, &USART_InitStructure);
    USART_Cmd(USART1, ENABLE);
}

int fputc(int ch)
{
    USART_SendData(USART1, (u8) ch); 
    while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
    return ch;
}


工程师
2012-04-19 22:44:32     打赏
26楼

ARM DIY进程7:I2C

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


                                                                                                   图1 I2C读写结果


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

相关代码:

#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     打赏
28楼

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     打赏
29楼

相关代码:

#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     打赏
30楼

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相波形


共75条 3/8 1 2 3 4 5 6 ›| 跳转至

回复

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