Cjy_JDxy 发表于 2019-12-18 18:58

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

今晚捣鼓了一下AT24C04,模拟时序,开漏输出。
代码:
#include "main.h"

/** @addtogroup Projects_Examples_MD
* @{
*/

/** @addtogroup Examples
* @{
*/
#define uchar unsigned char
#define uintunsigned 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;

/****************************************************************************
* ?    ?: 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;

}

/**
* @briefThis function configures GPIO
* @paramNone
* @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);
}


/**
* @briefTest main function
* @retval Status.
*/
int main()
{
        md_init_1ms_tick();
        config_gpio();
        buffer=ReadChar(0);
        Delay(100);         //??????
        WriteChar(0,0x55);
        Delayms(20);
        WriteChar(1,0xaa);
        Delayms(20);
        WriteChar(2,0x18);
        Delayms(20);
        buffer=ReadChar(1);
        buffer=ReadChar(2);
        buffer=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
根本不需要使用指针,直接操作变量就可以避免这个问题,直接判断那个位值就可以了 ...

好的
页: [1]
查看完整版本: 【东软载波ESF0654 PDS开发板活动】+ AT24C04