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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1520|回復: 7
收起左側

STC15F2K60S2單片機加TMTM1637驅動數碼管 檢測應答錯誤

[復制鏈接]
ID:961122 發表于 2023-2-19 11:00 | 顯示全部樓層 |閱讀模式
程序如下:問題:當我用多個_nop_()做延時,LED2燈就會亮(我用LED檢測應答,如果單片機沒收到應簽就亮起),數碼管顯示正常。如果延時用for語句,for內就一個_nop_(),LED2燈就不會亮,數碼管也正常。不知為什么,請高人指點。

I2C_DRIVE.C

I2C_DRIVE.C

#define _I2C_DRIVE_C

#include "reg51.h"
#include "I2C_drive.h"
#include "INTRINS.H"

sbit SCL          =                   P2^0 ;                //???????IIC???????
sbit SDA          =                   P2^1 ;                //???????IIC????????

void I2C_delay(void)                                        //延時4us 在11059200時鐘下一個nop為1us
{
uint8 i;
//不用for語句用_nop();LED2會亮起,說明檢測應答有誤
//_nop_();
//_nop_();
//_nop_();
//_nop_();

for(i=0;i<1;i++){   
    _nop_();
}

}

void I2C_Init(void)//IIC初始化
{
//  P2M1 |= 0x03;      //P1.5、P1.6定義為輸出
//  P2M0 |= 0x03;   
}

//***********************************************************************************
//*名稱:i2c_send_noack()                                                              *
//*功能:無應答I2C總線                                                              *
//*參數:無                                                                         *
//*返回:1 有NOACK信號 0 無NOACK信號                                                 *
//***********************************************************************************
void send_noack(void){
    SDA=1;  //SDA = 1; NO ACK
    I2C_delay();
    SCL=1;  //SCL = 1;
    I2C_delay();
    SCL=0;  //SCL = 0;  //START
}
// iic 應答  for slaver
void send_ack(void) {
    SDA=0; //OUT 0 ACK
    I2C_delay();
    SCL=1;
    I2C_delay();
    SCL=0;
}

/*
*停止iic
*/
void I2C_stop(void){
    SDA=0;
    SCL=0;  //SCL = 0;
    I2C_delay();
    SCL=1;  //SCL = 1;  STOP
    I2C_delay();
    SDA=1;  //SDA = 1;
    I2C_delay();
}

/*
* 啟動iic
*/
//  static void start(void) {
void I2C_start(void){

    SDA=1;  //SDA = 1;
    SCL=1;  //SCL = 1;
    I2C_delay();
    SDA=0;  //SDA = 0;
    I2C_delay();
    SCL=0;  //SCL = 0;  //START
}

/*
* iic寫一個字節
*/
void I2C_write(uint8 datIn) {
    uint8 mask;
    for(mask = 0x01; mask != 0;mask <<= 1){ // 先寫高低為:(mask = 0x80; mask != 0;mask >>= 1) TM1637先寫低位
        if((mask & datIn) == 0)
            SDA = 0;
        else
            SDA = 1;
        I2C_delay();
        SCL = 1;
        I2C_delay();
        SCL = 0;
    }
}
uint8 check_ack(void) {
    uint8 ack_flag;

    SDA = 1;
    I2C_delay();
    SCL = 1;    //read ask begin
    I2C_delay();

    ack_flag=SDA;
    I2C_delay();
    SCL = 0;    //read ask end
    return (~ack_flag); //應答值取反以符合通常的邏輯:0=不存在或忙或寫入失敗,1=存在且空閑或寫入成功
}

/*
* iic讀一個字節
*/
uint8 I2C_read(void) {
    uint8 mask,dat;
    SDA =1 ;

    for(mask = 0x80; mask != 0;mask >>= 1){
        I2C_delay();
        SCL = 1;
        if(SDA == 0)
            dat &= ~mask;
        else
            dat |= mask;
        I2C_delay();
        SCL = 0;
    }
    return dat;
}




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

MAIN.C
#include "REG51.H"
#include "I2C_drive.h"
sbit LED0   = P1^0;  
sbit LED1   = P1^1;
sbit LED2   = P1^2;
sbit LED3   = P1^3;

void main(){
  uint8 i;


  I2C_start();
  I2C_write(0x40);
  if(~check_ack()) LED0=0;
  I2C_stop();
  I2C_start();
  I2C_write(0xC0);
  if(~check_ack()) LED1=0;
  for(i=0;i<4;i++){
    I2C_write(0xff);
    if(~check_ack()) LED2=0;
  }
  I2C_stop();
  I2C_start();
  I2C_write(0x8f);
   if(~check_ack()) LED3=0;
  I2C_stop();

  while (1);
}

回復

使用道具 舉報

ID:213173 發表于 2023-2-19 13:48 | 顯示全部樓層
STC15F2K60S2是1T單片機,一個_nop_()延時時間在12MHz晶振12T單片機是1us,換了運行環境就大相徑庭了。
回復

使用道具 舉報

ID:961122 發表于 2023-2-19 14:02 | 顯示全部樓層
都是在同一個芯片上運行的
回復

使用道具 舉報

ID:1063483 發表于 2023-2-19 20:36 | 顯示全部樓層
void I2C_delay(void)                                        //延時4us 在11059200時鐘下一個nop為1us
{
uint8 i;
//不用for語句用_nop();LED2會亮起,說明檢測應答有誤
//_nop_();
//_nop_();
//_nop_();
//_nop_();

for(i=0;i<3;i++){   
    _nop_();
}

把for(i=0;i<1;i++)中的   i<1,改為  i<3,  循環4次,應該可以. 并不是一個_nop_()不行,而是單片機就算響應了,數碼管來不及響應就過了,試試看吧
回復

使用道具 舉報

ID:161164 發表于 2023-2-19 21:04 | 顯示全部樓層
以下仿真用12Mhz開始時間:75.25us

2023-02-19_184910.png

運行For之后:78.75us, 耗時:3.5us
2023-02-19_184920.png

運行nop之后:79.92us, 耗時:1.17us
2023-02-19_184929.png


用nop延時的時間太短
不足以讓1637返回Ack(拉低電平)
但1637收到命令和數據
所以也可以正常顯示
回復

使用道具 舉報

ID:961122 發表于 2023-2-20 13:43 | 顯示全部樓層
lkc8210 發表于 2023-2-19 21:04
以下仿真用12Mhz開始時間:75.25us

感謝各位,受教了。不但知道了結果,也了解了分析問題的方法。嚴謹性值得佩服!
回復

使用道具 舉報

ID:961122 發表于 2023-2-21 21:16 | 顯示全部樓層
用USBee測了4個nop的延時,高電平延時只有2us不到,不知為什么?
a.jpg
回復

使用道具 舉報

ID:961122 發表于 2023-2-21 21:19 | 顯示全部樓層
用usbee測了一下,SCL高電平中延時了2us不到,同一個延時為什么低電平有6us。真不知為什么?

aa

aa
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美在线一二三 | 欧美高清一级片 | av男人的天堂av | 午夜在线 | 亚洲精品一区二区 | 国产91久久精品一区二区 | 亚洲免费视频播放 | 91久久久久久久久 | 日韩二三区| 在线中文一区 | 国产精品久久久久久久毛片 | 成人不卡视频 | 伊人影院在线观看 | 国产激情一区二区三区 | 久久精品免费观看 | 国产成人精品亚洲日本在线观看 | 国产欧美日韩一区 | www久久久| 91在线精品秘密一区二区 | 亚洲一区视频在线 | 久久国内| 午夜免费在线观看 | 国产精品一区二区福利视频 | 国产精品一区在线播放 | 欧美一级黄色片在线观看 | 国产日韩一区二区 | 欧美一区二区小视频 | 成人高清在线视频 | 亚洲乱码一区二区 | 99re在线播放| 天天操天天舔 | 亚洲字幕在线观看 | 欧美成视频在线观看 | 精品久久久一区 | 久久在线看 | 国产亚洲精品久久情网 | 国产黄色小视频 | 天天欧美 | 亚洲精品久久久久久久久久久久久 | 午夜久久久久 | 九九热这里只有精品6 |