#include <stm32f10x.h>
#define _BV(n) (1 << (n))
#define SCL_1 GPIOB->BSRR = _BV(6)
#define SCL_0 GPIOB->BRR = _BV(6)
#define SDA ((GPIOB->IDR & _BV(7)) != 0)
#define SDA_1 GPIOB->BSRR = _BV(7)
#define SDA_0 GPIOB->BRR = _BV(7)
#define SDA_R GPIOB->CRL = 0x83000000
#define SDA_W GPIOB->CRL = 0x33000000
uint8_t num = 0;
uint8_t seg8[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90};
void delay_short(void)
{
    uint8_t i;
    for (i = 0; i < 6; i++);
}
void delay(void)
{
    uint32_t i;
    for (i = 0; i < 20000; i++);
}
void SerIn(uint8_t data)
{
    uint8_t i;
    for (i = 0; i < 8; i++)
    {
        GPIOC->BRR = _BV(15);
        if (data & 0x80)
            GPIOA->BSRR = _BV(0);
        else
            GPIOA->BRR = _BV(0);
        GPIOC->BSRR = _BV(15);
        data <<= 1;
    }
}
void ParOut(void)
{
    GPIOC->BRR = _BV(14);
    GPIOC->BSRR = _BV(14);
}
void seg_scan(void)
{
    SerIn(seg8[num / 100]);
    SerIn(_BV(2));
    ParOut();
    delay();
    
    SerIn(seg8[num % 100 / 10]);
    SerIn(_BV(1));
    ParOut();
    delay();
    
    SerIn(seg8[num % 10]);
    SerIn(_BV(0));
    ParOut();
    delay();
}
void I2CStart(void)
{
    SDA_1;
    SCL_1;
    delay_short();
    SDA_0;
    delay_short();
}
void I2CStop(void)
{
    SDA_0;
    SCL_1;
    delay_short();
    SDA_1;
    
    // 必须延长足够的时间
    delay();
    delay();
}
uint8_t I2CAck(void)
{
    uint8_t ack;
    SDA_1;
    SCL_0;
    delay_short();
    SDA_R; // 这两行不可交换!
    SCL_1; //
    delay_short();
    ack = SDA;
    SDA_W;
    SCL_0;
    return !ack;
}
void I2CSendAck(uint8_t ack)
{
    if (ack)
        SDA_0;
    else
        SDA_1;
    delay_short();
    SCL_1;
    delay_short();
    SCL_0;
}
uint8_t I2CWrite(uint8_t dat)
{
    uint8_t i;
    for (i = 0; i < 8; i++)
    {
        SCL_0;
        if (dat & 0x80)
            SDA_1;
        else
            SDA_0;
        dat <<= 1;
        SCL_1;
        delay_short();
    }
    SCL_0;
    return I2CAck();
}
uint8_t I2CRead(void)
{
    uint8_t i;
    uint8_t dat = 0;
    SDA_1;
    SDA_R;
    for (i = 0; i < 8; i++)
    {
        SCL_1;
        dat <<= 1;
        if (SDA)
            dat |= 1;
        SCL_0;
        delay_short();
    }
    SDA_W;
    return dat;
}
void read(void)
{
    I2CStart();
    I2CWrite(0xa0);
    I2CWrite(0x00); // 从0x00处开始连续读三个字节
    I2CStart();
    I2CWrite(0xa1);
    I2CRead();
    I2CSendAck(1);
    I2CRead();
    I2CSendAck(1);
    num = I2CRead();
    I2CSendAck(0);
    I2CStop();
}
void write(void)
{
    I2CStart();
    I2CWrite(0xa0);
    I2CWrite(0x01); // 从0x01处开始连续写两个字节
    I2CWrite(36);
    I2CWrite(51);
    I2CStop();
}
int main(void)
{
    RCC->APB2ENR = 0x1c; // 开启PA、PB、PC时钟
    GPIOA->CRL = 0x00000003; // PA0设为输出
    GPIOB->CRL = 0x33000000; // PB6~7设为推挽50MHz输出
    GPIOC->CRH = 0x33000000; // PC14~15设为输出
    
    // 初始化总线
    SCL_1;
    SDA_1;
    
    write();
    read();
    
    while (1)
    {
        seg_scan(); // 数码管显示051
    }
}
            
                      


