久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2240|回復: 5
打印 上一主題 下一主題
收起左側

一個實現硬件I2C從機收發的單片機程序,有幾個地方不懂,希望大佬們分析一下

[復制鏈接]
跳轉到指定樓層
樓主
ID:1043477 發表于 2022-9-21 17:28 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
#include "RX8F103.h"

#define        STCON         MSCON
#define        SRXBUF        MSRXBUF
#define        STXBUF        MSTXBUF
#define        SSTAT0        MSSTAT0
#define        SSTAT1        MSSTAT1
#define        SIEN0                MSIEN0
#define        SIEN1                MSIEN1
#define        SSADDR        MSADDR

//I2C主機多字節,單字節讀寫
//I2C Master 和 I2C Slave通信協議
/*
S + DevAdd(Read)  + BayteN + Stop
S + DevAdd(Write) + BayteN + Stop
*/

//I2C從機地址  7位地址
#define I2C_SLAVE_ADD   0x50

#define BUFF_MAX 128
unsigned char xdata DataBuf[BUFF_MAX];

unsigned char DataTxIndex = 0;
unsigned char DataRxIndex = 0;
unsigned char InterruptIndex = 0;
unsigned char WrtieTxBufFlag = 0;

void EUart0_SendOneChar(char c)
{
        ES0=0;                                //發送數據時關串口中斷
        TI0=0;                                //清TI位
        S0BUF = c;                //將待發送字符放入串口數據緩沖寄存器,并開始傳輸。
        while(!TI0);        //等待傳送結束。當字符發送結束后由硬件置位請求中斷,
                                                                //此時while循環結束,而串口中斷處理函數需等到ES重新置1后才可能響應。
        TI0=0;                                //軟件清TI位,亦可在中斷處理函數中清0
        ES0 = 1;                        //開串口中斷
}

void EUart0_SendString(char *st)
{
        while(*st)
        {
                EUart0_SendOneChar(*st++);
        }
}

void Uart0_init(void)
{        
        UART0PORTEN = 1;        //串口端口使能
        S0CON = 0x50;                        //SCON: Mode 1, 8-bit UART, Enable Rcvr
        S0RELH = 0x03;                //S0RELH + S0RELL  構成波特率設置S0REL[9:0]
        S0RELL = 0xF7;                //Baud rate  = SYSCK/(16×(1024-S0REL))  SYSCK跟CLKDIV寄存器有關  波特率為115200
        ES0 = 1;                                        //允許串口中斷位
        EUart0_SendString("RX8F103 UART0 Init OK!\r\n");
}

void I2c_Init(void)
{
        I2CPORTEN = 1;                                //IIC PORT口使能

        TOPCON = 0x00;                                //IIC Slave        

        SSADDR = I2C_SLAVE_ADD;//IIC 從機地址寄存器

        SIEN0 = 0x01;                                        //正常結束中斷

        SIEN1 = 0x21;                                        //使能接收區滿中斷

        STCON = 0x40;                                        //使能I2C                                
}

void I2c_TxBuf_Reset(void)
{
        TOPCON |= 0x02;
        TOPCON &= 0xFD;        

        I2c_Init();
}

void main(void)
{
        unsigned char i;

        CLKCON |= 0x1F;                                //默認所有時鐘打開
        RSTPORTEN = 1;                                //使能復位功能

        Uart0_init();

        //初始化數組
        for (i=0; i<BUFF_MAX; i++)
        {
                DataBuf[ i] = 0x10+i;
        }

        I2c_Init();

        EI2CFIFO = 1;                                        //開IIC FIFO 中斷
        EI2CRXTX = 1;                                        //開IIC TXRX 中斷
        EA = 1;                                                                //使能總中斷

        while(1);
}

/*
GC
SUNF
SOVF
SNE
以上任意一個或多個事件發送,均為產生EI2CRXTX中斷
*/
void I2C_Slave_TRX_ISR(void) interrupt EI2CRXTX_VECTOR                //TRX中斷
{
        unsigned char ReadData;

        //Transmitted Data Byte not ready
        if (0x04 == (SSTAT0 & 0x04))        
        {        
                //清中斷標志位
                SSTAT0 &= 0xFB;                                                               
        }               

        //Receive Overflow
        if (0x02 == (SSTAT0 & 0x02))        
        {
                ReadData = SRXBUF;

                //清中斷標志位
                SSTAT0 &= 0xFD;                                                                        
        }

        //Normal End
        if (0x01 == (SSTAT0 & 0x01))        
        {                                
                InterruptIndex = 0;
                WrtieTxBufFlag = 0;

                I2c_TxBuf_Reset();

                //清中斷標志位
                SSTAT0 &= 0xFE;                                                                                
        }               
}

/*
STBE
STBF
SRBE
SRBF
以上任意一個或多個事件發送,均為產生EI2CFIFO中斷
*/
void I2C_Slave_FIFO_ISR(void) interrupt EI2CFIFO_VECTOR                //FIFO中斷
{
        unsigned char ReadData;

        //Transmission buffer is empty
        if (0x20 == (SSTAT1 & 0x20))                                                                        
        {
                if ((DataTxIndex < BUFF_MAX) && (1 == WrtieTxBufFlag))
                {
                        STXBUF = DataBuf[DataTxIndex];
                        DataTxIndex++;        
                }

                SSTAT1 &= 0xDF;
        }

        // Reception buffer is full
        if (0x01 == (SSTAT1 & 0x01))                                                                        
        {
                ReadData = SRXBUF;

                if (0 == InterruptIndex)
                {
                        //收到Sub地址
                        if (ReadData < BUFF_MAX)
                        {
                                DataTxIndex = ReadData;               
                                DataRxIndex = ReadData;        

                                WrtieTxBufFlag = 1;
                        }
                }
                else
                {
                        WrtieTxBufFlag = 0;

                        if (DataRxIndex < BUFF_MAX)
                        {
                                DataBuf[DataRxIndex] = ReadData;                                       
                                DataRxIndex++;
                        }                                       
                }               
                InterruptIndex++;

                SSTAT1 &= 0xFE;
        }        
}

/*---------------------------------EUART0 ISR--------------------------------------------*/
void EUART0ISR(void) interrupt EUART0_VECTOR //using 2
{
        if(S0CON & RI0)                                                                                  //接收中斷
        {

        }
        RI0 = 0;                                                                                                                //清中斷標志位
}
程序主要不懂在下面這一段
if (0 == InterruptIndex)
{
//收到Sub地址
if (ReadData < BUFF_MAX)
{
DataTxIndex = ReadData;
DataRxIndex = ReadData;
WrtieTxBufFlag = 1;
}
}
else
{
WrtieTxBufFlag = 0;
if (DataRxIndex < BUFF_MAX)
{
DataBuf[DataRxIndex] = ReadData;
DataRxIndex++;
}
}
InterruptIndex++;
SSTAT1 &= 0xFE;
}
}
為什么if (0 == InterruptIndex)要這樣判斷,這樣的不就會丟失第一個數據么
if (ReadData < BUFF_MAX)
{
DataTxIndex = ReadData;
DataRxIndex = ReadData;
WrtieTxBufFlag = 1;這段程序到底是啥意思,看不懂

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:123289 發表于 2022-9-22 08:49 | 只看該作者
這么長,是不是考慮一下:需要問的地方做夠明顯標記。
回復

使用道具 舉報

板凳
ID:1043477 發表于 2022-9-22 09:10 | 只看該作者
yzwzfyz 發表于 2022-9-22 08:49
這么長,是不是考慮一下:需要問的地方做夠明顯標記。

好的,我等等把問的字體放大一下
回復

使用道具 舉報

地板
ID:1043477 發表于 2022-9-22 09:14 | 只看該作者
自己頂一下,對孩子很重要
回復

使用道具 舉報

5#
ID:624769 發表于 2022-9-23 12:13 | 只看該作者
為什么if (0 == InterruptIndex)要這樣判斷,這樣的不就會丟失第一個數據么
=〉  第一數據,不是長度么? 下面不是把 長度賦值給 INDEX了么?

if (ReadData < BUFF_MAX)
{
DataTxIndex = ReadData;
DataRxIndex = ReadData;
WrtieTxBufFlag = 1;這段程序到底是啥意思,看不懂

=〉 如果  “長度” 小于 “緩沖池最大值”(即:沒有溢出的話), 執行后面的語句, 即:賦值給 INDEX, 寫發送標志置1,等等。
回復

使用道具 舉報

6#
ID:1043477 發表于 2022-9-24 15:11 | 只看該作者
188610329 發表于 2022-9-23 12:13
為什么if (0 == InterruptIndex)要這樣判斷,這樣的不就會丟失第一個數據么
=〉  第一數據,不是長度么?  ...

的確很怪,我已經大改了程序,現在勉強可以使用,還不完善,如果后續有問題,大佬再幫忙解答一下
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 免费成人高清 | 午夜激情国产 | 91视频观看 | 午夜精品久久久久久久久久久久久 | 欧美日韩精品中文字幕 | 亚洲日韩视频 | 91一区二区| 一级黄色片网站 | 一区二区三区在线播放 | 在线伊人网 | 亚洲久久| 国产不卡视频在线 | 一区二区三区高清不卡 | 玖玖视频免费 | 在线观看亚洲专区 | 伊人伊成久久人综合网站 | 国产精品99久久久精品免费观看 | 国产亚洲人成a在线v网站 | 四季久久免费一区二区三区四区 | 久久精品久久久久久 | 久久成人国产精品 | 欧美99 | 国产精品中文字幕在线观看 | 最新超碰 | 国产精品成人69xxx免费视频 | 午夜精品久久久久久久久久久久久 | a免费视频 | 2019天天干天天操 | 成人精品一区 | 日韩最新网站 | 国产精品视频网站 | 99re国产精品 | 亚洲精品乱码久久久久久按摩观 | 国产一级电影在线观看 | 亚洲精品日韩欧美 | 欧洲尺码日本国产精品 | www亚洲一区 | 伊人春色在线观看 | 亚洲传媒在线 | 天天看逼| 久久久久国产一区二区三区四区 |