打印
[国产单片机]

【东软载波ESF0654 PDS开发板活动】+ AT24C04

[复制链接]
452|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Cjy_JDxy|  楼主 | 2019-12-18 18:58 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
今晚捣鼓了一下AT24C04,模拟时序,开漏输出。
代码:
#include "main.h"

/** @addtogroup Projects_Examples_MD
  * @{
  */

/** @addtogroup Examples
  * @{
  */
#define uchar unsigned char
#define uint  unsigned int
       
#define SDA_L            md_gpio_set_pin_low(SDA_GPIO_PORT, SDA_GPIO_PIN);
#define SDA_H            md_gpio_set_pin_high(SDA_GPIO_PORT, SDA_GPIO_PIN);

#define SDA                                                        md_gpio_get_input_data(SDA_GPIO_PORT, SDA_GPIO_PIN)

#define SCL_L         md_gpio_set_pin_low(SCL_GPIO_PORT, SCL_GPIO_PIN);
#define SCL_H         md_gpio_set_pin_high(SCL_GPIO_PORT, SCL_GPIO_PIN);

unsigned char buffer[3];

/****************************************************************************
* ?    ?: DelayMS()
* ?    ?: ????????,???????????16M(??????????)
* ????: msec ????,???,????
* ????: ?
****************************************************************************/
void DelayMS(uint msec)
{
    uint i,j;

    for (i=0; i<msec; i++)
        for (j=0; j<535; j++);
}

/****************************************************************************
* ?    ?: InitLed()
* ?    ?: ??LED????IO?
* ????: ?
* ????: ?
****************************************************************************/

void InitSDAInput(void)
{
            md_gpio_set_pin_function(SDA_GPIO_PORT, SDA_GPIO_PIN, GPIO_FUNC_1);
                        md_gpio_set_pin_push_pull(SDA_GPIO_PORT, SDA_GPIO_PIN);
                        md_gpio_set_pin_mode_input(SDA_GPIO_PORT, SDA_GPIO_PIN);
}

void InitSDAOutput(void)
{
    md_gpio_set_pin_function(SDA_GPIO_PORT, SDA_GPIO_PIN, GPIO_FUNC_1);
                md_gpio_set_pin_push_pull(SDA_GPIO_PORT, SDA_GPIO_PIN);
                md_gpio_set_pin_mode_output(SDA_GPIO_PORT, SDA_GPIO_PIN);
                md_gpio_set_pin_open_drain(SDA_GPIO_PORT, SDA_GPIO_PIN);

}
//-----------------------------------------------------------------------------------------
//????:Delay()
//?    ?:?????
//-----------------------------------------------------------------------------------------
void Delay(unsigned char us)  //5,7,9
{
  while(--us);  
}

//-----------------------------------------------------------------------------------------
//????:Delayms()
//-----------------------------------------------------------------------------------------
void Delayms(unsigned int ims)
{
  unsigned int i,j;
    for(i=0;i<ims;i++)
      for(j=0;j<65;j++) { Delay(1); }
}

void Start()

{
        InitSDAOutput();
       
  SCL_H;
        Delay(10);
  SDA_H;
        Delay(10);
  SDA_L;
        Delay(10);
  SCL_L;
        Delay(10);
}

void Stop()

{
        InitSDAOutput();
       
  SDA_L;
        Delay(10);
  SCL_H;
        Delay(10);
  SDA_H;
        Delay(10);
}

char ACK ()

{

  char c;
        InitSDAOutput();
       
  SDA_H;
        Delay(10);
  SCL_H;
        Delay(10);
  InitSDAInput();
        Delay(10);
  if(SDA)
    c=1;
  else
    c=0;
        Delay(10);
  InitSDAOutput();
        Delay(10);
  SCL_L;
        Delay(10);
  return c;

}

void SendChar(unsigned char ch)

{

  unsigned char i;

  i=8;
        InitSDAOutput();
       
  do

  {
    if((ch&0x80)==0x80)
      SDA_H;
    if((ch&0x80)==0x00)
      SDA_L;
                Delay(10);
    SCL_H;
                Delay(10);
    SCL_L;
                Delay(10);
    ch<<=1;

  }while(--i!=0);

}
unsigned char RecChar()

{

  unsigned char i,j;

  i=8;
  j=0;
       
        InitSDAInput();
        Delay(10);
  do

  {

    SCL_H;
                Delay(10);
    j=(j<<1);
    if(SDA)
      j=j|SDA;
                Delay(10);
    SCL_L;
                Delay(10);
  }while(--i!=0);
        InitSDAOutput();
  return j;

}

void WriteChar(unsigned int addr,unsigned char ch)

{

  unsigned char c;

  c=((*((unsigned char *)&addr))<<1)&0x02;

  Start();

  SendChar(0xa0|c);

  ACK();

  SendChar(addr);

  ACK();

  SendChar(ch);

  ACK();
  Stop();

  for(ch=0xff;ch!=0;ch--) ;

}

unsigned char ReadChar(unsigned int addr)

{

  unsigned char ch;

  ch=((*((unsigned char *)&addr))<<1)&0x02;

  Start();

  SendChar(0xa0|ch);

  ACK();

  SendChar(addr);

  ACK();

  Start();

  SendChar(0xa1|ch);

  ACK();

  ch=RecChar();

  Stop();

  return ch;

}

/**
  * @brief  This function configures GPIO
  * @param  None
  * @retval None
  */
void config_gpio(void)
{
//        md_gpio_set_pin_function(CLOCK_GPIO_PORT, CLOCK_GPIO_PIN, GPIO_FUNC_1);
//        md_gpio_set_pin_push_pull(CLOCK_GPIO_PORT, CLOCK_GPIO_PIN);
//        md_gpio_set_pin_mode_input(CLOCK_GPIO_PORT, CLOCK_GPIO_PIN);

       
        md_gpio_set_pin_function(SDA_GPIO_PORT, SDA_GPIO_PIN, GPIO_FUNC_1);
        md_gpio_set_pin_push_pull(SDA_GPIO_PORT, SDA_GPIO_PIN);
        md_gpio_set_pin_mode_output(SDA_GPIO_PORT, SDA_GPIO_PIN);
        md_gpio_set_pin_open_drain(SDA_GPIO_PORT, SDA_GPIO_PIN);
       
        md_gpio_set_pin_function(SCL_GPIO_PORT, SCL_GPIO_PIN, GPIO_FUNC_1);
        md_gpio_set_pin_push_pull(SCL_GPIO_PORT, SCL_GPIO_PIN);
        md_gpio_set_pin_mode_output(SCL_GPIO_PORT, SCL_GPIO_PIN);
        md_gpio_set_pin_open_drain(SCL_GPIO_PORT, SCL_GPIO_PIN);
       
        md_gpio_set_pin_function(LED2_GPIO_PORT, LED2_GPIO_PIN, GPIO_FUNC_1);
        md_gpio_set_pin_push_pull(LED2_GPIO_PORT, LED2_GPIO_PIN);
        md_gpio_set_pin_mode_output(LED2_GPIO_PORT, LED2_GPIO_PIN);
}


/**
  * @brief  Test main function
  * @retval Status.
  */
int main()
{
        md_init_1ms_tick();
        config_gpio();
        buffer[0]=ReadChar(0);
        Delay(100);           //??????
        WriteChar(0,0x55);
        Delayms(20);
        WriteChar(1,0xaa);
        Delayms(20);
        WriteChar(2,0x18);
        Delayms(20);
        buffer[0]=ReadChar(1);
        buffer[1]=ReadChar(2);
        buffer[2]=ReadChar(0);
        while (1)
        {
               
        }
}

效果图:


使用特权

评论回复

相关帖子

沙发
ayb_ice| | 2019-12-19 13:52 | 只看该作者
c=((*((unsigned char *)&addr))<<1)&0x02;

这个语句很危险,与大小端有关系,移植性不好,可读性不好

使用特权

评论回复
板凳
Cjy_JDxy|  楼主 | 2019-12-19 16:57 | 只看该作者
ayb_ice 发表于 2019-12-19 13:52
c=((*((unsigned char *)&addr))

是啊。你说怎么写好呢?大神

使用特权

评论回复
地板
ayb_ice| | 2019-12-19 17:19 | 只看该作者
本帖最后由 ayb_ice 于 2019-12-19 17:23 编辑
Cjy_JDxy 发表于 2019-12-19 16:57
是啊。你说怎么写好呢?大神

这样你看行吗如果是小端格式,可以这样
c=(addr&0x01)?0x02:0x00;
c =( (addr & 0x01)<<1);

使用特权

评论回复
5
Cjy_JDxy|  楼主 | 2019-12-19 17:45 | 只看该作者
ayb_ice 发表于 2019-12-19 17:19
这样你看行吗如果是小端格式,可以这样
c=(addr&0x01)?0x02:0x00;
c =( (addr & 0x01) ...

没看懂啊?给我讲讲好吗?谢谢

使用特权

评论回复
6
ayb_ice| | 2019-12-20 08:35 | 只看该作者
Cjy_JDxy 发表于 2019-12-19 17:45
没看懂啊?给我讲讲好吗?谢谢

如果强行把一个16位变量的地址强制转换成指向8位变量的指针,取出的值在大端模式与小端模式是不同的,

比如uint MyVar = 0x1234;

大端模式取到值是0x12,小端模式取到的值是0x34,显然这个代码移植性不好,而且BUG隐藏的很深

使用特权

评论回复
7
Cjy_JDxy|  楼主 | 2019-12-20 13:15 | 只看该作者
ayb_ice 发表于 2019-12-20 08:35
如果强行把一个16位变量的地址强制转换成指向8位变量的指针,取出的值在大端模式与小端模式是不同的,

...

谢谢!你的代码是怎么避免这个问题得呢?

使用特权

评论回复
8
ayb_ice| | 2019-12-20 13:54 | 只看该作者
Cjy_JDxy 发表于 2019-12-20 13:15
谢谢!你的代码是怎么避免这个问题得呢?

根本不需要使用指针,直接操作变量就可以避免这个问题,直接判断那个位值就可以了

使用特权

评论回复
9
Cjy_JDxy|  楼主 | 2019-12-20 14:16 | 只看该作者
ayb_ice 发表于 2019-12-20 13:54
根本不需要使用指针,直接操作变量就可以避免这个问题,直接判断那个位值就可以了 ...

好的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:绿水本无忧因风皱面,青山原不老为雪白头。

553

主题

3520

帖子

19

粉丝