普誠創智(成都)科技有限公司-论坛

 找回密码
 立即注册
搜索
热搜: PT32 BLDCM Motor USB
查看: 20239|回复: 1

PT32 IIC 主/从模式源码

[复制链接]

3

主题

3

帖子

57

积分

注册会员

Rank: 2

积分
57
发表于 2021-5-25 18:02:36 | 显示全部楼层 |阅读模式
本帖最后由 Dooo. 于 2021-5-25 18:01 编辑


对于该源码的说明:
1.作为主机和从机的配置主要为主/从机模式设置(I2C_CON)以及地址设置(I2C_TAR、I2C_SAR) 的不同。
2.例程为每500ms写8个字节或读8个字节。
3.在电机驱动中使用时建议将该程序中的延时TICKWaitms()更改为电机驱动中的计时方式。

PT32 IIC 主/从模式,参考源码如下:

#define  IIC_Master_Mode  1  // define Master Mode
#define  IIC_Slave_Mode    0  // define Slave Mode
#define  DATANUM            8
uCHAR   SlaveAddress = 0;
//
#if IIC_Master_Mode
uCHAR        Master_TxRxFlag = 0;                //0 主机写   1 主机读
uCHAR        Master_Rxddata[DATANUM] = {0};
uCHAR        Master_Rxddatacnt = 0;
uCHAR        Master_RxdOKFlag = 0;
uCHAR        Master_Txddata[DATANUM] = {0};
uCHAR        Master_Txddatacnt = 0;   
uCHAR        Master_TxdOKFlag = 0;
#elif  IIC_Slave_Mode
uCHAR        Slave_Rxddata[DATANUM] = {0};
uCHAR        Slave_Rxddatacnt = 0;
uCHAR        Slave_RxdOKFlag = 0;
uCHAR        Slave_Txddata[DATANUM] = {0};
uCHAR        Slave_Txddatacnt = 0;   
uCHAR        Slave_TxdOKFlag = 0;
#endif

//-----
void I2CMConfig(uCHAR i2cx,uLONG rate)
{
        uLONG        fosc;
        //
        pI2C0Ctrl->I2C_ENABLE=0;
        #if IIC_Master_Mode
        pI2C0Ctrl->I2C_CON=(I2CCON_SLAVEDEN|I2CCON_RESTARTEN|I2CCON_7BITADDR_MASTER|I2CCON_SS|I2CCON_MASTEREN);//作为主机
        #elif  IIC_Slave_Mode
        pI2C0Ctrl->I2C_CON=(I2CCON_SLAVEEN|I2CCON_RESTARTEN|I2CCON_7BITADDR_SLAVE|I2CCON_SS|I2CCON_MASTERDEN);//作为从机
        #endif
        //
        fosc=SystemFrequency_APBClk/1000000;
        switch (rate)
        {
                case I2CRATE_HS:        //high speed
                        pI2C0Ctrl->I2C_CON&=~(3<<1);
                        pI2C0Ctrl->I2C_CON|=I2CCON_HS;
                        pI2C0Ctrl->I2C_HS_SCL_HCNT=(fosc*I2CHS_SCLH)/1000;
                        pI2C0Ctrl->I2C_HS_SCL_LCNT=(fosc*I2CHS_SCLL)/1000;
                break;
                case I2CRATE_FS:        //fast speed
                        pI2C0Ctrl->I2C_CON&=~(3<<1);
                        pI2C0Ctrl->I2C_CON|=I2CCON_FS;
                        pI2C0Ctrl->I2C_FS_SCL_HCNT=(fosc*I2CFS_SCLH)/1000;
                        pI2C0Ctrl->I2C_FS_SCL_LCNT=(fosc*I2CFS_SCLL)/1000;
                break;
                case I2CRATE_SS:        //standard speed
                        pI2C0Ctrl->I2C_CON&=~(3<<1);
                        pI2C0Ctrl->I2C_CON|=I2CCON_SS;
                        pI2C0Ctrl->I2C_SS_SCL_HCNT=(fosc*I2CSS_SCLH)/1000;
                        pI2C0Ctrl->I2C_SS_SCL_LCNT=(fosc*I2CSS_SCLL)/1000;
                break;
                default:                        //default
                break;
        }
}   
//-----
void I2CMInit(void)
{
        //Configure GPIOB Alternate Function     GPIO 端口 PB02 复用为 SCL,内部上拉,开漏输出
        GPIOAfr(GPIOB,BIT02,AF2);        // Set PB02 as I2C(AF2) SCL  
        GPIOPuPd(GPIOB,BIT02,PUD_PULLUP);
        GPIOOTDR(GPIOB,BIT02,1,0);
        //Configure GPIOA Alternate Function
        GPIOAfr(GPIOA,BIT08,AF2);                   // Set PA08 as I2C(AF2) SDA
        GPIOPuPd(GPIOA,BIT08, PUD_PULLUP);
        GPIOOTDR(GPIOA,BIT08,1,0);
        //
        I2CMConfig(I2C0,I2CRATE_SS);
        #if IIC_Master_Mode
        I2CMIntEn(I2C0,I2CINTR_RXFULL);          
        pI2C0Ctrl->I2C_ISC = pI2C0Ctrl->I2C_RIS;
        #elif  IIC_Slave_Mode
        SlaveAddress = 0x5a;
        pI2C0Ctrl->I2C_ENABLE=0;
        pI2C0Ctrl->I2C_SAR = SlaveAddress;      //作为从机时 从机的地址设置
        I2CMIntEn(I2C0,I2CINTR_TXABRT | I2CINTR_RDREQ | I2CINTR_RXFULL);          
        pI2C0Ctrl->I2C_ISC = pI2C0Ctrl->I2C_RIS;
        I2CMDevEn(I2C0,1);
        #endif
}
//-----
int main(void)
{
        uCHAR cnt = 0;
        #if IIC_Master_Mode
        uLONG tabort = 0;
        uCHAR Master_Rxdtimecnt = 0;
        uCHAR Master_RxdSum = 0;
        uCHAR Master_TxdSum = 0;
        static uCHAR Master_RxdStatus = 0;
        static uCHAR Master_TxdStatus = 0;
        #elif  IIC_Slave_Mode
        uCHAR Slave_RxdSum = 0;
        uCHAR Slave_TxdSum = 0;
        #endif
        //
        Sys_Clk_Init();
        CoreInit();
        UartInit();
        TICKConfig();
        GPIOInit();
        I2CMInit();
        //
        printf("Version ID=0x%lx\r\n",pSYSCtrl->SC_PID0);
        printf("I2C Sample Example\r\n");
        printf("SysFosc=%ldHz\r\n",SystemFrequency);
        printf("SysFosc Sys=%ldHz\r\n",SystemFrequency_SysClk);
        printf("SysFosc AHB=%ldHz\r\n",SystemFrequency_AHBClk);
        printf("SysFosc APB=%ldHz\r\n",SystemFrequency_APBClk);   
        //
        while(1)
        {   
                #if IIC_Master_Mode
                if(Master_TxRxFlag == 0)        //Write
                {
                        if(Master_TxdStatus == 0)
                        {
                                SlaveAddress = 0x5a;
                                I2CMDevAddr(I2C0,SlaveAddress); //作为主机时 从机的地址设置
                                I2CMDevEn(I2C0,1);
                                //
                                tabort = pI2C0Ctrl->I2C_TABORT;
                                Master_Txddatacnt = 0;               
                                Master_TxdStatus = 1;
                                //
                                for(cnt= 0;cnt < DATANUM - 1; cnt++)
                                {
                                        Master_Txddata[cnt] = (0xa0 + cnt);   
                                        //
                                        Master_TxdSum += Master_Txddata[cnt];
                                        if(cnt == DATANUM - 2)
                                        {
                                                Master_Txddata[DATANUM - 1] = Master_TxdSum;
                                                Master_TxdSum = 0;
                                        }
                                }
                        }
                        else if(Master_TxdStatus == 1)
                        {
                                if(Master_Txddatacnt < DATANUM)
                                {
                                        if((pI2C0Ctrl->I2C_STATUS&I2CSTS_TFE) && (!(pI2C0Ctrl->I2C_STATUS&I2CSTS_ACTIVITY)))
                                        {
                                                I2CMByteWr(I2C0,Master_Txddata[Master_Txddatacnt]);
                                                tabort = pI2C0Ctrl->I2C_TABORT;
                                                if(tabort & I2CTXABRT_7BADDRNOACK)
                                                {
                                                        printf("Write False \r\n");
                                                        TICKWaitms(500);
                                                        Master_TxdStatus = 0;
                                                }
                                                else
                                                {
                                                        Master_Txddatacnt++;
                                                        if(Master_Txddatacnt == DATANUM)
                                                        {
                                                                Master_TxdOKFlag = 1;
                                                        }
                                                }
                                        }
                                }
                                if(Master_TxdOKFlag == 1)
                                {   
                                        printf("Write OK \r\n");
                                        TICKWaitms(500);  
                                        Master_RxdStatus = 0;
                                        Master_TxdOKFlag = 0;
                                        Master_Txddatacnt = 0;
                                        //
                                        Master_TxRxFlag = 1;
                                        Master_RxdStatus = 0;
                                }
                        }
                }
                else if(Master_TxRxFlag == 1)        //Read
                {
                        if(Master_RxdStatus == 0)
                        {
                                for(cnt= 0;cnt < DATANUM; cnt++)
                                {
                                        Master_Rxddata[cnt] = 0;
                                }
                                //
                                Master_Rxddatacnt = 0;
                                //               
                                SlaveAddress = 0x5a;
                                I2CMDevAddr(I2C0,SlaveAddress);
                                I2CMDevEn(I2C0,1);
                                pI2C0Ctrl->I2C_DATA_CMD = I2CRD;
                                //            
                                Master_RxdStatus = 1;
                        }
                        else if(Master_RxdStatus == 1)
                        {
                                if(Master_RxdOKFlag == 1)
                                {
                                        Master_Rxdtimecnt = 0;
                                        for(cnt= 0;cnt < DATANUM - 1; cnt++)
                                        {
                                                Master_RxdSum += Master_Rxddata[cnt];
                                                if(cnt == DATANUM - 2)
                                                {
                                                        if(Master_RxdSum == Master_Rxddata[DATANUM - 1])
                                                        {
                                                                printf("Read OK \r\n");
                                                        }
                                                        else
                                                        {
                                                                printf("Read False \r\n");
                                                        }
                                                        //
                                                        Master_RxdSum = 0;
                                                }
                                        }
                                        TICKWaitms(500);              
                                        Master_RxdStatus = 0;
                                        Master_RxdOKFlag = 0;
                                        Master_Rxddatacnt = 0;
                                        //
                                        Master_TxRxFlag = 0;
                                        Master_TxdStatus = 0;
                                }
                                else
                                {
                                        TICKWaitms(1);                                //可替换为其他计时方式
                                        Master_Rxdtimecnt++;
                                        if(Master_Rxdtimecnt > 10)        //一段时间内数据没收完直接报错
                                        {
                                                Master_Rxdtimecnt = 0;
                                                printf("Read False \r\n");
                                                TICKWaitms(500);
                                                Master_RxdStatus = 0;
                                        }
                                }
                        }
                }
                #elif  IIC_Slave_Mode
                if(Slave_RxdOKFlag == 1)
                {
                        for(cnt= 0;cnt < DATANUM - 1; cnt++)
                        {      
                                Slave_RxdSum += Slave_Rxddata[cnt];
                                if(cnt == DATANUM - 2)
                                {
                                        if(Slave_RxdSum == Slave_Rxddata[DATANUM - 1])
                                        {
                                                printf("Slave Read OK \r\n");
                                        }
                                        else
                                        {
                                                printf("Slave Read False \r\n");
                                        }
                                        //
                                        Slave_RxdSum = 0;
                                }
                        }
                        for(cnt= 0;cnt < DATANUM - 1; cnt++)
                        {                  
                                Slave_Txddata[cnt] = Slave_Rxddata[cnt] + 0x10;
                                //
                                Slave_TxdSum += Slave_Txddata[cnt];
                                if(cnt == DATANUM - 2)
                                {
                                        Slave_Txddata[DATANUM - 1] = Slave_TxdSum;
                                        Slave_TxdSum = 0;
                                }
                        }
                        //   
                        Slave_RxdOKFlag = 0;
                        Slave_Rxddatacnt = 0;
                        //
                        Slave_Txddatacnt = 0;
                }
                if(Slave_TxdOKFlag == 1)
                {
                        printf("Slave Write OK \r\n");   
                        Slave_TxdOKFlag = 0;   
                        Slave_Txddatacnt = 0;
                        //
                        Slave_Rxddatacnt = 0;
                }
                #endif
        }  
}
//-----   
void I2C_IRQHandler(void)       
{
        uCHAR TempData = 0;
        uLONG ris = pI2C0Ctrl->I2C_RIS;
        //
        #if IIC_Master_Mode
        if(ris & I2CINTR_RXFULL)
        {
                TempData =  pI2C0Ctrl->I2C_DATA_CMD;
                if(Master_Rxddatacnt < DATANUM)
                {
                        Master_Rxddata[Master_Rxddatacnt] = TempData;
                        Master_Rxddatacnt++;      
                        if(Master_Rxddatacnt == DATANUM)               
                        {
                                Master_RxdOKFlag = 1;
                        }
                        else
                        {
                                Master_RxdOKFlag = 0;
                                pI2C0Ctrl->I2C_DATA_CMD = I2CRD;                       
                        }
                }
                else
                {
                        Master_Rxddatacnt = DATANUM;
                }
        }
        #elif  IIC_Slave_Mode
        if(ris & I2CINTR_RDREQ)
        {        
                pI2C0Ctrl->I2C_DATA_CMD = Slave_Txddata[Slave_Txddatacnt];
                Slave_Txddatacnt++;
                if(Slave_Txddatacnt >= DATANUM)
                {
                        Slave_Txddatacnt = 0;
                        Slave_TxdOKFlag = 1;
                }
        }  
        else if(ris & I2CINTR_TXABRT)
        {
                Slave_Txddatacnt = 0;
        }
        //
        if(ris & I2CINTR_RXFULL)
        {
                TempData =  pI2C0Ctrl->I2C_DATA_CMD;
                if(Slave_Rxddatacnt < DATANUM)
                {
                        Slave_Rxddata[Slave_Rxddatacnt] = TempData;
                        Slave_Rxddatacnt++;        
                        if(Slave_Rxddatacnt == DATANUM)               
                        {
                                Slave_RxdOKFlag = 1;
                        }
                        else
                        {
                                Slave_RxdOKFlag = 0;               
                        }
                }
                else
                {
                        Slave_Rxddatacnt = DATANUM;
                }
        }
        #endif
        //
        pI2C0Ctrl->I2C_ISC = ris;
}


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

蜀ICP备16008743号-1|普诚科技公司|小黑屋|普誠創智(成都)科技有限公司-论坛  

GMT+8, 2024-3-29 13:14 , Processed in 0.154511 second(s), 22 queries .

快速回复 返回顶部 返回列表