打印

学习STM32F217快1个月了,有点迷茫!

[复制链接]
楼主: yujie870705
手机看帖
扫描二维码
随时随地手机跟帖
61
无冕之王| | 2011-9-13 16:21 | 只看该作者 回帖奖励 |倒序浏览
刚开始学的人,都有一种比较急躁的心态,相信楼主已经过了这个阶段了

使用特权

评论回复
62
hsbjb| | 2011-9-14 10:03 | 只看该作者
芯片资料得先仔细看看

使用特权

评论回复
63
楚地潮人| | 2011-9-28 14:07 | 只看该作者
封他为先驱,就是因为他买了你的芯片!

使用特权

评论回复
64
angryBird| | 2011-9-28 16:55 | 只看该作者
我同样经历了一个月的入门经历,抓住你做的项目,做好了,就逐渐深入了

使用特权

评论回复
65
lord_fan| | 2011-9-28 17:10 | 只看该作者
感觉看手册。看源码。看help文档 很重要。

使用特权

评论回复
66
woyaochenggong| | 2011-9-29 08:31 | 只看该作者
时间太短了,你要有耐心的

使用特权

评论回复
67
woyaochenggong| | 2011-9-29 08:31 | 只看该作者
是这样,学习任何东西,至少要3个月

使用特权

评论回复
68
woyaochenggong| | 2011-9-29 08:31 | 只看该作者
就是从刚接触到有感情,至少三个月

使用特权

评论回复
69
shuaijing| | 2011-9-29 09:03 | 只看该作者
学习本来就很枯燥,尤其是技术

使用特权

评论回复
70
shuaijing| | 2011-9-29 09:04 | 只看该作者
我学dsp不也一样,适应了就好了

使用特权

评论回复
71
yujie870705|  楼主 | 2011-10-11 10:26 | 只看该作者
这几个月的一些成果:
//------------------------------------------------------------------------------
//  Purpose: J1850PWM 链路层函数
//  Funtion: 提供基本 J1850PWM 协议操作接口
//  Dependent: CMPHY_VPW CAN CMP_J2178
//  Designer:
//  Date.Ver:
//  Protocol:
//  Info: 本模块的实现细节,使用一个定时器资源用作
//------------------------------------------------------------------------------
#include "CML_J1850PWM.h"

// defined of m_chState
#define CMLJ1850PWM_WAITING  0          //等待状态
#define CMLJ1850PWM_SENDING  1          //发送状态
#define CMLJ1850PWM_READING  2          //接收状态
#define CMLJ1850PWM_SENDFLA  3          //发送完毕

static struct CML_J1850PWM              //模块数据结构
{
    volatile unsigned char m_chState;   //通讯状态
    unsigned int  m_chECUID;            //数据包过滤ID
    unsigned int  m_DevAddr;            //当前设备地址
    unsigned char m_PakType;            //暂时被定义为包的第一个字节
    int           m_Maxwaittime;        //最大等待时间
    int           m_VehFrametime;       //多包超时时间
    CMP_J2178     m_chTemp;             //临时数据包
    int           m_chCount;            //当前字节计数
    unsigned char m_Lenth;              //长度标识
    unsigned char m_PakMode;            //回复格式
}   TagJ1850PWM;

//------------------------------------------------------------------------------
// Funtion: J1850PWM 开启通讯线路 初始化协议通讯模块
// Input  : para - 链路特性参数
//          time - 链路时间参数
// Output : none
// Return : 开启通讯线路成功时返回 true 开启通讯线路失败返回 false
// Info   : 当通讯线路开启后,K L 通讯线将处于繁忙状态,即不能再有另一个协议对
//          象使用或开启 K L 通讯线
//          本函数之外所有 J1850PWM 协议函数都必须在本函数调用后才有效
//------------------------------------------------------------------------------
char CML_J1850PWM_Open( CMLJ1850PWMpara para, CMLJ1850PWMtime time )
{
    // 初始化数据结构
    TagJ1850PWM.m_chState = CMLJ1850PWM_WAITING;
    TagJ1850PWM.m_Maxwaittime = time.Maxwaittime;
    TagJ1850PWM.m_DevAddr = para.Address;
    TagJ1850PWM.m_chECUID = para.ECUID;
    TagJ1850PWM.m_VehFrametime = time.VehFrametime;
    TagJ1850PWM.m_chCount = 0;
    TagJ1850PWM.m_Lenth = 0;
    TagJ1850PWM.m_PakMode = para.PakMode;
    TagJ1850PWM.m_PakType = para.PakType;
   
    PWM_Init();//PWM初始化
    PWM_Open(PWM_ECUPORT);
    // 连接至串口 1 3
    return true;
}

//------------------------------------------------------------------------------
// Funtion: J1850PWM 关闭通讯线路并释放资源
// Input  : none
// Output : none
// Return : none
// Info   : 关闭之后所有链路层函数将无效
//------------------------------------------------------------------------------
void CML_J1850PWM_Close( )
{

}
//------------------------------------------------------------------------------
// Funtion: J1850PWM 设置当前数据包格式
// Input  : nPakType - 数据包格式(请参看CMP部分)
// Output : none
// Return : none
// Info   : none
//------------------------------------------------------------------------------
void CML_J1850PWM_ConfPak( CMLJ1850PWMpara nPakType )
{
    TagJ1850PWM.m_DevAddr = nPakType.Address;
    TagJ1850PWM.m_chECUID = nPakType.ECUID;
    TagJ1850PWM.m_PakMode = nPakType.PakMode;
    TagJ1850PWM.m_PakType = nPakType.PakType;
}

//------------------------------------------------------------------------------
// Funtion: J1850PWM 读取当前数据包格式设定
// Input  : nPakType - 数据包格式(请参看CMP部分)
// Output : none
// Return : none
// Info   : none
//------------------------------------------------------------------------------
void CML_J1850PWM_ReadPakConf( CMLJ1850PWMpara *nPakType )
{
    nPakType->Address = TagJ1850PWM.m_DevAddr;
    nPakType->ECUID = TagJ1850PWM.m_chECUID;
    nPakType->PakMode = TagJ1850PWM.m_PakMode;
    nPakType->PakType = TagJ1850PWM.m_PakType;
}

//------------------------------------------------------------------------------
// Funtion: J1850PWM 设置字节间隔时间
// Input  : Time - 时间参数
// Output : none
// Return : 时间超出范围时返回 false
// Info   : none
//------------------------------------------------------------------------------
char CML_J1850PWM_ConfTime( CMLJ1850PWMtime Time )
{
    if( Time.Maxwaittime < 10000 )//最大等待时间不能超过10S
    {
        TagJ1850PWM.m_Maxwaittime = Time.Maxwaittime;
    }
    else
    {
        return false;
    }
    TagJ1850PWM.m_VehFrametime = Time.VehFrametime;//?
    return true;
}

//------------------------------------------------------------------------------
// Funtion: J1850PWM 读取当前通讯时间参数
// Input  : Time - 时间参数
// Output : none
// Return : none
// Info   : none
//------------------------------------------------------------------------------
void CML_J1850PWM_ReadTimeConf( CMLJ1850PWMtime *Time )
{
    Time->Maxwaittime = TagJ1850PWM.m_Maxwaittime;
    Time->VehFrametime = TagJ1850PWM.m_VehFrametime;
}

//------------------------------------------------------------------------------
// Funtion: J1850PWM 发送一个数据包
// Input  : PakSend - 待发送数据
// Output : none
// Return : 发送总线仲裁失败时返回 false
// Info   : 查询方式发送,发送时需要停止当前所有中断
//          注意发送前的仲裁避免等待时间
//------------------------------------------------------------------------------
char CML_J1850PWM_Send( PAKSEND *PakSend )
{
   unsigned char i;
   TagJ1850PWM.m_chState = CMLJ1850PWM_SENDING;//通讯状态为正在发送
   //构造待发送数据包
    //if( PakSend != NULL)
    if( CMLJ1850PWM_USERDATA == TagJ1850PWM.m_PakMode )//发送模式为用户区数据格式
    {
        TagJ1850PWM.m_chTemp.m_HeadType = 0;
        TagJ1850PWM.m_chTemp.m_Address =(unsigned char) TagJ1850PWM.m_DevAddr&0xff;
        TagJ1850PWM.m_chTemp.m_FrameID = (unsigned char)(TagJ1850PWM.m_DevAddr>>8);//当前设备地址
        TagJ1850PWM.m_chTemp.m_Priority = ( TagJ1850PWM.m_PakType & 0xE0 ) >> 5;
        //数据包优先级为第一个字节前3位
        TagJ1850PWM.m_chTemp.m_FrameType = TagJ1850PWM.m_PakType & 0x03;
        //帧格式为第一个字节后4位
        TagJ1850PWM.m_chTemp.m_IFR = TagJ1850PWM.m_PakType & 0x08;
        TagJ1850PWM.m_chTemp.m_AddrMode = TagJ1850PWM.m_PakType & 0x04;
        TagJ1850PWM.m_chTemp.m_DataLenth = PakSend->PakLenth;//用户数据区长度
        //TagJ1850PWM.m_chTemp.m_PackLenth =
        for( i=0; i<PakSend->PakLenth; i++ )//用户区数据赋值
        {
            TagJ1850PWM.m_chTemp.m_Data[ i ] = PakSend->Pakdata[ i ];
        }
        TagJ1850PWM.m_chTemp.m_PackLenth = PakSend->PakLenth + 4;//数据包长度
        CMP_J2178_CreatePackage( &TagJ1850PWM.m_chTemp );//构造发送原始数据包
    }
    else//整包传输格式
    {
        for( i=0; i<PakSend->PakLenth; i++ )
        {
            TagJ1850PWM.m_chTemp.m_PackData[ i ] = PakSend->Pakdata[ i ];
        }
        TagJ1850PWM.m_chTemp.m_PackLenth = PakSend->PakLenth;
    }
    PWM_Send( TagJ1850PWM.m_chTemp.m_PackData, TagJ1850PWM.m_chTemp.m_PackLenth);//发送数据包
    TagJ1850PWM.m_chState = CMLJ1850PWM_SENDFLA;//通讯状态为发送完毕
    return true;
}

//------------------------------------------------------------------------------
// Funtion: J1850PWM 接收一个数据包
// Input  : none
// Output : PakRecv - 接收到的数据包
// Return : true or false
// Info   : 接收时将默认过滤三种帧 广播帧 功能查询帧 功能读取帧
//          当过滤地址不为0时将仅接收与过滤地址吻合的包
//          请注意和 VehFrametime 的时间配合,VehFrametime指的是在多包指定时间
//          内收到有效数据包,不包含已接收的  广播帧 功能查询帧 功能读取帧
//------------------------------------------------------------------------------
unsigned char CML_J1850PWM_Recv( PAKRECV *PakRecv )
{
    unsigned char i;
    unsigned char PakType;
    int time;
    PakType = 0xff;
   
    if( NULL == PakRecv )//判断指针非空
    {
        return PakType;//返回0xff
    }
    if( TagJ1850PWM.m_chState == CMLJ1850PWM_SENDFLA)//根据通讯状态设置等待接收时间
    {
        time = TagJ1850PWM.m_Maxwaittime;
        
    }
    else
    {
        time = TagJ1850PWM.m_VehFrametime;
    }
    TagJ1850PWM.m_chState = CMLJ1850PWM_READING;//设置通讯状态
    TagJ1850PWM.m_chTemp.m_PackLenth = PWM_Receive( TagJ1850PWM.m_chTemp.m_PackData, 30, &time,1000);
    //接收数据包原始长度
    if( TagJ1850PWM.m_chTemp.m_PackLenth <= 4 )//判断接收长度,小于4则过滤掉
    {
        return false;
    }
    if( (TagJ1850PWM.m_chTemp.m_PackData[ 0 ] & 0x10)>0 )//判断第一个字节的第4为和第0位
    {
        return false;
    }
    PakRecv->PakID = ( TagJ1850PWM.m_chTemp.m_PackData[ 1 ]<<8 )|( TagJ1850PWM.m_chTemp.m_PackData[ 2 ] );
    //接收数据ID
    if( ( TagJ1850PWM.m_chECUID != 0)&&( TagJ1850PWM.m_chECUID != PakRecv->PakID))//判断接收ID和过滤ID对比
    {
        return false;
    }
    PakType = TagJ1850PWM.m_chTemp.m_PackData[ 0 ];//返回第一个字节
    CMP_J2178_SolvePackage( &TagJ1850PWM.m_chTemp );//解包
    PakRecv->PakLenth = TagJ1850PWM.m_chTemp.m_DataLenth;//重新构造数据包
//    PakRecv->Pakdata = (unsigned char *)calloc( 10, sizeof( char ) );
//    for( i=0; i<PakRecv->PakLenth; i++)
//    {
//        PakRecv->Pakdata[ i ] = TagJ1850PWM.m_chTemp.m_Data[ i ];
      PakRecv->Pakdata = TagJ1850PWM.m_chTemp.m_Data;
         //PakRecv->Pakdata[ i ] = 0x01;
//    }
//    free( (void *)PakRecv->Pakdata );
    return true;//返回第一个字节
}

//------------------------------------------------------ End Of File -----------

使用特权

评论回复
72
yujie870705|  楼主 | 2011-10-11 10:27 | 只看该作者
#include "CMPHY_CAN.h"
#include "CMPHY_Relay.h"
#include "CMPHY_Com.h"

void CAN_Test ( void )
{
    CMPHY_Relay Relaybuf;
    COM_PORTMODE Com1;
    //00 02 00 11 00
    Relaybuf.InputChannel = 9;
    Relaybuf.OutputChannel = 10;
    Relaybuf.CommType = COMM_DOUBLE_CAN_TYPE; //通讯类型串行口
   
    CMPHY_Relay_Init(&Relaybuf);
    CMPHY_Relay_Reset();
    CMPHY_Relay_Set(&Relaybuf );
   
////check line   
//    GPIO_InitTypeDef  GPIO_InitStructure;
//    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
//    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13;
//    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
//    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
//    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
//    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
//    GPIO_Init(GPIOB, &GPIO_InitStructure);
//    unsigned char i;
//    while(1){
//       GPIO_WriteBit(GPIOB,GPIO_Pin_12,(i++)%2);
//       delay(1);
//    }
  
    CAN_CONFIGPARA can1;
    CAN_TXMessage msg1;
    CAN_RXMessage msg2;
    // init database
    CANInit();
    // Open a port with 500kbps normal frame no filter
    can1.Baudrate = CAN_500KBPS;
    can1.Mode = CAN_NORMALFRAME;//*/CAN_EXTERNFRAME;
    unsigned int filterID[]={0x07d0,0x07d1} ;
//                            {0x06D7D000,0x06D7D002};// 0x0;
    can1.FilterID =  filterID;
    can1.FilterNum = 0;// sizeof(filterID)/sizeof(unsigned int);
    while(!CANOpen( CAN_PORTDOUBLE, &can1 ));
    // send pakage
    msg1.StdId = 0x07d0;    // 11bit addr
    msg1.IDE = CAN_ID_STD;//CAN_ID_EXT;  // normal frame
    msg1.RTR = CAN_RTR_DATA;    // data frame
    msg1.DLC = 8;
    msg1.ExtId = 0x06D7D001;
    unsigned char dat[]={0x04,0x18,0x00,0xFF,0x00,0xFF,0xFF,0xFF};
    unsigned char i;
    memcpy(msg1.Data,dat,sizeof(dat));
   
    while(1){
      if(CANSend( &msg1 )){    // send frame
          if(CANRecv(&msg2,1000)){
              delay(1);
          }
      }
    }
}

//--------------------------------------------------------- End Of File --------

使用特权

评论回复
73
yujie870705|  楼主 | 2011-10-11 10:27 | 只看该作者
#include "CMPHY_Com.h"


void  compsendfn()
{
    // Led on
     ComSendByte('S' );
}

void compreadfn()
{
    // Led off
     ComSendByte('R');
}

void Com_Test( void )
{
    COM_PORTMODE Com1;
    unsigned char combyte;
   
    // init database
    ComInit();
    // Open a com port with 10400bps ,8 bit, no Parity,
    Com1.BaudRate = 115200;//*/10400;
    Com1.WordLength = Com_WordLength_8b;
    Com1.StopBits = Com_StopBits_1;
    Com1.Parity = Com_Parity_No;
    ComOpen( COM_PCPORT, &Com1 );
   
//    return;
   
    unsigned int addr=0x64000000;
    ComSendFrame("run from nor flash!\r\n",20);
    ComSendFrame((unsigned char*)addr,100);
    ComSendFrame("read finished!\r\n",16);
    ComSendFrame("Nand init!\r\n",16);      

//   
////    FSMC_NOR_Init();
//    u16 dat[100];
//    u16 i,j;
//    for(i=0;i<100;i++){
//       dat[i]=*((u16*)(addr+(i<<1)));
//       ComSendByte(i);
//    }
//    ComSendFrame((unsigned char*)dat,200);   
//    Printf("test nor finished!\r\n");
//   
//   
//    #define BUFFER_SIZE      1024*8+436
//static uint8_t TxBuffer[BUFFER_SIZE], RxBuffer[BUFFER_SIZE];   
////    NAND_Init();
//    Printf("Nand test!\r\n");  
//    NAND_IDTypeDef NAND_ID;  
//    NAND_ADDRESS WriteReadAddr;   
//    /* NAND memory address to write to */
//    WriteReadAddr.Zone = 0x00;
//    WriteReadAddr.Block = 0x00;
//    WriteReadAddr.Page = 0x00;
//
//    /* Erase the NAND first Block */
//    unsigned char status = NAND_EraseBlock(WriteReadAddr);
//    Printf("Erase Block\r\n");
//        /* Read back the written data */
//    status = NAND_ReadPage (RxBuffer, WriteReadAddr);
//    Printf("Read erase page:\r\n");
//    for(i=0;i<100;i++){
//      Printf("%.2x ",RxBuffer[i]);
//    }
//    Printf("\r\n");
//    /* Write data to FSMC NAND memory */
//    /* Fill the buffer to send */
//    for(j=0;j<BUFFER_SIZE;j++){
//      TxBuffer[j]=j;
//    }
//    status = NAND_WritePage(TxBuffer, WriteReadAddr);
//    Printf("Write page\r\n");
//    for(j=0;j<100;j++){   
//      Printf("%.2x ",TxBuffer[j]);
//    }
//    Printf("\r\n");
//
//    /* Read back the written data */
//    status = NAND_ReadPage (RxBuffer, WriteReadAddr);
//    Printf("Read Page:\r\n");
//    for(j=0;j<100;j++){
//      Printf("%.2x ",RxBuffer[j]);
//    }
//   
//    while(1){
//        NAND_ReadID(&NAND_ID);
//        Printf("%.2x %.2x %.2x %.2x\r\n",NAND_ID.Maker_ID,
//                          NAND_ID.Device_ID,
//                          NAND_ID.Third_ID,
//                          NAND_ID.Fourth_ID);
//       delay(300);
//    }
  
    // load funtion
    //ComInterruptFuntionLoad( compsendfn, COM_INTERSEND );    // send frame
    //ComInterruptFuntionLoad( compreadfn, COM_INTERREAD );    // send frame
   
//    char* str="STM32F2xx run from ext NOR flash";
//    while(str!='\0'){
//      ComSendByte(*str++);
//    }
    // Send one byte
    ComSendByte('1' );
     
    // Read one byte
    combyte = ComReadByte();
   
    // Send one byte
    ComSendByte( combyte );
   
    ComSendByte( '5');
}


//--------------------------------------------------------- End Of File --------

使用特权

评论回复
74
yujie870705|  楼主 | 2011-10-11 10:28 | 只看该作者
//------------------------------------------------------------------------------
//  Purpose: CAN总线控制器控制模块
//  Funtion: 提供基本的CAN总线初始化,接收和发送一个数据包功能
//  Dependent:32F207 LIB
//  Designer:
//  Date.Ver:
//------------------------------------------------------------------------------
#ifndef CMPHY_CAN_C
#define CMPHY_CAN_C

#include "stdbool.h"
#include "CMPHY_CAN.h" // ST 32F207 LIB

__IO static CAN_PORT g_iCAN;

#define CANn          2
CAN_TypeDef*   CAN[CANn] = {CAN1,CAN2};
GPIO_TypeDef*  CAN_RX_PORT[CANn] = {GPIOB,GPIOB};
GPIO_TypeDef*  CAN_TX_PORT[CANn] = {GPIOB,GPIOB};
const uint32_t CAN_CLK[CANn] = {RCC_APB1Periph_CAN1,RCC_APB1Periph_CAN2};
const uint32_t CAN_RX_PORT_CLK[CANn] = {RCC_AHB1Periph_GPIOB,RCC_AHB1Periph_GPIOB};
const uint32_t CAN_TX_PORT_CLK[CANn] = {RCC_AHB1Periph_GPIOB,RCC_AHB1Periph_GPIOB};
const uint16_t CAN_RX_PIN[CANn] = {GPIO_Pin_8,GPIO_Pin_12};
const uint16_t CAN_TX_PIN[CANn] = {GPIO_Pin_9,GPIO_Pin_13};
const uint8_t  CAN_RX_PIN_SOURCE[CANn] = {GPIO_PinSource8,GPIO_PinSource12};
const uint8_t  CAN_TX_PIN_SOURCE[CANn] = {GPIO_PinSource9,GPIO_PinSource13};
const uint8_t  CAN_AF[CANn] = {GPIO_AF_CAN1,GPIO_AF_CAN2};

//------------------------------------------------------------------------------
// Funtion: 初始化CAN模块(进入系统时必须初始化)
// Input  : none
// Output : none
// Return : none
// Info   : none
//-----------------------------------------------------------------------------
void CANInit()
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    uint8_t i = 0;
    for( ; i < CANn; i++ )
    {
        /* Configure CAN1 and CAN2 IOs ****************************************/
        /* GPIO  clocks enable */
        RCC_APB1PeriphClockCmd( CAN_CLK[i], ENABLE);        
        RCC_AHB1PeriphClockCmd( CAN_TX_PORT_CLK[i] | CAN_RX_PORT_CLK[i], ENABLE);
        
        GPIO_PinAFConfig(CAN_TX_PORT[i], CAN_TX_PIN_SOURCE[i], CAN_AF[i]);
        GPIO_PinAFConfig(CAN_RX_PORT[i], CAN_RX_PIN_SOURCE[i], CAN_AF[i]);
        
        GPIO_InitStructure.GPIO_Pin = CAN_TX_PIN[i];
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
        GPIO_Init(CAN_TX_PORT[i], &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = CAN_RX_PIN[i];
        GPIO_Init(CAN_RX_PORT[i], &GPIO_InitStructure);
    }
}


//-----------------------------------------------------------------------------
// Funtion: 初始化 CAN 端口
// Input  : CANport - 待操作 CAN 端口
//                    CAN_PORTDOUBLE CAN_PORTSIGNAL
//          CANmode - CAN 端口初始化参数
// Output : none
// Return : none
// Info   : 硬件可以支持接收掩码功能,但需要在初始化前给出帧格式,帧格式和掩码
//          在通讯过程中不可改变,CAN当前仅使用查询方式
//-----------------------------------------------------------------------------
unsigned char CANOpen( CAN_PORT CANport, CAN_CONFIGPARA *CANmode )
{
    CAN_InitTypeDef        CAN_InitStructure;
    CAN_FilterInitTypeDef  CAN_FilterInitStructure;
      
    g_iCAN =CANport;
   
    /* CAN1 and CAN2 register init */
    CAN_DeInit(CAN[g_iCAN]);
   
    /* Struct init*/
    CAN_StructInit(&CAN_InitStructure);
   
    /* CAN cell init */
    CAN_InitStructure.CAN_TTCM = DISABLE;
    CAN_InitStructure.CAN_ABOM = DISABLE;
    CAN_InitStructure.CAN_AWUM = DISABLE;
    CAN_InitStructure.CAN_NART = DISABLE;
    CAN_InitStructure.CAN_RFLM = DISABLE;
    CAN_InitStructure.CAN_TXFP = DISABLE;
    CAN_InitStructure.CAN_Mode =  CAN_Mode_Normal;
    //CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack;
    //(CAN clocked at 30 MHz)
    const uint16_t CANBAUD[8][4]=
    {
        {CAN_SJW_1tq,CAN_BS1_6tq,CAN_BS2_8tq,60},//33k
        {CAN_SJW_1tq,CAN_BS1_6tq,CAN_BS2_8tq,80},//25k
        {CAN_SJW_1tq,CAN_BS1_6tq,CAN_BS2_8tq,40},//50k
        {CAN_SJW_1tq,CAN_BS1_6tq,CAN_BS2_8tq,32},//62.5k
        {CAN_SJW_1tq,CAN_BS1_6tq,CAN_BS2_8tq,20},//100k
        {CAN_SJW_1tq,CAN_BS1_6tq,CAN_BS2_8tq,16},//125k
        {CAN_SJW_1tq,CAN_BS1_6tq,CAN_BS2_8tq, 8},//250k
        {CAN_SJW_1tq,CAN_BS1_6tq,CAN_BS2_8tq, 4}//500k
    };
    CAN_InitStructure.CAN_SJW = CANBAUD[CANmode->Baudrate][0];//CAN_SJW_1tq;
    CAN_InitStructure.CAN_BS1 = CANBAUD[CANmode->Baudrate][1];//CAN_BS1_6tq;
    CAN_InitStructure.CAN_BS2 = CANBAUD[CANmode->Baudrate][2];//CAN_BS2_8tq;
    CAN_InitStructure.CAN_Prescaler = CANBAUD[CANmode->Baudrate][3];//60;
   
    /*Initializes the CAN*/
    if( CAN_InitStatus_Success != CAN_Init( CAN[g_iCAN], &CAN_InitStructure ) )
    {
        return false;
    }
   
    /* CAN filter init */
    if( CANmode->FilterNum == 0 )
    {
        if( CAN1 == CAN[g_iCAN] )
        {
            CAN_FilterInitStructure.CAN_FilterNumber = 0;
        }
        else
        {
            CAN_FilterInitStructure.CAN_FilterNumber = 14;
        }
        CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
        CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
        CAN_FilterInitStructure.CAN_FilterIdHigh = 0;
        CAN_FilterInitStructure.CAN_FilterIdLow = 0;
        CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0;
        CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0;
        CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
        CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
        CAN_FilterInit( &CAN_FilterInitStructure );
        return true;
    }
    uint8_t i;
    for( i = 0; i < CANmode->FilterNum; i++ )
    {
        //if(CAN1==CAN[g_iCAN]){
        //CAN_FilterInitStructure.CAN_FilterNumber = 0;
        //}
        //else{
        //CAN_FilterInitStructure.CAN_FilterNumber = 14;
        //}
        uint32_t filterID = CANmode->FilterID[i];
        CAN_FilterInitStructure.CAN_FilterNumber = i + 14;
        CAN_FilterInitStructure.CAN_FilterMode =  CAN_FilterMode_IdMask;
        CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
        if( CAN_EXTERNFRAME == CANmode->Mode )
        {      
            CAN_FilterInitStructure.CAN_FilterIdHigh =(filterID>>13);
            CAN_FilterInitStructure.CAN_FilterIdLow =
              (((filterID&0x0000ffff)<<3) | CAN_ID_EXT | CAN_RTR_DATA);
        }
        else
        {
            CAN_FilterInitStructure.CAN_FilterIdHigh =
              (((u32)filterID<<21)&0xFFFF0000)>>16;
            CAN_FilterInitStructure.CAN_FilterIdLow =
              (((u32)filterID<<21)|CAN_ID_STD|CAN_RTR_DATA)&0xFFFF;         
        }
        CAN_FilterInitStructure.CAN_FilterMaskIdHigh =0xFFFF;
        CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFFF;
        CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
        CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
        CAN_FilterInit(&CAN_FilterInitStructure);
    }
    return true;
}

//-----------------------------------------------------------------------------
// Funtion: 发送一个CAN数据包
// Input  : Canmsg - CAN数据包
// Output : none
// Return : false or true 代表发送成功或失败
// Info   : none
//-----------------------------------------------------------------------------
unsigned char CANSend( CAN_TXMessage *Canmsg )
{
    uint8_t TransmitMailbox = CAN_Transmit(CAN[g_iCAN], Canmsg);
    uint32_t i = 0;
    while( (CAN_TransmitStatus(CAN[g_iCAN], TransmitMailbox)  !=  CANTXOK)
         && (i  !=  0x7FFFFF))
    {
        i++;
    }
    return (i!=0x7FFFFF);
}

//-----------------------------------------------------------------------------
// Funtion: 接收一个CAN数据包
// Input  : Canmsg - CAN数据包
//          Waittime - 等待时间(MS)
// Output : none
// Return : false or true 代表接收到有效数据或没有
// Info   : none
//-----------------------------------------------------------------------------
unsigned char CANRecv( CAN_RXMessage *Canmsg, unsigned int Waittime )
{
    uint8_t 标志寄存器 = false;
#ifdef VECT_TAB_SRAM
    __IO uint32_t time = Waittime*2147; //3736;
#else   
    __IO uint32_t time = Waittime*2491; //4285;
#endif   
    //CAN_FIFORelease( CAN[g_iCAN], CAN_FIFO0 );
    do
    {
        if( CAN_MessagePending( CAN[g_iCAN], CAN_FIFO0 ) > 0 )
        {
            标志寄存器 = true;
            break;
        }
    }
    while( time-- );
    if( !标志寄存器 )
    {
        return false;
    }
    CAN_Receive( CAN[g_iCAN], CAN_FIFO0, Canmsg );
    return true;
}

#endif
//--------------------------------------------------------- End Of File --------

使用特权

评论回复
75
yujie870705|  楼主 | 2011-10-11 10:29 | 只看该作者
//------------------------------------------------------------------------------
//  Purpose: 串口资源控制模块
//  Funtion: 提供基本的串口操作接口和一个中断处理机制
//           需要占用处理机 2 个串口中断源,其中一个为保留资源
//  Dependent:32F207 LIB
//  Designer:
//  Date.Ver:
//------------------------------------------------------------------------------
#ifndef CMPHY_Com_C
#define CMPHY_Com_C

#include "stdbool.h"
#include "stm32f2xx_usart.h"
#include "CMPHY_Com.h"

//#define lFosc  //晶振频率
//
//struct CMPHY_Com   //串口中断内部数据结构
//{
//     pFnSCON pfnScom;   //串口中断指针
//}    Scomer;


__IO static COM_PORT g_iCOM;//com;

#define COMn 3
#define COMIntn 3
pFnSCON COM_Int[COMn][COMIntn]={0};
USART_TypeDef* COM_USART[COMn] = {USART2,USART3,USART3};
GPIO_TypeDef* COM_TX_PORT[COMn] = {GPIOA,GPIOB,GPIOC};
GPIO_TypeDef* COM_RX_PORT[COMn] = {GPIOA,GPIOB,GPIOC};
const uint32_t COM_USART_CLK[COMn] = {RCC_APB1Periph_USART2,
                                      RCC_APB1Periph_USART3,
                                      RCC_APB1Periph_USART3};
const uint32_t COM_TX_PORT_CLK[COMn] = {RCC_AHB1Periph_GPIOA,
                                        RCC_AHB1Periph_GPIOB,
                                        RCC_AHB1Periph_GPIOC};
const uint32_t COM_RX_PORT_CLK[COMn] = {RCC_AHB1Periph_GPIOA,
                                        RCC_AHB1Periph_GPIOB,
                                        RCC_AHB1Periph_GPIOC};
const uint16_t COM_TX_PIN[COMn] = {GPIO_Pin_2,GPIO_Pin_10,GPIO_Pin_10};
const uint16_t COM_RX_PIN[COMn] = {GPIO_Pin_3,GPIO_Pin_11,GPIO_Pin_11};
const uint8_t COM_TX_PIN_SOURCE[COMn] = {GPIO_PinSource2,GPIO_PinSource10,GPIO_PinSource10};
const uint8_t COM_RX_PIN_SOURCE[COMn] = {GPIO_PinSource3,GPIO_PinSource11,GPIO_PinSource11};
const uint8_t COM_TX_AF[COMn] = {GPIO_AF_USART2,GPIO_AF_USART3,GPIO_AF_USART3};
const uint8_t COM_RX_AF[COMn] = {GPIO_AF_USART2,GPIO_AF_USART3,GPIO_AF_USART3};
__IO  uint8_t COM_RxFlag[COMn][2] ={0};//串口接收中断标识
__IO  uint8_t COM_TxFlag[COMn]={0};    //串口发送中断标识
//------------------------------------------------------------------------------
// Funtion: 初始化串口处理模块(进入系统时必须初始化)
// Input  : none
// Output : none
// Return : none
// Info   : none
//------------------------------------------------------------------------------
void ComInit()
{
}

static void ComConfig(COM_PORT port)
{
      GPIO_InitTypeDef GPIO_InitStructure;
      uint8_t com=port;
//      for(com=0;com<COMn;com++)
      {
            /* Enable GPIO clock */
            RCC_AHB1PeriphClockCmd(COM_TX_PORT_CLK[com] | COM_RX_PORT_CLK[com], ENABLE);
           
            /* Enable UART clock */
            RCC_APB1PeriphClockCmd(COM_USART_CLK[com], ENABLE);
         
            /* Connect PXx to USARTx_Tx*/
            GPIO_PinAFConfig(COM_TX_PORT[com], COM_TX_PIN_SOURCE[com], COM_TX_AF[com]);
         
            /* Connect PXx to USARTx_Rx*/
            GPIO_PinAFConfig(COM_RX_PORT[com], COM_RX_PIN_SOURCE[com], COM_RX_AF[com]);
         
            /* Configure USART Tx as alternate function  */
            GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
            GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
         
            GPIO_InitStructure.GPIO_Pin = COM_TX_PIN[com];
            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
            GPIO_Init(COM_TX_PORT[com], &GPIO_InitStructure);
         
            /* Configure USART Rx as alternate function  */
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
            GPIO_InitStructure.GPIO_Pin = COM_RX_PIN[com];
            GPIO_Init(COM_RX_PORT[com], &GPIO_InitStructure);
      }
}

//------------------------------------------------------------------------------
// Funtion: 向串口缓冲区写一个字符数据并等待数据从串口发送完毕
// Input  : chbyte - 发送的数据
// Output : none
// Return : none
// Info   : 查询接口,请注意使用在中断中的效果
//------------------------------------------------------------------------------
void ComSendByte(unsigned char chbyte )
{
  COM_TxFlag[g_iCOM]=false;
  /*write a character to the USART */
  USART_SendData(COM_USART[g_iCOM], (uint8_t) chbyte);

  /* Loop until the end of transmission */
  while ( (!COM_TxFlag[g_iCOM]) && (USART_GetFlagStatus(COM_USART[g_iCOM],  USART_FLAG_TC ) == RESET))
  {}
}

//------------------------------------------------------------------------------
// Funtion: 向串口缓冲区写多个字符数据并等待数据从串口发送完毕
// Input  : chframe - 发送的数据 chLenth - 数据长度
// Output : none
// Return : none
// Info   : 查询接口,请注意使用在中断中的效果
//------------------------------------------------------------------------------
void ComSendFrame(unsigned char *chframe, unsigned char chLenth )
{
    unsigned char i;
    for(i=0;i<chLenth;i++){
      ComSendByte(chframe[i]);
    }
}

//------------------------------------------------------------------------------
// Funtion: 一直等待接收一个数据并在接收到时从串口缓冲区读取这个数据并
//          清空缓冲区
// Input  : none
// Output : none
// Return : 接收数据
// Info   : 查询接口,请注意使用在中断中的效果
//------------------------------------------------------------------------------
unsigned char ComReadByte()
{
  COM_RxFlag[g_iCOM][0]=RESET;
  unsigned char dat;
  while(1){
      if(COM_RxFlag[g_iCOM][0]==SET){
         dat=COM_RxFlag[g_iCOM][1];
         break;
      }
      if (USART_GetFlagStatus(COM_USART[g_iCOM], USART_FLAG_RXNE)!=RESET){
         USART_ClearFlag(COM_USART[g_iCOM],USART_FLAG_ORE);
         USART_ReceiveData(COM_USART[g_iCOM]);   
      }
      if(USART_GetFlagStatus(COM_USART[g_iCOM], USART_FLAG_RXNE) == SET){
         dat=USART_ReceiveData(COM_USART[g_iCOM]);
         break;
      }
  }
//  while( USART_GetFlagStatus(COM_USART[com], USART_FLAG_RXNE) != SET);
//  unsigned char dat=USART_ReceiveData(COM_USART[com]);
////  USART_ClearFlag(COM_USART[com],USART_FLAG_RXNE);
  return dat;
}

//------------------------------------------------------------------------------
// Funtion: 一定时间内接收一个数据并在接收到时从串口缓冲区读取这个数据
//          并清空缓冲区
// Input  : nWaitMS - 等待溢出时间记数( 时间单位 MS )
//          chByte - 接收的数据
// Output : none
// Return : false 表示没有接收到数据 true 表示接收到数据
// Info   : 查询接口,请注意使用在中断中的效果
//------------------------------------------------------------------------------
char ComByte( unsigned char *chByte, unsigned int nWaitMS )
{
    uint8_t flag=false;
//#ifdef VECT_TAB_NOR
//    __IO uint32_t time=nWaitMS*130;//3736;   
//#else   
//#ifdef VECT_TAB_SRAM
//    __IO uint32_t time=nWaitMS*2147;//3736;
//#else   
//    __IO uint32_t time=nWaitMS*2491;//4285;
//#endif   
//#endif
   
    SetDelay(nWaitMS*1000);
    do{
       if ((COM_USART[g_iCOM]->SR & USART_FLAG_ORE)!=RESET){
           COM_USART[g_iCOM]->SR = (uint16_t)~USART_FLAG_ORE;
           COM_USART[g_iCOM]->DR;
//           USART_ReceiveData(COM_USART[g_iCOM]);
       }
       if ((COM_USART[g_iCOM]->SR & USART_FLAG_RXNE) ==RESET) continue;
       *chByte=USART_ReceiveData(COM_USART[g_iCOM]);
       flag=true;
       break;
    }
//    while(time--);
    while(DelayState());   
    return flag;
}

//------------------------------------------------------------------------------
// Funtion: 配置并打开串口,所有收发操作前必须打开串口
// Input  : port - 目标串口
//          PortmodePortmode - 串行口参数
// Output : none
// Return : 串口已被打开时返回 false
//          打开串口成功返回 true
// Info   : 请注意给出接收 FIFO 的长度,最好将 FIFO 设置为 1
//------------------------------------------------------------------------------
char ComOpen( COM_PORT port,COM_PORTMODE *Portmode )
{
  USART_InitTypeDef USART_InitStructure;

//  uint8_t i;
//  uint8_t flag=false;
//  for(i=0;i<COMn;i++){
//      if(i!=port){
//          ComClose(i);
//      }
//      else{
//          g_iCOM=port;
////          com=port;
//          flag=true;
//      }
//  }
//  if(!flag) return false;
  g_iCOM=port;  
  //初始化IO配置
  ComConfig(port);
  //参数配置
  USART_InitStructure.USART_BaudRate = Portmode->BaudRate;
  USART_InitStructure.USART_WordLength = Portmode->WordLength;;
  USART_InitStructure.USART_StopBits = Portmode->StopBits;
  USART_InitStructure.USART_Parity = Portmode->Parity;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  /* USART configuration */
  USART_Init(COM_USART[port], &USART_InitStructure);
  /* Enable USART */
  USART_Cmd(COM_USART[port], ENABLE);
  USART_ClearFlag(COM_USART[port],USART_FLAG_TC);
  return true;
}

//------------------------------------------------------------------------------
// Funtion: 装入串口中断
// Input  : pfnc 串口中断
//          Mode - COM_INTERSEND 代表为发送中断
//                 COM_INTERREAD 代表为接收中断
// Output : none
// Return : none
// Info   : pFnSCON 为 系统默认串口中断类型
//------------------------------------------------------------------------------
void ComInterruptFuntionLoad(pFnSCON pfnc, unsigned char Mode )
{
    if(Mode>COMIntn) return;//非存在中断
    COM_Int[g_iCOM][Mode]=pfnc;
    if(Mode==COM_INTERSEND){
      USART_ITConfig(COM_USART[g_iCOM], USART_IT_TC, ENABLE);            
    }
    if(Mode==COM_INTERREAD){
    //Enable Interrupt Rx and Send Complete
      USART_ITConfig(COM_USART[g_iCOM], USART_IT_RXNE, ENABLE);  
    }
}

//------------------------------------------------------------------------------
// Funtion: 销毁串口中断
// Input  : none
// Output : none
// Return : none
// Info   : none
//------------------------------------------------------------------------------
void ComDestroyInterruptFuntion()
{
    unsigned char j;
    for(j=0;j<COMIntn;j++){
        COM_Int[g_iCOM][j]=0;
    }
//USART_ITConfig(COM_USART[port], USART_IT_RXNE, DISABLE);  
}


void InterruptSet(COM_PORT com,unsigned char state)
{
    if(state){
      USART_ClearITPendingBit(COM_USART[com],USART_IT_RXNE);
      USART_ClearFlag(COM_USART[com],USART_FLAG_ORE);
      USART_ITConfig(COM_USART[com], USART_IT_RXNE, ENABLE);
    }
    else{
      USART_ITConfig(COM_USART[com], USART_IT_RXNE, DISABLE);
    }
}

//------------------------------------------------------------------------------
// Funtion: 串口响应函数
// Input  : none
// Output : none
// Return : none
// Info   : none
//------------------------------------------------------------------------------
__INLINE void ComIsr(COM_PORT com)
{
    /* USART in mode Tramitter Complete-------------------------------------------------*/
    if (USART_GetITStatus(COM_USART[com], USART_IT_TC) == SET)
    {
         if(COM_Int[com][COM_INTERSEND]!=0){
          COM_Int[com][COM_INTERSEND]();
         }
         COM_TxFlag[com]=true;
         USART_ClearITPendingBit(COM_USART[com],USART_IT_TC);
    }
   
    /* USART in mode Receiver --------------------------------------------------*/
    if (USART_GetITStatus(COM_USART[com], USART_IT_RXNE) == SET)
    {
           if(COM_Int[com][COM_INTERREAD]!=0){
                COM_Int[com][COM_INTERREAD]();
           }
          COM_RxFlag[com][0]=USART_GetITStatus(COM_USART[com], USART_IT_RXNE);
          if(COM_RxFlag[com][0]==SET){
             COM_RxFlag[com][1]=USART_ReceiveData(COM_USART[com]);
          }
          USART_ClearITPendingBit(COM_USART[com],USART_IT_RXNE);
    }     
   
    if (USART_GetFlagStatus(COM_USART[com], USART_FLAG_ORE) == SET){
         USART_ClearFlag(COM_USART[com],USART_FLAG_ORE); //读SR其实就是清除标志
         USART_ReceiveData(COM_USART[com]);    //读DR
    }
}



//------------------------------------------------------------------------------
// Funtion: 关闭当前串口
// Input  : port - 目标串口
// Output : none
// Return : none
// Info   : none
//------------------------------------------------------------------------------
void ComClose( COM_PORT port )
{
    /* Disable USART */
    USART_Cmd(COM_USART[port], DISABLE);
}

//------------------------------------------------------------------------------
// Funtion: 串口中断映射函数
// Input  : none
// Output : none
// Return : none
// Info   : none
//------------------------------------------------------------------------------
//void USART3_IRQHandler(void)
//{
////    ComIsr(COMPORT3);
//    ComIsr(COM_PCPORT);   
//}

void USART2_IRQHandler(void)
{
    ComIsr(COMPORT2);
}


//------------------------------------------------------------------------------
// Funtion: 串口接收函数
// Input  : port 串口号
// Output : none
// Return : 接收数据
// Info   : none
//------------------------------------------------------------------------------
uint8_t ComRxByte(COM_PORT port)
{
  return USART_ReceiveData(COM_USART[port]);
}
//------------------------------------------------------------------------------
// Funtion: 串口发送函数
// Input  : port 串口号
//          byte 发送字节
// Output : none
// Return : none
// Info   : none
//------------------------------------------------------------------------------
void ComTxByte(COM_PORT port,uint8_t byte)
{
/*write a character to the USART */
  USART_SendData(COM_USART[port], byte);
  /* Loop until the end of transmission */
  while ( (!COM_TxFlag[port]) && (USART_GetFlagStatus(COM_USART[port],USART_FLAG_TC ) == RESET))
  {}
}

#endif
//----------------------------------------------------------------- End Of File --------

使用特权

评论回复
76
yujie870705|  楼主 | 2011-10-11 10:29 | 只看该作者
//includes
#include "misc.h"
#include "CMPHY_System.h"
//------------------------------------------------------------------------------
// Funtion: 初始化硬件设置,中断相关
// Input  : none
// Output : none
// Return : none
// Info   : none
//------------------------------------------------------------------------------
void CMPHY_Init(void)
{
  __set_PRIMASK(1);  
  //中断配置
  NVIC_InitTypeDef  NVIC_InitStructure;
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  
//  NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn;
//  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0;
//  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
//  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//  NVIC_Init(&NVIC_InitStructure);

  NVIC_InitStructure.NVIC_IRQChannel = ETH_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);  
  

  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  
  NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  
  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x2;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  
  NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x3;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  
  NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x4;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  
  NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x5;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  
  NVIC_InitStructure.NVIC_IRQChannel = TIM8_BRK_TIM12_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x5;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);  

  __set_PRIMASK(0);  
}

使用特权

评论回复
77
yujie870705|  楼主 | 2011-10-11 10:29 | 只看该作者
//------------------------------------------------------------------------------
//  Purpose: 定时器资源控制模块
//  Funtion: 提供基本的定时器基本操作接口和一个不要求非常实时的中断处理机制
//           需要占用处理机 3 个定时器中断源,其中一个为保留资源
//           编写时请注意先计算 MCU 软延时的计数时间
//  Dependent:32F207 LIB
//  Designer:
//  Date.Ver:
//------------------------------------------------------------------------------
#ifndef CMPHY_Timer_C
#define CMPHY_Timer_C

#include "stdbool.h"
#include "stm32f2xx_tim.h"
#include "CMPHY_Common.h"
#include "CMPHY_Timer.h"


//struct CMPHY_Timer                       //定时器模块内部数据结构
//{
//     unsigned char chTH0,chTL0;         //TH0 TL0
//     unsigned char chTH1,chTL1;         //TH1 TL1
//     volatile unsigned int nTimeCount0; //计时器0
//     volatile unsigned int nTimeCount1; //计时器1
//     pFnTime pfnTimer0;                 //定时回调函数指针0
//     pFnTime pfnTimer1;                 //定时回调函数指针1
//}    TIMER;
//#define lFosc              //晶振频率

//软件定时/硬件
//#define SOFTDELAY

#define TIMn    3
pFnTime TIM_Int[TIMn]={0};
TIM_TypeDef* TIM[TIMn] = {TIM2,TIM5,TIM4};
uint32_t  TIM_CLK[TIMn] = {RCC_APB1Periph_TIM2,RCC_APB1Periph_TIM5,RCC_APB1Periph_TIM4};
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// Funtion: 初始化定时器中断处理模块(初始化系统时需要做该操作)
// Input  : none
// Output : none
// Return : none
// Info   : 初始化将影响MCU所有定时器状态,所有当前正在工作的定时器将回复到一个
//          内定的不工作状态,相关的内存部分也被清为默认和空
//------------------------------------------------------------------------------
void TimerInit()
{
    uint8_t i;
    uint32_t clk=0;
    for(i=0;i<TIMn;i++){
       clk|=TIM_CLK[i];
    }
    /* TIM clock enable */
    RCC_APB1PeriphClockCmd(clk, ENABLE);
}

//------------------------------------------------------------------------------
// Funtion: 配置定时器(最小可定时1毫秒)
// Input  : chTimerid - 定时器ID ( TIMER0 ~ TIMER1 )
//          chFoutTimeMS- 硬件中断发生时间间隔 ( ms )
// Output : none
// Return : 返回值 true 成功 false 则失败
// Info   : MCU定时器部分使用何种方式工作不需要给出,这个函数主要为产生定是中断做准
//          备,定时中断的时间最小可设定到 1 MS
//------------------------------------------------------------------------------
char TimerConfig( TIMER_ID chTimerid, unsigned char chFoutTimeMS )
{
    if(chFoutTimeMS==0) return false;
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    /* Compute the prescaler value */
    uint16_t PrescalerValue = (uint16_t) ( SystemCoreClock /20000) - 1;
   
    /* Time base configuration */
    TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
    TIM_TimeBaseStructure.TIM_Period = (10*chFoutTimeMS)-1;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM[chTimerid], &TIM_TimeBaseStructure);
   
    return true;
}

//------------------------------------------------------------------------------
// Funtion: 定时器开始工作
// Input  : chTimerid - 定时器ID ( TIMER0 ~ TIMER1 )
// Output : none
// Return : none
// Info   : TimerConfig 完成后需要调用该函数启动定时器工作
//------------------------------------------------------------------------------
void TimerStart( TIMER_ID chTimerid )
{
      TIM_Cmd(TIM[chTimerid], ENABLE);
      /* TIM Interrupts enable */
      TIM_ITConfig(TIM[chTimerid], TIM_IT_Update, ENABLE);      
}

//------------------------------------------------------------------------------
// Funtion: 定时器停止计时
// Input  : chTimerid - 定时器ID ( TIMER0 ~ TIMER1 )
// Output : none
// Return : none
// Info   : 停止定时器工作并不影响在改定时器上所作出配置
//------------------------------------------------------------------------------
void TimerStop( TIMER_ID chTimerid )
{
     TIM_Cmd(TIM[chTimerid], DISABLE);
    /* TIM Interrupts enable */
     TIM_ITConfig(TIM[chTimerid], TIM_IT_Update, DISABLE);           
}



//------------------------------------------------------------------------------
// Funtion: 系统延时( ms )
// Input  : nDelayTimems: 延时时间 (ms)
// Output : none
// Return : none
// Info   : 请使用软件延时完成
//------------------------------------------------------------------------------
void delay( unsigned int nDelayTimems )
{
#ifdef  SOFTDELAY
               uint32_t j;  
          __IO uint32_t i;
          for(j=0;j<nDelayTimems;j++){
      #ifdef VECT_TAB_NOR
              for(i=0;i<620;i++);  
      #else      
      #ifdef VECT_TAB_SRAM
              for(i=0;i<8500;i++);
      #else
              for(i=0;i<12000;i++);
      #endif         
      #endif
          }
#else
      Delay(nDelayTimems*1000);         
#endif           

}


//------------------------------------------------------------------------------
// Funtion: 软件延时
// Input  : ndelayus - 延时微秒数
// Output : none
// Return : none
// Info   : 请使用软件延时完成
//------------------------------------------------------------------------------
void sleepus(unsigned int us)
{
uint32_t j;  
#ifdef VECT_TAB_NOR
         for(j=0;j<ndelayus;j++){
           __ASM("nop");
         }
#else
    __IO uint32_t i;
    for(j=0;j<us;j++){  
#ifdef VECT_TAB_SRAM
       for(i=0;i<8;i++);
#else
       for(i=0;i<11;i++);      
#endif      
    }
#endif   
}

//------------------------------------------------------------------------------
// Funtion: 软件延时
// Input  : ndelayus - 延时微秒数
// Output : none
// Return : none
// Info   : 请使用软件延时完成
//------------------------------------------------------------------------------
void delayus( unsigned int ndelayus )
{
#ifdef SOFTDELAY  
               uint32_t j;  
      #ifdef VECT_TAB_NOR
               for(j=0;j<ndelayus;j++){
                 __ASM("nop");
               }
      #else
          __IO uint32_t i;
          for(j=0;j<ndelayus;j++){  
      #ifdef VECT_TAB_SRAM
             for(i=0;i<8;i++);
      #else
             for(i=0;i<11;i++);      
      #endif      
          }
      #endif   
#else
      Delay(ndelayus);
#endif   
}

//------------------------------------------------------------------------------
// Funtion: 复位定时器初始值
// Input  : chTimerid - 定时器ID ( TIMER0 ~ TIMER1 )
// Output : none
// Return : none
// Info   : 仅仅复位定时的计数状态
//------------------------------------------------------------------------------
void TimerReset( TIMER_ID chTimerid )
{
   TIM_SetCounter(TIM[chTimerid],0);
}

//------------------------------------------------------------------------------
// Funtion: 加载定时中断
// Input  : chTimerid - 定时器ID ( TIMER0 ~ TIMER1 )
//          pFn - 回调时间函数指针pFn ( 中断函数名 )
// Output : none
// Return : none
// Info   : 仅影响一个软件的函数指针,不影响硬件定时器配置
//------------------------------------------------------------------------------
void TimerInterruptFuntionLoad( TIMER_ID chTimerid, pFnTime pFn )
{
    if(chTimerid>=TIMn) return;
    TIM_Int[chTimerid]=pFn;
}

//------------------------------------------------------------------------------
// Funtion: 消毁第uiTimer个定时中断
// Input  : chTimerid - 定时器ID ( TIMER0 ~ TIMER1 )
// Output : none
// Return : none
// Info   : 仅影响一个软件的函数指针,不影响硬件定时器配置
//------------------------------------------------------------------------------
void TimerDestroyInterruptFuntion( TIMER_ID chTimerid )
{
  if(chTimerid>=TIMn) return;
  TIM_Int[chTimerid]=0x0;
}

//------------------------------------------------------------------------------
// Funtion: 释放定时器资源
// Input  : chTimerid - 定时器ID ( TIMER0 ~ TIMER1 )
// Output : none
// Return : none
// Info   : 释放后,某个定时器复位到调用 TimerInit 时的相同状态
//------------------------------------------------------------------------------
void TimerRelease( TIMER_ID chTimerid )
{
   //禁止中断
    TIM_ITConfig(TIM[chTimerid], TIM_IT_Update, DISABLE);
    //停止定时器
    TimerStop(chTimerid);
}


//------------------------------------------------------------------------------
// Funtion: 定时器 中断处理
// Input  : chTimerid - 定时器ID ( TIMER0 ~ TIMER2 )
// Output : none
// Return : none
// Info   : none
__INLINE void TimerIsr(TIMER_ID chTimerid)
{
      if(TIM_GetITStatus(TIM[chTimerid],TIM_IT_Update)!=RESET)
      {
          TIM_ClearITPendingBit(TIM[chTimerid],TIM_IT_Update);         
          if(TIM_Int[chTimerid]!=0){
              TIM_Int[chTimerid]();
          }
      }
}

//------------------------------------------------------------------------------
// Funtion: 定时器 0 中断映射
// Input  : none
// Output : none
// Return : none
// Info   : none
//------------------------------------------------------------------------------
void TIM2_IRQHandler(void)
{
    TimerIsr(TMR0);
}
//------------------------------------------------------------------------------
// Funtion: 定时器1中断映射
// Input  : none
// Output : none
// Return : none
// Info   : none
//------------------------------------------------------------------------------
void TIM5_IRQHandler(void)
{
    TimerIsr(TMR1);
}

//------------------------------------------------------------------------------
// Funtion: 定时器2中断映射
// Input  : none
// Output : none
// Return : none
// Info   : none
//------------------------------------------------------------------------------
void TIM4_IRQHandler(void)
{
    TimerIsr(TMR2);
}


#endif

//--------------------------------------------------------- End Of File --------

使用特权

评论回复
78
yujie870705|  楼主 | 2011-10-11 10:30 | 只看该作者
#include "stdbool.h"
#include "stm32f2xx_tim.h"
#include "CMPHY_Common.h"
#include "CMPHY_VPWM.h"
#include "CMPHY_PWM.h"


#define PWMn 1

const VPWM PWM[PWMn]={
  { { GPIOB,RCC_AHB1Periph_GPIOB,GPIO_Pin_4,GPIO_PinSource4,
        TIM3,RCC_APB1Periph_TIM3,GPIO_AF_TIM3,
        1,TIM_IT_CC1,TIM_FLAG_CC1},
    { GPIOB,RCC_AHB1Periph_GPIOB,GPIO_Pin_0,GPIO_PinSource0,
      TIM3,RCC_APB1Periph_TIM3,GPIO_AF_TIM3,
      3,TIM_IT_CC3,TIM_FLAG_CC3},
    {0}
  }
};

//const VPWM PWM[PWMn]={
//  { { GPIOB,RCC_AHB1Periph_GPIOB,GPIO_Pin_4,GPIO_PinSource4,
//        TIM3,RCC_APB1Periph_TIM3,GPIO_AF_TIM3,
//        1,TIM_IT_CC1,TIM_FLAG_CC1},
//    { GPIOA,RCC_AHB1Periph_GPIOA,GPIO_Pin_9,GPIO_PinSource9,
//      TIM1,RCC_APB2Periph_TIM1,GPIO_AF_TIM1,
//      2,TIM_IT_CC2,TIM_FLAG_CC2},
//    { GPIOB,RCC_AHB1Periph_GPIOB,GPIO_Pin_0,GPIO_PinSource0,
//      TIM1,RCC_APB2Periph_TIM1,GPIO_AF_TIM1,
//      2,TIM_IT_CC2,TIM_FLAG_CC2}
//  }
//};

//const VPWM PWM[PWMn]={ GPIOB,GPIOB,
//        RCC_AHB1Periph_GPIOB,RCC_AHB1Periph_GPIOB,
//                  GPIO_Pin_4,GPIO_Pin_0,
//             GPIO_PinSource4,GPIO_PinSource0,
//                        TIM3,TIM3,
//         RCC_APB1Periph_TIM3,RCC_APB1Periph_TIM3,
//                GPIO_AF_TIM3,GPIO_AF_TIM3,
//                           1,3,
//                  TIM_IT_CC1,TIM_IT_CC3,
//                TIM_FLAG_CC1,TIM_FLAG_CC3
//};
VPWM_DATA   PWM_Data[PWMn]={0};
__IO static PWM_PORT g_iPWM;
//------------------------------------------------------------------------------
// Funtion: 初始化PWM处理模块(进入系统时必须初始化)
// Input  : none
// Output : none
// Return : none
// Info   : none
//------------------------------------------------------------------------------
void PWM_Init()
{
    uint8_t i;
    for(i=0;i<PWMn;i++){
       VPWM_Init((VPWM*)&PWM[i]);
    }
}


void TIM3_IRQHandler(void)
{
    VPWM_TxIsr((VPWM*)&PWM[PWMPORT1],&PWM_Data[PWMPORT1]);
}

//------------------------------------------------------------------------------
// 功能:J1850 - PWM 数据发送函数
// 输入:chbuf - 待发送命令
//       chlen - 发送长度
// 输出:无
// 返回:true 表示发送成功 false 表示发送失败
// 附加:无
//------------------------------------------------------------------------------
char PWM_Send( unsigned char *chbuf, unsigned char chlen )
{
      uint32_t num=(uint32_t)((chlen<<3)+2);  
      //get space
      PWM_Data[g_iPWM].Period=(uint16_t *)malloc(num<<1);
      if(PWM_Data[g_iPWM].Period==0) return false;
      PWM_Data[g_iPWM].Duty  =(uint16_t *)malloc(num<<1);
      if(PWM_Data[g_iPWM].Duty == 0){
        free(PWM_Data[g_iPWM].Period);
        return false;
      }
      //data convert
      if(!DatToPWM(&PWM_Data[g_iPWM],chbuf,chlen)) return false;
      //Check BUS
//      if(!VPWM_CheckBus((VPWM*)&PWM[g_iPWM])) return false;
      
//      SetDelay(16);//SOF
//      WaitDelay();  
      VPWM_Output((VPWM*)&PWM[g_iPWM],&PWM_Data[g_iPWM]);
//      SetDelay(32);//EOF
//      WaitDelay();  
      free(PWM_Data[g_iPWM].Period);
      free(PWM_Data[g_iPWM].Duty);
      return true;
}

//------------------------------------------------------------------------------
// Funtion: 接收PWM数据
// Input  : chlen  接受长度
//          ms  超时时间  
// Output : chbuf  接受缓冲区
// Return : true/false
// Info   : none
//------------------------------------------------------------------------------
uint32_t PWM_Receive( unsigned char *chbuf,unsigned char chlen,unsigned int *firstms,unsigned int ms)
{
      uint32_t num=(uint32_t)((chlen<<3)+2);  
      //get space
      PWM_Data[g_iPWM].HighTime=(uint16_t *)malloc(num<<1);
      if(PWM_Data[g_iPWM].HighTime== 0)
        return 0;
      PWM_Data[g_iPWM].LowTime  =(uint16_t *)malloc(num<<1);
      if(PWM_Data[g_iPWM].LowTime == 0)
      {
        free(PWM_Data[g_iPWM].HighTime);
        return 0;
      }
      PWM_Data[g_iPWM].Index=0;
      PWM_Data[g_iPWM].Num=num;

      *firstms=VPWM_Input((VPWM*)&PWM[g_iPWM],&PWM_Data[g_iPWM],TIM_ICPolarity_Falling/*TIM_ICPolarity_Rising*/,ms*1000)/1000;

     
      num=PWMtoDat(&PWM_Data[g_iPWM],chbuf,chlen);

      free(PWM_Data[g_iPWM].HighTime);
      free(PWM_Data[g_iPWM].LowTime);
      return num;
      
//  return PWM_Input((VPWM*)&PWM[g_iPWM],chbuf,chlen,ms);
}

//------------------------------------------------------------------------------
// Funtion: 配置并打开PWM,所有收发操作前必须打开串口
// Input  : port - 目标串口
//          PortmodePortmode - 串行口参数
// Output : none
// Return : PWM已被打开时返回 false
//          PWM串口成功返回 true
// Info   : 请注意给出接收 FIFO 的长度,最好将 FIFO 设置为 1
//------------------------------------------------------------------------------
char PWM_Open( PWM_PORT port )
{
    g_iPWM = port;
}

//------------------------------------------------------------------------------
// Funtion: 关闭当前PWM
// Input  : port - 目标PWM
// Output : none
// Return : none
// Info   : none
//------------------------------------------------------------------------------
void PWM_Close( PWM_PORT port )
{
}

使用特权

评论回复
79
yujie870705|  楼主 | 2011-10-11 10:31 | 只看该作者
#include "stdbool.h"
#include "stm32f2xx_gpio.h"
#include "stm32f2xx_tim.h"
#include "CMPHY_VPWM.h"


//------------------------------------------------------------------------------
// Funtion: 初始化VPWM处理模块(进入系统时必须初始化)
// Input  : VPWM
// Output : none
// Return : none
// Info   : none
//------------------------------------------------------------------------------
void VPWM_Init(VPWM *vpwm)
{
    static GPIO_InitTypeDef GPIO_InitStructure;
    /* TIM clock enable */
    RCC_APB1PeriphClockCmd(vpwm->TxPPin.TimClk|vpwm->RxPin.TimClk,ENABLE);        
    /* GPIO clock enable */
    RCC_AHB1PeriphClockCmd(vpwm->TxPPin.PortClk|vpwm->RxPin.PortClk, ENABLE);        
    /* GPIO Configuration: TIM CH */
    GPIO_InitStructure.GPIO_Pin = vpwm->TxPPin.Pin;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_Init(vpwm->TxPPin.Port, &GPIO_InitStructure);     
   
    GPIO_SetBits(vpwm->TxPPin.Port,vpwm->TxPPin.Pin);
    GPIO_ResetBits(vpwm->TxPPin.Port,vpwm->TxPPin.Pin);
   
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        
    GPIO_Init(vpwm->TxPPin.Port, &GPIO_InitStructure);     
    GPIO_InitStructure.GPIO_Pin = vpwm->RxPin.Pin;
    GPIO_Init(vpwm->RxPin.Port, &GPIO_InitStructure);         
   
    /* Connect TIM pins to AF */  
    GPIO_PinAFConfig(vpwm->TxPPin.Port, vpwm->TxPPin.PinSource,vpwm->TxPPin.Af);
    GPIO_PinAFConfig(vpwm->RxPin.Port, vpwm->RxPin.PinSource,vpwm->RxPin.Af);

}
//------------------------------------------------------------------------------
// Funtion: 判断总线状态
// Input  : VPWM对象
// Output : none
// Return : none
// Info   : none
//------------------------------------------------------------------------------
uint8_t VPWM_CheckBus(const VPWM *vpwm)
{
      SetDelay(2000000);//2s
      while(DelayState()){
          if(Bit_RESET==GPIO_ReadInputDataBit(vpwm->RxPin.Port,vpwm->RxPin.Pin)){
            return true;
          }
      }
      return false;
}


//------------------------------------------------------------------------------
// Funtion: 更新VPW时间,占空比
// Input  : port VPW号
// Output : none
// Return : none
// Info   : none
//------------------------------------------------------------------------------
uint8_t  VPWM_Update(const VPWM *vpwm,VPWM_DATA *vdat)
{
   if(vdat->Index<vdat->Num){
       switch(vpwm->TxPPin.TimCh){
       case 1:
           vpwm->TxPPin.Tim->CCR1=vdat->Duty[vdat->Index];
           break;
       case 2:
           vpwm->TxPPin.Tim->CCR2=vdat->Duty[vdat->Index];     
           break;
       case 3:
           vpwm->TxPPin.Tim->CCR3=vdat->Duty[vdat->Index];     
           break;
       case 4:
           vpwm->TxPPin.Tim->CCR4=vdat->Duty[vdat->Index];     
           break;
       default:
           return false;
           break;
       }
       vpwm->TxPPin.Tim->ARR=vdat->Period[vdat->Index];
       vdat->Index++;
       return true;
   }
   return false;
}

//------------------------------------------------------------------------------
// Funtion: VPWM接收中断处理
// Input  : port VPW号
// Output : none
// Return : none
// Info   : none
//------------------------------------------------------------------------------
void VPWM_RxIsr(VPWM *vpwm, VPWM_DATA * vdat)
{
    if(TIM_GetITStatus(vpwm->RxPin.Tim,vpwm->RxPin.TimItCc)!=RESET)
    {
         /* Clear TIM Capture compare interrupt pending bit */
          TIM_ClearITPendingBit(vpwm->RxPin.Tim,vpwm->RxPin.TimItCc); //清楚TIM的中断待处理位               
          /* Get the Input Capture value */
         //读取IC2捕获寄存器的值,即为PWM周期的计数值         
          static uint32_t IC2Value;
          static uint32_t IC1Value;         
          IC2Value=vpwm->RxPin.Tim->CCR2;
          IC1Value=vpwm->RxPin.Tim->CCR1;
          if (IC2Value!= 0){
//              if(VPW_Para[port].Index>=VPW_Para[port].Num){
//                  TIM_Cmd(VPW_RX_TIM[g_iVPW], DISABLE);
//                  TIM_ITConfig(VPW_RX_TIM[port], VPW_RX_TIM_CC[port], DISABLE);
//                  VPW_Para[port].State=VPWM_IDLE;  
//              }
//              else{
//    //              RCC_ClocksTypeDef RCC_Clocks;
//    //              RCC_GetClocksFreq(&RCC_Clocks);
//    ////              Frequency = (RCC_Clocks.HCLK_Frequency)/2 / IC2Value;
//    //              /* Duty cycle computation */
//                  VPW_Para[port].Duty[VPW_Para[port].Index]=1+
//                           ((IC2Value) * 100) /(IC1Value);         //读取IC1捕获寄存器的值,并计算占空比
//                  /* Frequency computation */
//                  VPW_Para[port].Period[VPW_Para[port].Index]=1+(IC1Value)/60;//((RCC_Clocks.HCLK_Frequency /2) / 1000000);
//                  VPW_Para[port].Index++;
//              }
          }
//          else
//          {
//            DutyCycle = 0;
//            Frequency = 0;
//          }
    }
}
//------------------------------------------------------------------------------
// Funtion: VPWM发送中断处理
// Input  : port VPW号
// Output : none
// Return : none
// Info   : none
//------------------------------------------------------------------------------
void VPWM_TxIsr(VPWM *vpwm, VPWM_DATA * vdat)
{
      if(TIM_GetITStatus(vpwm->TxPPin.Tim,vpwm->TxPPin.TimItCc)!=RESET)
      {
          TIM_ClearITPendingBit(vpwm->TxPPin.Tim,vpwm->TxPPin.TimItCc);
          if(!VPWM_Update(vpwm,vdat))
          {
              vdat->Index=0;
//              TIM_Cmd(vpwm->TxPPin.Tim, DISABLE);   
//              TIM_ITConfig(vpwm->TxPPin.Tim,vpwm->TxPPin.TimItCc, DISABLE);            
//              vdat->State=VPWM_IDLE;            
          }
      }
}



//------------------------------------------------------------------------------
// Funtion: 产生VPWM波
// Input  : tim    脉冲时间
//          duty   脉冲占空比   
//          num    肪冲数   
// Output : none
// Return : none
// Info   : none
//------------------------------------------------------------------------------
void VPWM_Output(VPWM *vpwm,VPWM_DATA *vdat)
{
      if(vdat->Num==0) return;
      vdat->Index=0;
      vdat->State=VPWM_OUTPUT;
      
      uint16_t Period =vdat->Period[vdat->Index];
      uint16_t CCR_Val=vdat->Duty[vdat->Index];
      vdat->Index++;
   
      TIM_DeInit(vpwm->TxPPin.Tim);
      static TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
      static TIM_OCInitTypeDef  TIM_OCInitStructure;
      /* Compute the prescaler value */
      uint16_t PrescalerValue = (uint16_t) ((SystemCoreClock /2) / 10000000) - 1;
      
      /* PWM1 Mode configuration: Channel1 */
      TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
      TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
      TIM_OCInitStructure.TIM_Pulse = CCR_Val;
      TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
   
      switch(vpwm->TxPPin.TimCh){
      case 1:
          TIM_OC1Init(vpwm->TxPPin.Tim, &TIM_OCInitStructure);
          TIM_OC1PreloadConfig(vpwm->TxPPin.Tim, TIM_OCPreload_Enable);
        break;
      case 2:
          TIM_OC2Init(vpwm->TxPPin.Tim, &TIM_OCInitStructure);
          TIM_OC2PreloadConfig(vpwm->TxPPin.Tim,TIM_OCPreload_Enable);
        break;
      case 3:
          TIM_OC3Init(vpwm->TxPPin.Tim, &TIM_OCInitStructure);
          TIM_OC3PreloadConfig(vpwm->TxPPin.Tim, TIM_OCPreload_Enable);
        break;
      case 4:
          TIM_OC4Init(vpwm->TxPPin.Tim, &TIM_OCInitStructure);
          TIM_OC4PreloadConfig(vpwm->TxPPin.Tim, TIM_OCPreload_Enable);
        break;
      }
      TIM_ARRPreloadConfig(vpwm->TxPPin.Tim, ENABLE);
   
      /* Time base configuration */
      TIM_TimeBaseStructure.TIM_Period = Period;
      TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
      TIM_TimeBaseStructure.TIM_ClockDivision = 0;
      TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
      TIM_TimeBaseInit(vpwm->TxPPin.Tim, &TIM_TimeBaseStructure);
      
//      TIM_ITConfig(vpwm->TxPPin.Tim, vpwm->TxPPin.TimItCc, ENABLE);         
      /* TIM enable counter */
      TIM_Cmd(vpwm->TxPPin.Tim, ENABLE);
//      return;
      
      while(vdat->State!=VPWM_IDLE){
            if(TIM_GetFlagStatus(vpwm->TxPPin.Tim,vpwm->TxPPin.TimFlagCc)==RESET)continue;
            TIM_ClearFlag(vpwm->TxPPin.Tim,vpwm->TxPPin.TimFlagCc);
            if(!VPWM_Update(vpwm,vdat)){
                TIM_Cmd(vpwm->TxPPin.Tim, DISABLE);   
                vdat->State=VPWM_IDLE;            
            }
      }
}



uint8_t VPWtoBit(uint16_t lowleveltime,uint16_t highleveltime)
{
#define SHORT_RX_MIN  34
#define SHORT_RX_MAX  96  
#define LONG_RX_MIN   95
#define LONG_RX_MAX   162  
#define SOF_RX_MIN    164
#define SOF_RX_MAX    237  
//    uint16_t highleveltime = period-lowleveltime;
    if(highleveltime> SHORT_RX_MIN && highleveltime <SHORT_RX_MAX){
        if(lowleveltime<LONG_RX_MAX && lowleveltime> LONG_RX_MIN){
             return VPWM_BIT11;
        }
        else if(lowleveltime >SHORT_RX_MIN && lowleveltime <SHORT_RX_MAX){
             return VPWM_BIT01;
        }
        else{
             return VPWM_ERR;
        }
    }   
    if(highleveltime > LONG_RX_MIN && highleveltime <LONG_RX_MAX){
         if(lowleveltime<LONG_RX_MAX && lowleveltime> LONG_RX_MIN){
             return VPWM_BIT10;
        }
        else if(lowleveltime >SHORT_RX_MIN && lowleveltime <SHORT_RX_MAX){
             return VPWM_BIT00;
        }
        else{
             return VPWM_ERR;
        }
    }
    if(highleveltime<SOF_RX_MAX && highleveltime> SOF_RX_MIN){
        return VPWM_SOF;   
    }
    return VPWM_ERR;
}

uint8_t  VPWtoDat(VPWM_DATA *vpwm,uint8_t *buf,uint8_t len)
{
      uint8_t j=0,k=0;
      uint8_t ch=0;
      uint8_t state;
      uint32_t i;
      for(i=0;i<vpwm->Index;i++){
                state =VPWtoBit(vpwm->HighTime[i],vpwm->LowTime[i]);
                if(state&VPWM_BIT11){
                  ch|=1<<(7-j++);
                  ch|=1<<(7-j++);                  
                }
                else if(state&VPWM_BIT01){
                  j++;
                  ch|=1<<(7-j++);
                }
                else if(state&VPWM_BIT10){
                  ch|=1<<(7-j++);
                  j++;
                }
                else if(state&VPWM_BIT00){
                   j+=2;
                }
                else if( state&VPWM_BIT1){
                   ch|=1<<(7-j++);
                }
                else if(state&VPWM_BIT0){
                   j++;
                }
                else if(state==VPWM_ERR){
                  ch=0;
                  j=0;
                }
                if(j==8){
                      if(k>=len) return k;
                      buf[k++]=ch;
                      j=0;
                      ch=0;
                }
      }
      return k;
}

uint8_t  PWMtoBit(uint16_t lowleveltime,uint16_t highleveltime)
{
//      static uint16_t j=0;
//      static uint16_t ic1[100];
//      static uint16_t ic2[100];
//      ic1[j]=highleveltime;
//      ic2[j]=lowleveltime;
//      if(++j>=100){
//          j=0;
//      }
//      return 0;

//    uint16_t highleveltime = period-lowleveltime;
      if(highleveltime <=35 && highleveltime >=30){
              return VPWM_SOF;
      }
      else if(highleveltime>=6 && highleveltime <=11){
              return VPWM_BIT1;
          }
      else if(highleveltime >=14 && highleveltime <=19){
              return VPWM_BIT0;
          }
      return VPWM_ERR;
  
//      if(lowleveltime<=19 && lowleveltime>=14){
//          if(highleveltime>=6 && highleveltime <=11){
//              return VPWM_BIT1;
//          }
//          else if(highleveltime <=35 && highleveltime >=30){
//              return VPWM_SOF;
//          }
//          else{
//              return VPWM_ERR;
//          }
//      }
//      else if(lowleveltime <= 11 && lowleveltime >=6){
//          if(highleveltime >=14 && highleveltime <=19){
//              return VPWM_BIT0;
//          }
//          else{
//              return VPWM_ERR;
//          }
//      }
//      return VPWM_ERR;
}

uint8_t  PWMtoDat(VPWM_DATA *vpwm,uint8_t *buf,uint8_t len)
{
      uint8_t j=0,k=0;
      uint8_t ch=0;
      uint8_t state;
      uint32_t i;
      for(i=0;i<vpwm->Index;i++){
                state =PWMtoBit(vpwm->HighTime[i],vpwm->LowTime[i]);
                if(state&VPWM_BIT1){
                   ch|=1<<(7-j++);
                }
                else if(state&VPWM_BIT0){
                   j++;
                }
                else if(state==VPWM_ERR){
                  ch=0;
                  j=0;
                }
                if(j==8){
                      if(k>=len) return k;
                      buf[k++]=ch;
                      j=0;
                      ch=0;
                }
      }
      return k;
}



//------------------------------------------------------------------------------
unsigned int VPWM_Input(VPWM *vpwm,VPWM_DATA *vdat,uint16_t polarity,uint32_t us)
{
    TIM_DeInit(vpwm->RxPin.Tim);
    static  TIM_ICInitTypeDef  TIM_ICInitStructure;
    static  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    //1Mhz
    uint16_t PrescalerValue = (uint16_t) ((SystemCoreClock /2) / 1000000) - 1;
        /* Time base configuration */
    TIM_TimeBaseStructure.TIM_Period = 10000-1;
    TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(vpwm->RxPin.Tim, &TIM_TimeBaseStructure);
   
    TIM_ICInitStructure.TIM_Channel =(vpwm->RxPin.TimCh-1)<<2;
    TIM_ICInitStructure.TIM_ICPolarity = polarity;//TIM_ICPolarity_Falling;
    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    TIM_ICInitStructure.TIM_ICFilter = 0x0;
  
    TIM_PWMIConfig(vpwm->RxPin.Tim, &TIM_ICInitStructure);
  
    /* Select the TIM  Input Trigger */
    TIM_SelectInputTrigger(vpwm->RxPin.Tim,0x40|(vpwm->RxPin.TimCh-1)<<4);
   
     /* Select the slave Mode: Reset Mode */
    TIM_SelectSlaveMode(vpwm->RxPin.Tim, TIM_SlaveMode_Reset);//TIM从模式:触发信号的上升沿重新初始化计数器和触发寄存器的更新事件
  
    /* Enable the Master/Slave Mode */
    TIM_SelectMasterSlaveMode(vpwm->RxPin.Tim, TIM_MasterSlaveMode_Enable); //启动定时器的被动触发

    /* TIM enable counter */
    TIM_Cmd(vpwm->RxPin.Tim, ENABLE);
    /* Enable the CC2 Interrupt Request */
  //  TIM_ITConfig(vpwm->RxPin.Tim,vpwm->RxPin.TimItCc, ENABLE);   

    uint16_t i=0;
    SetDelay(us);
    uint32_t ustime=us;
    uint32_t time;
    while(1)
    {
            if(TIM_GetFlagStatus(vpwm->RxPin.Tim,vpwm->RxPin.TimFlagCc)==RESET)
            {
                if(i!=0)
                {
                    if(TIM_GetFlagStatus(vpwm->RxPin.Tim,TIM_FLAG_Update)!=RESET)
                    {//超时
                         TIM_ClearFlag(vpwm->RxPin.Tim,TIM_FLAG_Update);                  
                         time=GetDelay();
                    }
                    else{
                        if(time-GetDelay()>1000){
                           break;
                        }
                    }
                }
                if(!DelayState()) break;
                continue;
            }
        
            TIM_ClearFlag(vpwm->RxPin.Tim,vpwm->RxPin.TimFlagCc);
            if(i++==0)
            {//获取时间
              ustime-=GetDelay();
            }
            /* Get the Input Capture value */
            if(polarity==TIM_ICPolarity_Falling)
            {
              vdat->HighTime[vdat->Index]=vpwm->RxPin.Tim->CCR2;
              vdat->LowTime[vdat->Index]=vpwm->RxPin.Tim->CCR1;
            }
            else
            {
              vdat->HighTime[vdat->Index]=vpwm->RxPin.Tim->CCR1;
              vdat->LowTime[vdat->Index]=vpwm->RxPin.Tim->CCR2;
            }
            if(++vdat->Index>=vdat->Num)
              break;
    }
    return ustime;
   
}




void ToPWM(VPWM_DATA *vdat,uint16_t time0,uint16_t time1)
{
    uint16_t Period=(10*(time0+time1)-1);
    vdat->Period[vdat->Num]=Period;
    vdat->Duty[vdat->Num++]=((uint32_t)(Period*(10*time0+vdat->Offset)))/(10*(time0+time1));            
}


uint8_t DatToPWM(VPWM_DATA *vdat,uint8_t *buf,uint8_t  len)
{
    uint8_t i,j;
    uint16_t time=30;//32;//SOF
    uint16_t time1=16;
    vdat->Num=0;
    ToPWM(vdat,time,time1);
    for(i=0;i<len;i++){
        for(j=0;j<8;j++){
            if( (buf[i]>>(7-j))&0x1){//HIGH
                time=8;
                time1=16;
            }
            else{//LOW
                time=16;
                time1=8;
            }
            ToPWM(vdat,time,time1);   
        }
    }
    //EOF
    time=16;
    time1=32;
    ToPWM(vdat,time,time1);
    return true;
}

使用特权

评论回复
80
yujie870705|  楼主 | 2011-10-11 10:34 | 只看该作者
//------------------------------------------------------------------------------
//  Purpose: GPIO口电平时序控制模块
//  Funtion: 提供基本的GPIO口状态输出和输入操作接口,包括初始化,选定某个IO口
//           设定IO口输出电平状态和输出时间,监控IO口电平状态和电平持续时间
//           必要时需要占用一个MCU定时器资源
//  Dependent:32F207 LIB
//  Designer:
//  Date.Ver:
//------------------------------------------------------------------------------
#ifndef CMPHY_IOCtrl_C
#define CMPHY_IOCtrl_C
//includes
#include "stdbool.h"
#include "stm32f2xx_gpio.h"  
#include "CMPHY_Common.h"
#include "CMPHY_IOCtrl.h"

#define PORT_MODE(mode)   ((mode>>1)&0x1)
#define TIME_MODE(mode)   (mode&0x1)
//typedef enum{KLINE_RX=0,KLINE_TX=1,PWM_RX=2,PWM_TX=3,VPW_RX=4,VPW_TX=5}IO_CTRL_PORT;
#define IOn  6
const uint32_t IO_CLK[IOn] = { RCC_AHB1Periph_GPIOA,RCC_AHB1Periph_GPIOA,
                               RCC_AHB1Periph_GPIOB,RCC_AHB1Periph_GPIOB,
                               RCC_AHB1Periph_GPIOB,RCC_AHB1Periph_GPIOB };
GPIO_TypeDef  *IO_PORT[IOn] = { GPIOA,GPIOA,
                                GPIOB,GPIOB,
                                GPIOB,GPIOB};
const uint16_t IO_PIN[IOn] = { GPIO_Pin_3,GPIO_Pin_2,
                               GPIO_Pin_1,GPIO_Pin_0,
                               GPIO_Pin_14,GPIO_Pin_15};

static __IO uint8_t  g_iIO;
static __IO uint8_t  g_iTimeMode;


static __INLINE void SetOutput()
{
      GPIO_InitTypeDef GPIO_InitStructure;     
      GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
      GPIO_InitStructure.GPIO_Pin = IO_PIN[g_iIO];
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
      GPIO_Init(IO_PORT[g_iIO], &GPIO_InitStructure);
}

static __INLINE void SetInput()
{
      GPIO_InitTypeDef GPIO_InitStructure;
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
      GPIO_InitStructure.GPIO_Pin = IO_PIN[g_iIO];
      GPIO_Init(IO_PORT[g_iIO], &GPIO_InitStructure);
//      uint32_t pinpos=IO_PIN_NO[g_iIO];
//      IO_PORT[g_iIO]->MODER  &= ~(GPIO_MODER_MODER0 << (pinpos * 2));
//      IO_PORT[g_iIO]->MODER |= (((uint32_t)GPIO_Mode_IN) << (pinpos * 2));
//      /* Pull-up Pull down resistor configuration*/
//      IO_PORT[g_iIO]->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)pinpos * 2));
//      IO_PORT[g_iIO]->PUPDR |= (((uint32_t)GPIO_PuPd_UP) << (pinpos * 2));
}

//------------------------------------------------------------------------------
// Funtion: 初始化GPIO口模块(进入系统时必须初始化)
// Input  : none
// Output : none
// Return : none
// Info   : none
//-----------------------------------------------------------------------------
void IOCTRLInit()
{
//     uint8_t i;
//     for(i=0;i<IOn;i++){
//            /* Enable GPIO clock */
//            RCC_AHB1PeriphClockCmd(IO_CLK[i], ENABLE);
//     }
}

//-----------------------------------------------------------------------------
// Funtion: 选择带操作IO口
// Input  : IOport - 待操作IO口
//                   IOCTRL_KLINESEND IOCTRL_KLINEREAD IOCTRL_PWMSEND
//                   IOCTRL_PWMREAD IOCTRL_VPWSEND IOCTRL_VPWREAD
//          Workmode - 工作模式
//                   IOCTRL_INPUT IOCTRL_OUTPUT | IOCTRL_USMODE IOCTRL_MSMODE
// Output : none
// Return : none
// Info   :
//-----------------------------------------------------------------------------
void IOCTRLSelect( IOCTRL_PORT IOport, unsigned char Workmode )
{
    g_iIO=IOport;
    g_iTimeMode = TIME_MODE(Workmode);
    RCC_AHB1PeriphClockCmd(IO_CLK[g_iIO], ENABLE);   
    if(PORT_MODE(Workmode)==IOCTRL_OUTPUT){
        SetOutput();
    }
    else{
        SetInput();
    }
}

//-----------------------------------------------------------------------------
// Funtion: 设置当前 GPIO 口电平状态和电平时间
// Input  : Portstat - GPIO 口电平状态
//                     IOCTRL_HIGH  IOCTRL_LOW
//          Porttime - 电平时间(US or MS)
// Output : none
// Return : none
// Info   : 请注意计时的精准性
//-----------------------------------------------------------------------------
void IOCTRLSet( IOCTRL_STAT Portstat, unsigned int Porttime )
{
    SetDelay( (g_iTimeMode==IOCTRL_USMODE)?Porttime:(Porttime*1000) );  
//    SetOutput();
    GPIO_WriteBit(IO_PORT[g_iIO],IO_PIN[g_iIO],(BitAction)Portstat);
    WaitDelay();
}

//-----------------------------------------------------------------------------
// Funtion: 读取当前 GPIO 口电平状态和电平时间
// Input  : Portstat - 当前 GPIO 口电平状态
//                     IOCTRL_HIGH  IOCTRL_LOW
//          Maxtime - 最大等待时间(US or MS)
// Output : none
// Return : 当前 GPIO 口电平 持续时间
// Info   : 请注意计时的精准性
//-----------------------------------------------------------------------------
unsigned int IOCTRLRead( unsigned int Maxtime )
{
    SetDelay( (g_iTimeMode==IOCTRL_USMODE)?Maxtime:(Maxtime*1000) );   
//    SetDelay(Maxtime);
//    SetInput();   
//    uint8_t state=GPIO_ReadInputDataBit(IO_PORT[g_iIO],IO_PIN[g_iIO]);
    uint8_t state = (IO_PORT[g_iIO]->IDR & IO_PIN[g_iIO]);
//    *Portstat = state;
    while(DelayState()){
        if(state!= (IO_PORT[g_iIO]->IDR & IO_PIN[g_iIO])){
           uint32_t us=GetDelay();
           return (Maxtime-((g_iTimeMode==IOCTRL_USMODE)?us:(us/1000)) );
        }
    }
    return Maxtime;
}



//-----------------------------------------------------------------------------
// Funtion: 读取当前 GPIO 口电平状态
// Input  : Portstat - 监控 GPIO 口电平状态
//                     IOCTRL_HIGH  IOCTRL_LOW
//          Maxtime - 最大等待时间(US or MS)
// Output : none
// Return : 当前 GPIO 口电平 持续时间
// Info   : 请注意计时的精准性
//-----------------------------------------------------------------------------
unsigned char IOCTRLReadState( IOCTRL_STAT Portstat, unsigned int Maxtime )
{
    SetDelay(Maxtime);
//    SetInput();   
//    uint32_t time=Maxtime;      
    uint8_t state;
    if(Portstat ==IOCTRL_HIGH ){
      state =IO_PIN[g_iIO];
    }
    else{
      state = 0;
    }
//    *Portstat = state;
    while(DelayState()){
        if(state== (IO_PORT[g_iIO]->IDR & IO_PIN[g_iIO])){
           ClearDelay();
           return true;
        }
    }
    return false;
}

#endif
//--------------------------------------------------------- End Of File --------

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则