GD32E230C8T6《调试篇》之 (硬件) IIC通信 + GN1650驱动芯片 + 4位8段数码管显示(未成功)

GD32E230C8T6《调试篇》之 (硬件) IIC通信 + GN1650驱动芯片 + 4位8段数码管显示(未成功)

  • 前言
  • GN1650
  • IIC简介
  • 测试工具——逻辑分析仪
  • 代码

前言

芯片型号更换成E230了

GN1650

GN1650是2线串口共阴极8段4位,7*4位键盘扫描并带部分组合按键功能驱动控制专用电路。
内部集成有MCU输入输出控制数字接口、数据锁存器、LED驱动、键盘扫描、辉度调节等电路。本芯片性能稳定、质量可靠、抗干扰能力强,可适应于24小时长期连续工作的应用场合。
通信接口:类IIC,使用了IIC相同的时序,但没有完全遵守IIC的协议,不带从机地址

使用一款新的芯片时,首先就要查看其芯片规格书,以上来自GN1650规格书

GD32E230C8T6《调试篇》之 (硬件) IIC通信 + GN1650驱动芯片 + 4位8段数码管显示(未成功)_第1张图片
我使用了2、3脚和GD32E23的42、43脚连接,

GD32E230C8T6《调试篇》之 (硬件) IIC通信 + GN1650驱动芯片 + 4位8段数码管显示(未成功)_第2张图片
GN1650没有TM1650的文档详细,看的还是费劲;
上图的红色字的意思为:要先写入想显示的数据,再开启数码管显示;
GD32E230C8T6《调试篇》之 (硬件) IIC通信 + GN1650驱动芯片 + 4位8段数码管显示(未成功)_第3张图片
GD32E230C8T6《调试篇》之 (硬件) IIC通信 + GN1650驱动芯片 + 4位8段数码管显示(未成功)_第4张图片
GN1650就这么多有用信息,对于没有使用过1650的友友真的不友好;
再看TM1650的规格书,看看能不能提供有价值的线索
GD32E230C8T6《调试篇》之 (硬件) IIC通信 + GN1650驱动芯片 + 4位8段数码管显示(未成功)_第5张图片
所以,GN1650的B7~B0 0100 1000就是系统指令0x48;GN1650的时序和TM1650的时序图差不多,我们参考一下;
可以看出GN1650的一个时序要包含ADDRESS和DATA,不能分开发,我在这里踩过坑;

IIC简介

I2C(Inter-Integrated Circuit BUS) 集成电路总线,该总线由NXP(原PHILIPS)公司设计,多用于主控制器和从器件间的主从通信,在小数据量场合使用,传输距离短,任意时刻只能有一个主机等特性。
软件IIC:软件IIC通信指的是用单片机的两个I/O端口模拟出来的IIC,用软件控制管脚状态以模拟I2C通信波形,软件模拟寄存器的工作方式。
硬件IIC:一块硬件电路,硬件I2C对应芯片上的I2C外设,有相应I2C驱动电路,其所使用的I2C管脚也是专用的,硬件(固件)I2C是直接调用内部寄存器进行

测试工具——逻辑分析仪

除了CLK、GND,找其他通道连接数码管的SCL和SDA,GND接数码管的负极;
GD32E230C8T6《调试篇》之 (硬件) IIC通信 + GN1650驱动芯片 + 4位8段数码管显示(未成功)_第6张图片

这种有输出波形的实验,还是要借助工具,不然很难知道错在哪;
参照了网上的方法以及GD32e230的例程,用逻辑分析仪还是没有抓到IIC的时序波形 ,所以数码管肯定不会亮;

GD32E230C8T6《调试篇》之 (硬件) IIC通信 + GN1650驱动芯片 + 4位8段数码管显示(未成功)_第7张图片

代码

#define I2C0_SLAVE_GN1650    0x68 //DIG1
uint8_t i;

/******PA0用作测试脚,每隔50ms输出一次高低电平,对实验没有影响***/
void myGPIO_init(void)
{
	 /* enable GPIOB clock */
	 rcu_periph_clock_enable(RCU_GPIOA);	
		
	 gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ,GPIO_PIN_0);//  GPIO_OTYPE_PP推挽输出
	 gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO_PIN_0);	
}


//主函数处理,系统资源管理线程独占阻塞模式
int main(void)
{
	systick_config();
		
	myGPIO_init();
	
	delay_ms(100);
 	
	i2c_config();

    while(1)
	{
		gpio_bit_set(GPIOA,GPIO_PIN_0);
		delay_ms(50);
		gpio_bit_reset(GPIOA,GPIO_PIN_0);
		delay_ms(50);
		GN1650_Show();
	}
 
}

/********** 数码管显示 **********/
void  GN1650_Show(void)
{	
	uint16_t n;
	n = 0x01;
	unsigned short  *ndata;
	ndata = &n;
	GN1650_Wrt_RAM(0x68,ndata,16);	
	GN1650_Wrt_RAM(0x48,ndata,16);//0x48 系统指令  0x41//4级亮度 8段显示 显示开
	
} 

void GN1650_Wrt_RAM(uint8_t Address, unsigned short *ndata,uint8_t size)
{
	uint8_t timeoutcnt = 10;
	uint8_t timeoutcnt_t = 0;
	
	timeoutcnt_t = timeoutcnt;
	/* wait until I2C bus is idle */
    while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY))
	{
		if(timeoutcnt_t > 0) timeoutcnt_t--;
		else break;
	}
	
	/* send a start condition to I2C bus */
	i2c_start_on_bus(I2C0);
	
	
	timeoutcnt_t = timeoutcnt;
	/* wait until SBSEND bit is set */
    while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND))
	{
		if(timeoutcnt_t > 0) timeoutcnt_t--;
		else break;		
	}
	
	/* send slave address to I2C bus*/
   // i2c_master_addressing(I2C0, I2C0_SLAVE_GN1650,I2C_RECEIVER);
	
	
	//timeoutcnt_t = timeoutcnt;
	/* wait until ADDSEND bit is set*/
//	while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND))
//	{
//		if(timeoutcnt_t > 0)	timeoutcnt_t--;
//		else break;
//	}

	/* clear ADDSEND bit */
	//i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
	
	/* send a data byte */
	i2c_data_transmit(I2C0,Address);

	timeoutcnt_t = timeoutcnt;
	/* wait until the transmission data register is empty*/
	while(!i2c_flag_get(I2C0, I2C_FLAG_TBE))
	{
		if(timeoutcnt_t > 0)	timeoutcnt_t--;
		else break;		
	}
	/* enable acknowledge */
  	i2c_ack_config(I2C0, I2C_ACK_ENABLE);

	for(i=0;i<size;i++)
	{
		/* send a data byte */
		i2c_data_transmit(I2C0,(*ndata));	
		
		timeoutcnt_t = timeoutcnt;
		/* wait until the second last data byte is received into the shift register */
		while(!i2c_flag_get(I2C0, I2C_FLAG_BTC))
		{
			if(timeoutcnt_t > 0)	timeoutcnt_t--;
			else	break;			
		}		
		ndata++;
	}
	
	/* enable acknowledge */
  	i2c_ack_config(I2C0, I2C_ACK_ENABLE);
	
	/* send a stop condition to I2C bus*/
    i2c_stop_on_bus(I2C0);
	
	timeoutcnt_t = timeoutcnt;
	/* wait until stop condition generate */ 
	while(I2C_CTL0(I2C0)&0x0200)
	{
		if(timeoutcnt_t > 0)	timeoutcnt_t--;
		else break;
	}
	
//    /* clear the STPDET bit */
//    i2c_enable(I2C0);	
}

/*!
    \brief      cofigure the I2C0 interfaces
    \param[in]  none
    \param[out] none
    \retval     none
*/

void i2c_config(void)
{
	 /* enable GPIOB clock */
	 rcu_periph_clock_enable(RCU_GPIOB);	
	 /* enable I2C0 clock */
	 rcu_periph_clock_enable(RCU_I2C0);
	
	 /* connect PB6 to I2C0_SCL */
	 gpio_af_set(GPIOB,GPIO_AF_1,GPIO_PIN_6);
	 /* connect PB7 to I2C0_SDA */
	 gpio_af_set(GPIOB,GPIO_AF_1,GPIO_PIN_7);
	
	 gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_2MHZ,GPIO_PIN_6);//PB6_42  I2C0_SCL 
	 gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_6);
	
	 gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_2MHZ,GPIO_PIN_7);//PB7_43  I2C0_SDA
	 gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_7);
			
	 /* configure I2C0 clock */
	 i2c_clock_config(I2C0,60000,I2C_DTCY_2);
	 /* configure I2C0 address */
	 i2c_mode_addr_config(I2C0,I2C_I2CMODE_ENABLE,I2C_ADDFORMAT_7BITS,I2C0_SLAVE_GN1650);
	 /* enable I2C0 */
	 i2c_enable(I2C0);
	 /* enable acknowledge */
	 i2c_ack_config(I2C0,I2C_I2CMODE_ENABLE);
	 	
}

如有不清楚的可以看看《调试篇》的三篇IIC合集 

你可能感兴趣的:(GD32资源调试篇,单片机,嵌入式硬件)