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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

單片機GPIO模擬I2C 寫EEPROM延時問題

[復制鏈接]
跳轉到指定樓層
樓主
ID:997026 發表于 2023-7-29 20:00 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
大家好,

我用GPIO模擬I2C,和外部EEPROM通信,主要是單片機向EEPROM寫入數據,寫入時規格書要求必須延時5ms.
我現在的程序延時用的是嘀嗒延時,嘀嗒定時器延時應該也是阻塞式延時,我現在要做的就是消除程序里所有的阻塞式延時,其他的延時已經用定時器延改成了非阻塞了,就是這個寫EEPROM,我是怎么也沒想到比較好的非阻塞延時方式,如果用定時器來延時,沒有好的思路。

部分代碼如下,
void Write_EEPROM(uint8_t address,uint8_t data,uint8_t paddr) //寫數據到EEPROM
{
    IIC_GPIO_Start();
    IIC_WriteOneByte(paddr);
    IIC_WriteOneByte(address);
    IIC_WriteOneByte(data);
    IIC_GPIO_Stop();  
    Systick_delay_ms(5); //此處寫完后延時5ms,用的是阻塞式延時,怎么改成非阻塞延時?
}


希望得到各位的幫助,謝謝
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:883242 發表于 2023-7-31 06:53 | 只看該作者
非阻塞就要把CPU控制權交給其他任務執行,最簡單的做法是上RTOS。
回復

使用道具 舉報

板凳
ID:1087948 發表于 2023-7-31 12:46 | 只看該作者
你可以使用一個狀態機和定時器中斷來實現非阻塞延時。在這種情況下,你需要將寫EEPROM的過程分解為幾個步驟,并為每個步驟定義一個狀態。然后,你可以在定時器中斷服務程序中改變狀態。

以下是一個簡單的示例:

c
typedef enum {
    STATE_IDLE,
    STATE_START,
    STATE_WRITE_PADDR,
    STATE_WRITE_ADDRESS,
    STATE_WRITE_DATA,
    STATE_STOP,
    STATE_DELAY
} State;

volatile State state = STATE_IDLE;
uint8_t address, data, paddr;

void TIMx_IRQHandler(void) // 定時器中斷服務程序
{
    if (TIM_GetITStatus(TIMx, TIM_IT_Update) != RESET)
    {
        TIM_ClearITPendingBit(TIMx, TIM_IT_Update);
        
        switch (state)
        {
            case STATE_IDLE:
                break;
               
            case STATE_START:
                IIC_GPIO_Start();
                state = STATE_WRITE_PADDR;
                break;
               
            case STATE_WRITE_PADDR:
                IIC_WriteOneByte(paddr);
                state = STATE_WRITE_ADDRESS;
                break;
               
            case STATE_WRITE_ADDRESS:
                IIC_WriteOneByte(address);
                state = STATE_WRITE_DATA;
                break;
               
            case STATE_WRITE_DATA:
                IIC_WriteOneByte(data);
                state = STATE_STOP;
                break;
               
            case STATE_STOP:
                IIC_GPIO_Stop();
                state = STATE_DELAY;
                break;
               
            case STATE_DELAY:
                // 延時5ms后,返回到空閑狀態
                static int delayCounter = 0;
                if (++delayCounter >= 5)
                {
                    delayCounter = 0;
                    state = STATE_IDLE;
                }
                break;
        }
    }
}

void Write_EEPROM(uint8_t _address, uint8_t _data, uint8_t _paddr)
{
    // 如果當前狀態為空閑,則開始寫入過程
    if (state == STATE_IDLE)
    {
        address = _address;
        data = _data;
        paddr = _paddr;
        state = STATE_START;
    }
}
這樣,你就可以在主循環中調用Write_EEPROM函數,而不會阻塞其他任務。只有當寫入過程完成(即狀態返回到STATE_IDLE)時,才能開始新的寫入過程。
回復

使用道具 舉報

地板
ID:401564 發表于 2023-7-31 12:56 | 只看該作者
你選擇了模擬IIC,就注定了效率會變慢的
但這5mS是不需要這樣等待的
把等待低電平的部分重新寫一個函數
Write_EEPROM只管釋放SDA數據線和標志一個標志位,比如IIC_F,然后就函數返回
在主程序中增加一個一個檢測IIC_F的函數
進入函數后,先:
if(IIC_F & !SDA)
{
IIC_F = 0;
其它處理;
}
只有收到應答信號之后才進行對應的處理
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产精品久久久久久久久久久免费看 | 一级黄色毛片免费 | www.青青草| 狠狠干天天干 | 亚洲国产成人精品在线 | 久久天天躁狠狠躁夜夜躁2014 | 欧美伊人| 欧美综合精品 | 国产精品777一区二区 | 黄色大片在线免费观看 | 亚洲欧美综合精品久久成人 | 亚洲免费在线 | 黄网站在线观看 | 亚洲欧洲在线观看视频 | 高清免费av | 国产成人福利在线观看 | 国产精品成人免费 | 欧美一级欧美三级在线观看 | 99福利视频| 1级毛片| 久草免费在线视频 | 国产日韩欧美精品一区二区三区 | 久久国产精品久久久久久久久久 | 男人的天堂中文字幕 | 成人av电影免费在线观看 | 久草日韩 | 日韩成人在线看 | 亚洲高清av在线 | 午夜影院网站 | 国产一区二区久久 | 国产精品美女久久久久久久久久久 | 成人在线观看免费视频 | 国产日韩欧美在线观看 | 国产精品一区二 | 午夜影院黄 | 国产精品日日摸夜夜添夜夜av | 国产精品免费av | 国产大学生情侣呻吟视频 | 日韩欧美在线一区 | 综合国产第二页 | 欧美亚洲国产精品 |