[国产单片机] 【东软载波ESF0654 PDS开发板活动】+ AT24C04

[复制链接]
 楼主| 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);

 楼主| Cjy_JDxy 发表于 2019-12-19 17:45 | 显示全部楼层
ayb_ice 发表于 2019-12-19 17:19
这样你看行吗如果是小端格式,可以这样
c=(addr&0x01)?0x02:0x00;
c =( (addr & 0x01) ...

没看懂啊?给我讲讲好吗?谢谢
ayb_ice 发表于 2019-12-20 08:35 | 显示全部楼层
Cjy_JDxy 发表于 2019-12-19 17:45
没看懂啊?给我讲讲好吗?谢谢

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

比如uint MyVar = 0x1234;

大端模式取到值是0x12,小端模式取到的值是0x34,显然这个代码移植性不好,而且BUG隐藏的很深
 楼主| Cjy_JDxy 发表于 2019-12-20 13:15 | 显示全部楼层
ayb_ice 发表于 2019-12-20 08:35
如果强行把一个16位变量的地址强制转换成指向8位变量的指针,取出的值在大端模式与小端模式是不同的,

...

谢谢!你的代码是怎么避免这个问题得呢?
ayb_ice 发表于 2019-12-20 13:54 | 显示全部楼层
Cjy_JDxy 发表于 2019-12-20 13:15
谢谢!你的代码是怎么避免这个问题得呢?

根本不需要使用指针,直接操作变量就可以避免这个问题,直接判断那个位值就可以了
 楼主| Cjy_JDxy 发表于 2019-12-20 14:16 | 显示全部楼层
ayb_ice 发表于 2019-12-20 13:54
根本不需要使用指针,直接操作变量就可以避免这个问题,直接判断那个位值就可以了 ...

好的
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

553

主题

3530

帖子

20

粉丝
快速回复 在线客服 返回列表 返回顶部