|
前言 某宝立华家一款8*8点阵模块电路板(机器人眼睛)价格便宜,近期入手多块。该板含两个8*8点阵屏,驱动芯片为FZH119(方中禾),FZH119主要用于8段16位共阴极或16段8位共阳极数码管驱动。经查询FZH119用于点阵屏的例子不多,但点阵屏和数码管是相通的。为实现点阵屏驱动,本文多有借鉴前辈们数码管驱动源码。 同时该电路板可能存在安装和设计缺陷,滤波电容极性反接,走线不走寻常路。本来FZH119只要注意数据低位在前高位在后,可以用IIC驱动点阵。但正常的IIC在该板表现为乱码。为解决乱码问题,加入了2个数组seg_sq[]、grid_sq[]来控制段位输出顺序。本人初学不知道这样控制是否合理,不会是画蛇添足吧。不管怎么说最后实现了正常显示。 
话不多直接上源码。 一、源码1.IIC头文件“my_iic.h”
- #ifndef __MY_IIC_H
- #define __MY_IIC_H
- #include <STC15F2K60S2.H>
- #include "intrins.h"
-
- sbit I2C_SDA = P3^7;
- sbit I2C_SCL = P3^6;
-
- void I2C_init(void);
- void I2C_Start(void);
- void I2C_Stop(void);
- void I2C_SendByte(unsigned char Byte);
- void I2c_nbByte(unsigned char cmd,unsigned char* str,unsigned char len);
- void I2c_cmdSend(signed char cmd);
- void I2c_nbREyeByte(unsigned char cmd,unsigned char* str,unsigned char len);
-
- #endif
复制代码
2.IIC实现文件“my_iic.c”代码如下(示例):
- #include "my_iic.h"
- #include "intrins.h"
-
- int grid_sq[]={1,3,0,4,6,7,5,2,8,11,9,10,13,15,14,12};
- unsigned char seg_sq[]={0x08,0x20,0x40,0x80,0x04,0x10,0x02,0x01};
-
-
- //2微秒
- void delay(void)
- {
- /* _nop_();
- ;*/
- }
-
-
- /**
- * @brief I2C初始化
- * @param 无
- * @retval 无
- *
- */
- void I2C_init(void)
- {
- I2C_SDA = 1; //
- delay();
- I2C_SCL = 1;
- delay();
- }
-
-
- /**
- * @brief I2C起始信号
- * @param 无
- * @retval 无
- * 起始条件:SCL高电平期间,SDA从高电平切换到低电平
- */
- void I2C_Start(void)
- {
- I2C_SDA = 1; //拼接其他块,确保默认是1
- I2C_SCL = 1;
- delay();
- I2C_SDA = 0; //时序上先拉低
- delay();
- I2C_SCL = 0;
- }
-
- /**
- * @brief I2C停止信号
- * @param 无
- * @retval 无
- * 终止条件:SCL高电平期间,SDA从低电平切换到高电平
- */
- void I2C_Stop(void)
- {
- I2C_SDA = 0; //确保默认0,保证由低电平拉高至高电平
- I2C_SCL = 1;
- delay();
- I2C_SDA = 1;
- }
-
-
- /**
- * @brief I2C发送一个字节数据
- * @param Byte 要发送的字节
- * @retval 无
- * 微处理器的数据通过两线总线接口和 FZH119 通信,在输入数据时当 CLK 是高电平时,DIN 上的信号
- 必须保持不变;只有 CLK 上的时钟信号为低电平时,DIN 上的信号才能改变。数据的输入总是低位在前,高位
- 在后传输.数据输入的开始条件是 CLK 为高电平时,DIN 由高变低;结束条件是 CLK 为高时,DIN 由低电平
- 变为高电平。
- */
- void I2C_SendByte(unsigned char Byte)
- {
- unsigned char i;
- for (i = 0; i < 8; i ++)
- {
- I2C_SDA = Byte&0x01; //数据的输入总是低位在前,高位在后传输
- Byte=Byte>>1;
- I2C_SCL = 1;
- I2C_SCL = 0;
- }
- }
-
- /**
- * @brief I2C_SendReyeByte
- * IIC发送机器人眼睛段信息,数据顺序不常规
- * 机器人眼睛段地址顺序:
- * unsigned char seg_sq[]={0x08,0x20,0x40,0x80,0x04,0x10,0x20,0x01};
- * 时钟下降沿发送数据
- */
- void I2C_SendREyeByte(unsigned char Byte)
- {
- unsigned char i;
- for (i = 0; i < 8; i ++)
- {
- I2C_SDA=Byte&seg_sq[i];
- I2C_SCL = 1;
- I2C_SCL = 0;
- }
- }
-
-
-
- /**
- * @brief 发送多个字节
- * start -> command2 -> data1-dataN ->end
- */
- void I2c_nbByte(unsigned char cmd,unsigned char* str,unsigned char len)
-
- {
- unsigned char i;
- I2C_Start();//start
- I2C_SendByte(cmd);//command2
- for(i=0;i<len;i++){
- I2C_SendByte(str[i]);
- }//data1-dataN
- I2C_Stop();//end
- }
-
-
- /**
- * @brief I2c_nbREyeByte
- * IIC发送机器人眼睛位信息,数据顺序不常规
- * 机器人眼睛位地址顺序:
- * int grid_sq[]={1,3,0,4,6,7,5,2,9,11,8,12,14,15,13,10};
- * 时钟下降沿发送数据
- * len设置16
- */
- void I2c_nbREyeByte(unsigned char cmd,unsigned char* str,unsigned char len)
- {
- unsigned char i;
- I2C_Start();//start
- I2C_SendByte(cmd);//command2
- for(i=0;i<len;i++){
- I2C_SendREyeByte(str[grid_sq[i]]); //变化了顺序
- }//data1-dataN
-
- I2C_Stop();//end
- }
-
- /**
- * @brief 发送命令
- * start -> command ->end
- */
-
- void I2c_cmdSend(signed char cmd)
- {
- I2C_Start();//start
- I2C_SendByte(cmd);//command
- I2C_Stop();//end
- }
复制代码
3.FZH119定义头文件“FZHxxx.h”
- #ifndef __FZHXXX_H
- #define __FZHXXX_H
- #define cmdData //010000
-
-
- typedef signed char int8_t;
- typedef unsigned char uint8_t;
- typedef unsigned short uint16_t;
-
- enum GRID{
- grid1=0xc0,
- grid2,
- grid3,
- grid4,
- grid5,
- grid6,
- grid7,
- grid8,
- grid9,
- grid10,
- grid11,
- grid12,
- grid13,
- grid14,
- grid15,
- grid16
- };
-
- #define FZH_CMD_ON 0x88
- #define FZH_CMD_FF 0x80
- #define USAER_CMD_CYCLE_1_16 0
- #define USAER_CMD_CYCLE_2_16 1
- #define USAER_CMD_CYCLE_4_16 2
- #define USAER_CMD_CYCLE_10_16 3
- #define USAER_CMD_CYCLE_11_16 4
- #define USAER_CMD_CYCLE_12_16 5
- #define USAER_CMD_CYCLE_13_16 6
- #define USAER_CMD_CYCLE_14_16 7
-
-
- #define USAER_CMD_SHOW_ON 1
- #define USAER_CMD_SHOW_OFF 0
-
-
- //与硬件连接相关设置
- #define START_SRAM grid1 //是定开始扫描地址地址
-
-
- int8_t fzh_WriteSram(uint8_t cmd1,uint8_t cmd2,uint8_t *str,uint8_t len,uint8_t cmd3 );
-
- int8_t fzh_cmdWrite(uint8_t cmd);
- int8_t fzh_cmdWriteDat(uint8_t cmd,uint8_t dat);
- /***********************************************************************************************
- *
- *函数名 :void fzh_SetLightGrade(uint8_t grade,uint8_t onff)
- *函数功能描述 :亮度设置
- *函数参数 :grade:亮度等级 支持7个等级 参考宏定义USAER_CMD_CYCLE_ onff 0:关闭显示 其它:显示
- *函数返回值 :无
- *作者 :SY
- *函数创建日期 :20211007
- *
- ***********************************************************************************************/
- void fzh_SetLightGrade(uint8_t grade,uint8_t onff);
- /***********************************************************************************************
- *
- *函数名 :void fzh_Init(void)
- *函数功能描述 :数码管初始化数码管显示驱动 并设为等亮度 默认显示
- *函数参数 :无
- *函数返回值 :无
- *作者 :SY
- *函数创建日期 :20211007
- *
- ***********************************************************************************************/
- void fzh_Init(void);
- int8_t fzh_WriteREyeSram( uint8_t cmd1,uint8_t cmd2,uint8_t* str,uint8_t len,uint8_t cmd3 );
- #endif
复制代码
4.FZH119实现文件“FZHxxx.c”
- #include "FZHxxx.h"
- #include "intrins.h"
- #include "my_iic.h"
-
-
-
-
- uint8_t fzh_light_grade = 0x8c;
-
- int8_t fzh_WriteSram( uint8_t cmd1,uint8_t cmd2,uint8_t* str,uint8_t len,uint8_t cmd3 ) {
- if( ( len==0 )||( len>16 ) ) {
- return -1;
- }
- I2c_cmdSend( cmd1 );
- I2c_nbByte(cmd2,str,len );
- I2c_cmdSend( cmd3 );
- return 0;
- }
-
- /**
- * @brief fzh_WriteREyeSram
-
- */
- //机器人眼睛FZH119顺序
- //len 输入 16
- int8_t fzh_WriteREyeSram( uint8_t cmd1,uint8_t cmd2,uint8_t* str,uint8_t len,uint8_t cmd3 ) {
-
- I2c_cmdSend( cmd1 ); //显示方式设置
- I2c_nbREyeByte(cmd2,str,len );
- I2c_cmdSend( cmd3 ); //显示ON,显示亮度
- return 0;
- }
-
- int8_t fzh_cmdWrite( uint8_t cmd ) {
- I2c_cmdSend( cmd );
- return 0;
- }
-
- int8_t fzh_cmdWriteDat( uint8_t cmd,uint8_t dat ) {
- I2c_nbByte( cmd,&dat,1 );
- return 0;
- }
-
-
- void fzh_SetLightGrade(uint8_t grade,uint8_t onff){
- if(grade>7)grade=7;
- fzh_light_grade = 0;
- if(onff!=0){
- fzh_light_grade = FZH_CMD_ON|grade;
- }else {
- fzh_light_grade = FZH_CMD_FF;
- }
- }
-
- void fzh_Init(void){
- I2C_init();
- fzh_SetLightGrade(USAER_CMD_CYCLE_11_16,USAER_CMD_SHOW_ON);
- }
复制代码- Hxxx.h"
- #include "intrins.h"
- #include "my_iic.h"
-
-
-
-
- uint8_t fzh_light_grade = 0x8c;
-
- int8_t fzh_WriteSram( uint8_t cmd1,uint8_t cmd2,uint8_t* str,uint8_t len,uint8_t cmd3 ) {
- if( ( len==0 )||( len>16 ) ) {
- return -1;
- }
- I2c_cmdSend( cmd1 );
- I2c_nbByte(cmd2,str,len );
- I2c_cmdSend( cmd3 );
- return 0;
- }
-
- /**
- * @brief fzh_WriteREyeSram
-
- */
- //机器人眼睛FZH119顺序
- //len 输入 16
- int8_t fzh_WriteREyeSram( uint8_t cmd1,uint8_t cmd2,uint8_t* str,uint8_t len,uint8_t cmd3 ) {
-
- I2c_cmdSend( cmd1 ); //显示方式设置
- I2c_nbREyeByte(cmd2,str,len );
- I2c_cmdSend( cmd3 ); //显示ON,显示亮度
- return 0;
- }
-
- int8_t fzh_cmdWrite( uint8_t cmd ) {
- I2c_cmdSend( cmd );
- return 0;
- }
-
- int8_t fzh_cmdWriteDat( uint8_t cmd,uint8_t dat ) {
- I2c_nbByte( cmd,&dat,1 );
- return 0;
- }
-
-
- void fzh_SetLightGrade(uint8_t grade,uint8_t onff){
- if(grade>7)grade=7;
- fzh_light_grade = 0;
- if(onff!=0){
- fzh_light_grade = FZH_CMD_ON|grade;
- }else {
- fzh_light_grade = FZH_CMD_FF;
- }
- }
-
- void fzh_Init(void){
- I2C_init();
- fzh_SetLightGrade(USAER_CMD_CYCLE_11_16,USAER_CMD_SHOW_ON);
- }
复制代码
5.main文件“main.c”- #include <STC15F2K60S2.H>
- #include "intrins.h"
- #include "FZHxxx.h"
-
- unsigned char fangkuang1[]={0x10,0xFE,0x92,0x92,0xFE,0x92,0x10,0x10,0xFF,0xFD,0x91,0xFD,0x9D,0xFD,0x81,0xFF};
- unsigned char fangkuang2[]={0x24,0x7E,0xFF,0xFF,0xFF,0x7E,0x3C,0x18,0x24,0x7E,0xFF,0xFF,0xFF,0x7E,0x3C,0x18};
-
- void Delay5000ms() //@11.0592MHz
- {
- unsigned char i, j, k;
-
- _nop_();
- i = 36;
- j = 5;
- k = 211;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
-
-
-
-
- //上电时,地址默认设为C0H,grid1
- int main(void){
- fzh_Init();
-
- while(1){
- fzh_SetLightGrade(USAER_CMD_CYCLE_14_16,USAER_CMD_SHOW_ON);
- //0x40:地址自动加一
- //grid1:从grid1开始
- fzh_WriteREyeSram( 0x40,grid1,fangkuang1,16,FZH_CMD_ON|USAER_CMD_CYCLE_11_16);
- Delay5000ms();
- Delay5000ms();
- fzh_WriteREyeSram( 0x40,grid1,fangkuang2,16,FZH_CMD_ON|USAER_CMD_CYCLE_2_16);
- Delay5000ms();
- Delay5000ms();
-
- /*
- //fzh_WriteSram是正常顺序输出的函数,显示乱码
- fzh_WriteSram( 0x40,grid1,fangkuang1,16,FZH_CMD_ON|USAER_CMD_CYCLE_14_16);
- Delay5000ms();
- Delay5000ms();
- fzh_WriteSram( 0x40,grid1,fangkuang2,16,FZH_CMD_ON|USAER_CMD_CYCLE_2_16);
- Delay5000ms();
- Delay5000ms();
- */
- }
- return 1;
- }
复制代码
总结本文借鉴了很多前辈关于FZH119数码管驱动、IIC实现的源码。甚至是文件名和函数名都没改直接照搬过来,在此一并感谢。 后有前辈指出FZH119和TM1640兼容,查了一下确实。 |