[求助] 关于STM32F051模拟驱动HL9576

dwlovehome   2014-10-16 09:20 楼主
是这样的,用到了HL9576,用STM32F051的IO口模拟IIC驱动这个片子,结果发现要么就是不显示,要么就是感觉地址不对,
SCLK 用的是PB10,SDA用的是PB11 ,下面是我的驱动和显示。不知道这个有没有问题,大牛们给看看
void Init_HL9576(void)
{
        IIC_Start();
        IIC_Send_Byte(0x70); //器件地址
        IIC_Wait_Ack();
        IIC_Send_Byte(0xd8); //工作模式 省电模式
        IIC_Wait_Ack();
        IIC_Send_Byte(0xf0); //不闪烁命令
        IIC_Wait_Ack();
        for(i=0;i<20;i++)        //清屏
                IIC_Send_Byte(0x00);
        IIC_Wait_Ack();
        IIC_Stop();
}
void DisPlayDate(void)
{
        u8 i=0;
        IIC_Start();   
        IIC_Send_Byte(0x70); //发送被控器件总线地址
        IIC_Wait_Ack();
        IIC_Send_Byte(0xd8); //工作模式 省电模式
        IIC_Wait_Ack();
        IIC_Send_Byte(0x00); //首位地址 0开始
        IIC_Wait_Ack();
        for(i=0;i<5;i++)     //前5个地址全部点亮
                IIC_Send_Byte(0xff);
        IIC_Wait_Ack();
        IIC_Stop();
}


//下面是我的IIC
#define IIC_SDA_OUT_HIGH         GPIO_SetBits(GPIOB,GPIO_Pin_11)              
#define IIC_SDA_OUT_LOW          GPIO_ResetBits(GPIOB,GPIO_Pin_11)
#define IIC_SCL_OUT_HIGH        GPIO_SetBits(GPIOB,GPIO_Pin_10)
#define IIC_SCL_OUT_LOW         GPIO_ResetBits(GPIOB,GPIO_Pin_10)
#define        READ_IIC_SDA                        (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11))
//初始化IIC
void IIC_Init(void)
{                                             
        GPIO_InitTypeDef GPIO_InitStructure;
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
       
GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;                        //输出模式
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                        //推挽输出
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;                                //上拉模式
  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_10|GPIO_Pin_11;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void IIC_SDA_IO_OUT(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
       
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;                        //输出模式
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                        //推挽输出
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;                                //上拉模式
  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_11;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
}

void IIC_SDA_IO_IN(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN;                        //输入模式
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  //GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                        //输入模式下无效
        GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;//GPIO_PuPd_UP;                                //上拉模式
        GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_11;               
  GPIO_Init(GPIOB, &GPIO_InitStructure);
}

//开始IIC
void IIC_Start(void)
{
        IIC_SDA_IO_OUT();//SDA???
        IIC_SDA_OUT_HIGH;              
        IIC_SCL_OUT_HIGH;
        delay_us(8);
        IIC_SDA_OUT_LOW;//START:when CLK is high,DATA change form high to low
        delay_us(4);
        IIC_SCL_OUT_LOW;//钳住I2C总线,准备发送或接收数据
}          
//停止IIC
void IIC_Stop(void)
{
        IIC_SDA_IO_OUT();//sda线输出
        IIC_SCL_OUT_LOW;
        IIC_SDA_OUT_LOW;//STOP:when CLK is high DATA change form low to high
        delay_us(8);
        IIC_SCL_OUT_HIGH;
        IIC_SDA_OUT_HIGH;
        delay_us(4);                                                                  
}
//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
u8 IIC_Wait_Ack(void)
{
        u8 ucErrTime=0;

        IIC_SDA_OUT_HIGH;delay_us(1);          
        IIC_SCL_OUT_HIGH;delay_us(1);       
       
        IIC_SDA_IO_IN();      //SDA输入
        while(READ_IIC_SDA)
        {
                ucErrTime++;
                if(ucErrTime>250)
                {
                        IIC_Stop();
                        return 1;
                }
        }
        IIC_SCL_OUT_LOW;//时钟输出0
        IIC_SDA_IO_OUT();
        return 0;  
}
//产生ACK应答
void IIC_Ack(void)
{
        IIC_SCL_OUT_LOW;
        IIC_SDA_IO_OUT();
        IIC_SDA_OUT_LOW;
        delay_us(8);
        IIC_SCL_OUT_HIGH;
        delay_us(4);
        IIC_SCL_OUT_LOW;
}
//不产生ACK应答            
void IIC_NAck(void)
{
        IIC_SCL_OUT_LOW;
        IIC_SDA_IO_OUT();
        IIC_SDA_OUT_HIGH;
        delay_us(8);
        IIC_SCL_OUT_HIGH;
        delay_us(4);
        IIC_SCL_OUT_LOW;
}                                                                              
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答                          
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
                IIC_SDA_IO_OUT();        
    IIC_SCL_OUT_LOW;//拉低时钟开始数据传输
                delay_us(4);
    for(t=0;t<8;t++)
    {   
      if(txd&0x80)
        IIC_SDA_OUT_HIGH;
      else
                                IIC_SDA_OUT_LOW;
      txd<<=1;           
                        delay_us(8);   //?TEA5767?3????????
                        IIC_SCL_OUT_HIGH;
                        delay_us(4);
                        IIC_SCL_OUT_LOW;       
                        delay_us(4);
    }         
}             
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
u8 IIC_Read_Byte(unsigned char ack)
{
  unsigned char i,receive=0;
  IIC_SDA_IO_IN();//SDA设置为输入
  for(i=0;i<8;i++ )
  {
    IIC_SCL_OUT_LOW;
    delay_us(4);
    IIC_SCL_OUT_HIGH;

    receive<<=1;
    if(READ_IIC_SDA)
      receive++;   
    delay_us(2);
   }               
       
    if (!ack)
        IIC_NAck();//发送nACK
    else
        IIC_Ack(); //发送ACK   
                IIC_SDA_IO_OUT();
                delay_us(4);       
    return receive;
}

回复评论 (4)

IIC的模拟非常简单,但要注意时序,特别是时间延时问题
我的博客
点赞  2014-10-16 10:19
调试 IIC ,如果经验不多,一定不要着急,用示波器耐心看看波形,肯定可以找到问题的。IIC_SDA_IO_IN 可考虑 IO 设置为 float 。 从程序上来看的话, START 时序 SDA 置高后,可考虑加个延时。 还有,在适当的地方,加个 release 时序。 实在不行,上网上找一个针对 STM32 的,我之前用过 STM8L 的 IO 口模拟的,大体也差不多。
STM8L10x_SWI2C.zip (3.23 KB)
(下载次数: 6, 2014-10-16 11:43 上传)
本帖最后由 Study_Stellaris 于 2014-10-16 11:43 编辑
点赞  2014-10-16 11:22
引用: Study_Stellaris 发表于 2014-10-16 11:22
调试 IIC ,如果经验不多,一定不要着急,用示波器耐心看看波形,肯定可以找到问题的。IIC_SDA_IO_IN 可考 ...

嗯,谢谢了。我的IIC应该没什么问题,我同一条线上还挂了24C64,24C64的读写没有问题,但是就是HL9576没有显示~
点赞  2014-10-16 22:09
好好看看HL9576的时序,和寄存器设置。。。。。。。。
我的博客
点赞  2014-10-17 09:34
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复