找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

帖子
查看: 1575|回復(fù): 7
打印 上一主題 下一主題
收起左側(cè)

STC15F2K60S2單片機(jī)加TMTM1637驅(qū)動(dòng)數(shù)碼管 檢測(cè)應(yīng)答錯(cuò)誤

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
程序如下:?jiǎn)栴}:當(dāng)我用多個(gè)_nop_()做延時(shí),LED2燈就會(huì)亮(我用LED檢測(cè)應(yīng)答,如果單片機(jī)沒(méi)收到應(yīng)簽就亮起),數(shù)碼管顯示正常。如果延時(shí)用for語(yǔ)句,for內(nèi)就一個(gè)_nop_(),LED2燈就不會(huì)亮,數(shù)碼管也正常。不知為什么,請(qǐng)高人指點(diǎn)。

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)                                        //延時(shí)4us 在11059200時(shí)鐘下一個(gè)nop為1us
{
uint8 i;
//不用for語(yǔ)句用_nop();LED2會(huì)亮起,說(shuō)明檢測(cè)應(yīng)答有誤
//_nop_();
//_nop_();
//_nop_();
//_nop_();

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

}

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

//***********************************************************************************
//*名稱(chēng):i2c_send_noack()                                                              *
//*功能:無(wú)應(yīng)答I2C總線(xiàn)                                                              *
//*參數(shù):無(wú)                                                                         *
//*返回:1 有NOACK信號(hào) 0 無(wú)NOACK信號(hào)                                                 *
//***********************************************************************************
void send_noack(void){
    SDA=1;  //SDA = 1; NO ACK
    I2C_delay();
    SCL=1;  //SCL = 1;
    I2C_delay();
    SCL=0;  //SCL = 0;  //START
}
// iic 應(yīng)答  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();
}

/*
* 啟動(dòng)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寫(xiě)一個(gè)字節(jié)
*/
void I2C_write(uint8 datIn) {
    uint8 mask;
    for(mask = 0x01; mask != 0;mask <<= 1){ // 先寫(xiě)高低為:(mask = 0x80; mask != 0;mask >>= 1) TM1637先寫(xiě)低位
        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); //應(yīng)答值取反以符合通常的邏輯:0=不存在或忙或?qū)懭胧。?=存在且空閑或?qū)懭氤晒?br /> }

/*
* iic讀一個(gè)字節(jié)
*/
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);
}

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

使用道具 舉報(bào)

沙發(fā)
ID:213173 發(fā)表于 2023-2-19 13:48 | 只看該作者
STC15F2K60S2是1T單片機(jī),一個(gè)_nop_()延時(shí)時(shí)間在12MHz晶振12T單片機(jī)是1us,換了運(yùn)行環(huán)境就大相徑庭了。
回復(fù)

使用道具 舉報(bào)

板凳
ID:961122 發(fā)表于 2023-2-19 14:02 | 只看該作者
都是在同一個(gè)芯片上運(yùn)行的
回復(fù)

使用道具 舉報(bào)

地板
ID:1063483 發(fā)表于 2023-2-19 20:36 | 只看該作者
void I2C_delay(void)                                        //延時(shí)4us 在11059200時(shí)鐘下一個(gè)nop為1us
{
uint8 i;
//不用for語(yǔ)句用_nop();LED2會(huì)亮起,說(shuō)明檢測(cè)應(yīng)答有誤
//_nop_();
//_nop_();
//_nop_();
//_nop_();

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

把for(i=0;i<1;i++)中的   i<1,改為  i<3,  循環(huán)4次,應(yīng)該可以. 并不是一個(gè)_nop_()不行,而是單片機(jī)就算響應(yīng)了,數(shù)碼管來(lái)不及響應(yīng)就過(guò)了,試試看吧
回復(fù)

使用道具 舉報(bào)

5#
ID:161164 發(fā)表于 2023-2-19 21:04 | 只看該作者
以下仿真用12Mhz開(kāi)始時(shí)間:75.25us



運(yùn)行For之后:78.75us, 耗時(shí):3.5us


運(yùn)行nop之后:79.92us, 耗時(shí):1.17us



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

使用道具 舉報(bào)

6#
ID:961122 發(fā)表于 2023-2-20 13:43 | 只看該作者
lkc8210 發(fā)表于 2023-2-19 21:04
以下仿真用12Mhz開(kāi)始時(shí)間:75.25us

感謝各位,受教了。不但知道了結(jié)果,也了解了分析問(wèn)題的方法。嚴(yán)謹(jǐn)性值得佩服!
回復(fù)

使用道具 舉報(bào)

7#
ID:961122 發(fā)表于 2023-2-21 21:16 | 只看該作者
用USBee測(cè)了4個(gè)nop的延時(shí),高電平延時(shí)只有2us不到,不知為什么?

a.jpg (252.18 KB, 下載次數(shù): 50)

a.jpg
回復(fù)

使用道具 舉報(bào)

8#
ID:961122 發(fā)表于 2023-2-21 21:19 | 只看該作者
用usbee測(cè)了一下,SCL高電平中延時(shí)了2us不到,同一個(gè)延時(shí)為什么低電平有6us。真不知為什么?

a.jpg (252.18 KB, 下載次數(shù): 61)

aa

aa
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表